diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml new file mode 100644 index 000000000..79d8d45a0 --- /dev/null +++ b/.github/workflows/static-checks.yml @@ -0,0 +1,24 @@ +name: Static Checks 📊 +on: + push: + branches-ignore: + - gh-pages + - l10n_master + pull_request: + paths: + - "addons/*" + - "src/*" + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: pip3 install gdtoolkit + - run: gdformat --diff . + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: pip3 install gdtoolkit + - run: gdlint . diff --git a/addons/gdgifexporter/converter.gd b/addons/gdgifexporter/converter.gd index c9f7d2f86..846d93cdd 100644 --- a/addons/gdgifexporter/converter.gd +++ b/addons/gdgifexporter/converter.gd @@ -1,6 +1,5 @@ extends Reference - var _shader: Shader @@ -29,7 +28,9 @@ func _convert(image: Image, colors: Array) -> PoolByteArray: VisualServer.canvas_item_set_parent(ci_rid, canvas) var texture = ImageTexture.new() texture.create_from_image(image) - VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(Vector2(0, 0), image.get_size()), texture) + VisualServer.canvas_item_add_texture_rect( + ci_rid, Rect2(Vector2(0, 0), image.get_size()), texture + ) var mat_rid = VisualServer.material_create() VisualServer.material_set_shader(mat_rid, _shader.get_rid()) diff --git a/addons/gdgifexporter/exporter.gd b/addons/gdgifexporter/exporter.gd index a96cff6e9..c561a4b7d 100644 --- a/addons/gdgifexporter/exporter.gd +++ b/addons/gdgifexporter/exporter.gd @@ -1,15 +1,9 @@ extends Reference +enum Error { OK = 0, EMPTY_IMAGE = 1, BAD_IMAGE_FORMAT = 2 } -enum Error { - OK = 0, - EMPTY_IMAGE = 1, - BAD_IMAGE_FORMAT = 2 -} - - -var little_endian = preload('./little_endian.gd').new() -var lzw = preload('./gif-lzw/lzw.gd').new() +var little_endian = preload("./little_endian.gd").new() +var lzw = preload("./gif-lzw/lzw.gd").new() var converter = preload("./converter.gd") var last_color_table := [] @@ -24,11 +18,14 @@ func _init(_width: int, _height: int): add_logical_screen_descriptor(_width, _height) add_application_ext("NETSCAPE", "2.0", [1, 0, 0]) + func export_file_data() -> PoolByteArray: return data + PoolByteArray([0x3b]) + func add_header() -> void: - data += 'GIF'.to_ascii() + '89a'.to_ascii() + data += "GIF".to_ascii() + "89a".to_ascii() + func add_logical_screen_descriptor(width: int, height: int) -> void: # not Global Color Table Flag @@ -46,6 +43,7 @@ func add_logical_screen_descriptor(width: int, height: int) -> void: data.append(background_color_index) data.append(pixel_aspect_ratio) + func add_application_ext(app_iden: String, app_auth_code: String, _data: Array) -> void: var extension_introducer := 0x21 var extension_label := 0xff @@ -61,6 +59,7 @@ func add_application_ext(app_iden: String, app_auth_code: String, _data: Array) data += PoolByteArray(_data) data.append(0) + # finds the image color table. Stops if the size gets larger than 256. func find_color_table(image: Image) -> Dictionary: image.lock() @@ -72,7 +71,8 @@ func find_color_table(image: Image) -> Dictionary: int(image_data[i]), int(image_data[i + 1]), int(image_data[i + 2]), - int(image_data[i + 3])] + int(image_data[i + 3]) + ] if not color in result: result[color] = result.size() if result.size() > 256: @@ -81,25 +81,21 @@ func find_color_table(image: Image) -> Dictionary: image.unlock() return result + func find_transparency_color_index(color_table: Dictionary) -> int: for color in color_table: if color[3] == 0: return color_table[color] return -1 -func change_colors_to_codes(image: Image, - color_palette: Dictionary, - transparency_color_index: int) -> PoolByteArray: + +func change_colors_to_codes(image: Image, color_palette: Dictionary, transparency_color_index: int) -> PoolByteArray: image.lock() var image_data: PoolByteArray = image.get_data() var result: PoolByteArray = PoolByteArray([]) for i in range(0, image_data.size(), 4): - var color: Array = [ - image_data[i], - image_data[i + 1], - image_data[i + 2], - image_data[i + 3]] + var color: Array = [image_data[i], image_data[i + 1], image_data[i + 2], image_data[i + 3]] if color in color_palette: if color[3] == 0 and transparency_color_index != -1: @@ -108,11 +104,12 @@ func change_colors_to_codes(image: Image, result.append(color_palette[color]) else: result.append(0) - push_warning('change_colors_to_codes: color not found! [%d, %d, %d, %d]' % color) + push_warning("change_colors_to_codes: color not found! [%d, %d, %d, %d]" % color) image.unlock() return result + # makes sure that the color table is at least size 4. func make_proper_size(color_table: Array) -> Array: var result := [] + color_table @@ -121,15 +118,18 @@ func make_proper_size(color_table: Array) -> Array: result.append([0, 0, 0, 0]) return result + func calc_delay_time(frame_delay: float) -> int: return int(ceil(frame_delay / 0.01)) + func color_table_to_indexes(colors: Array) -> PoolByteArray: var result: PoolByteArray = PoolByteArray([]) for i in range(colors.size()): result.append(i) return result + func add_frame(image: Image, frame_delay: float, quantizator: Script) -> int: # check if image is of good format if image.get_format() != Image.FORMAT_RGBA8: @@ -144,7 +144,7 @@ func add_frame(image: Image, frame_delay: float, quantizator: Script) -> int: var image_converted_to_codes: PoolByteArray var transparency_color_index: int = -1 var color_table: Array - if found_color_table.size() <= 256: # we don't need to quantize the image. + if found_color_table.size() <= 256: # we don't need to quantize the image. # try to find transparency color index. transparency_color_index = find_transparency_color_index(found_color_table) # if didn't found transparency color index but there is atleast one @@ -153,37 +153,36 @@ func add_frame(image: Image, frame_delay: float, quantizator: Script) -> int: found_color_table[[0, 0, 0, 0]] = found_color_table.size() transparency_color_index = found_color_table.size() - 1 image_converted_to_codes = change_colors_to_codes( - image, found_color_table, transparency_color_index) + image, found_color_table, transparency_color_index + ) color_table = make_proper_size(found_color_table.keys()) - else: # we have to quantize the image. + else: # we have to quantize the image. var quantization_result: Array = quantizator.new().quantize(image) image_converted_to_codes = quantization_result[0] color_table = quantization_result[1] # transparency index should always be as the first element of color table. transparency_color_index = 0 if quantization_result[2] else -1 - + last_color_table = color_table last_transparency_index = transparency_color_index - + var delay_time := calc_delay_time(frame_delay) - + var color_table_indexes := color_table_to_indexes(color_table) var compressed_image_result: Array = lzw.compress_lzw( - image_converted_to_codes, - color_table_indexes) + image_converted_to_codes, color_table_indexes + ) var compressed_image_data: PoolByteArray = compressed_image_result[0] var lzw_min_code_size: int = compressed_image_result[1] - + add_graphic_constrol_ext(delay_time, transparency_color_index) - add_image_descriptor( - Vector2.ZERO, - image.get_size(), - color_table_bit_size(color_table)) + add_image_descriptor(Vector2.ZERO, image.get_size(), color_table_bit_size(color_table)) add_local_color_table(color_table) add_image_data_block(lzw_min_code_size, compressed_image_data) return Error.OK + # adds frame with last color informations func add_frame_with_lci(image: Image, frame_delay: float) -> int: # check if image is of good format @@ -194,27 +193,27 @@ func add_frame_with_lci(image: Image, frame_delay: float) -> int: if image.is_empty(): return Error.EMPTY_IMAGE - var image_converted_to_codes: PoolByteArray = converter.new().get_similar_indexed_datas(image, last_color_table) - + var image_converted_to_codes: PoolByteArray = converter.new().get_similar_indexed_datas( + image, last_color_table + ) + var color_table_indexes := color_table_to_indexes(last_color_table) var compressed_image_result: Array = lzw.compress_lzw( - image_converted_to_codes, - color_table_indexes) + image_converted_to_codes, color_table_indexes + ) var compressed_image_data: PoolByteArray = compressed_image_result[0] var lzw_min_code_size: int = compressed_image_result[1] - + var delay_time := calc_delay_time(frame_delay) - + add_graphic_constrol_ext(delay_time, last_transparency_index) - add_image_descriptor( - Vector2.ZERO, - image.get_size(), - color_table_bit_size(last_color_table)) + add_image_descriptor(Vector2.ZERO, image.get_size(), color_table_bit_size(last_color_table)) add_local_color_table(last_color_table) add_image_data_block(lzw_min_code_size, compressed_image_data) return Error.OK + func add_graphic_constrol_ext(_delay_time: float, tci: int = -1) -> void: var extension_introducer: int = 0x21 var graphic_control_label: int = 0xf9 @@ -226,7 +225,7 @@ func add_graphic_constrol_ext(_delay_time: float, tci: int = -1) -> void: var delay_time: int = _delay_time var transparent_color_index: int = tci if tci != -1 else 0 - + data.append(extension_introducer) data.append(graphic_control_label) @@ -237,27 +236,26 @@ func add_graphic_constrol_ext(_delay_time: float, tci: int = -1) -> void: data.append(0) -func add_image_descriptor(pos: Vector2, - size: Vector2, - l_color_table_size: int) -> void: + +func add_image_descriptor(pos: Vector2, size: Vector2, l_color_table_size: int) -> void: var image_separator: int = 0x2c var packed_fields: int = 0b10000000 | (0b111 & l_color_table_size) - - var little_endian = preload('./little_endian.gd').new() data.append(image_separator) - data += little_endian.int_to_2bytes(int(pos.x)) # left pos - data += little_endian.int_to_2bytes(int(pos.y)) # top pos - data += little_endian.int_to_2bytes(int(size.x)) # width - data += little_endian.int_to_2bytes(int(size.y)) # height + data += little_endian.int_to_2bytes(int(pos.x)) # left pos + data += little_endian.int_to_2bytes(int(pos.y)) # top pos + data += little_endian.int_to_2bytes(int(size.x)) # width + data += little_endian.int_to_2bytes(int(size.y)) # height data.append(packed_fields) + func color_table_bit_size(color_table: Array) -> int: if color_table.size() <= 1: return 0 var bit_size := int(ceil(log(color_table.size()) / log(2.0))) return bit_size - 1 + func add_local_color_table(color_table: Array) -> void: for color in color_table: data.append(color[0]) @@ -271,9 +269,10 @@ func add_local_color_table(color_table: Array) -> void: for i in range(proper_size - color_table.size()): data += PoolByteArray([0, 0, 0]) + func add_image_data_block(lzw_min_code_size: int, _data: PoolByteArray) -> void: data.append(lzw_min_code_size) - + var block_size_index: int = 0 var i: int = 0 var data_index: int = 0 diff --git a/addons/gdgifexporter/gif-lzw/lsbbitpacker.gd b/addons/gdgifexporter/gif-lzw/lsbbitpacker.gd index 8fe3ac43d..3141d0914 100644 --- a/addons/gdgifexporter/gif-lzw/lsbbitpacker.gd +++ b/addons/gdgifexporter/gif-lzw/lsbbitpacker.gd @@ -1,7 +1,7 @@ extends Reference -class LSB_LZWBitPacker: +class LSBLZWBitPacker: var bit_index: int = 0 var stream: int = 0 diff --git a/addons/gdgifexporter/gif-lzw/lsbbitunpacker.gd b/addons/gdgifexporter/gif-lzw/lsbbitunpacker.gd index be8e9d6bf..9f8507f2d 100644 --- a/addons/gdgifexporter/gif-lzw/lsbbitunpacker.gd +++ b/addons/gdgifexporter/gif-lzw/lsbbitunpacker.gd @@ -1,7 +1,7 @@ extends Reference -class LSB_LZWBitUnpacker: +class LSBLZWBitUnpacker: var chunk_stream: PoolByteArray var bit_index: int = 0 var byte: int diff --git a/addons/gdgifexporter/gif-lzw/lzw.gd b/addons/gdgifexporter/gif-lzw/lzw.gd index 6cfd6f30a..719f483ac 100644 --- a/addons/gdgifexporter/gif-lzw/lzw.gd +++ b/addons/gdgifexporter/gif-lzw/lzw.gd @@ -1,8 +1,8 @@ extends Reference +var lsbbitpacker = preload("./lsbbitpacker.gd") +var lsbbitunpacker = preload("./lsbbitunpacker.gd") -var lsbbitpacker = preload('./lsbbitpacker.gd') -var lsbbitunpacker = preload('./lsbbitunpacker.gd') class CodeEntry: var sequence: PoolByteArray @@ -16,11 +16,12 @@ class CodeEntry: return CodeEntry.new(self.raw_array + other.raw_array) func to_string(): - var result: String = '' + var result: String = "" for element in self.sequence: - result += str(element) + ', ' + result += str(element) + ", " return result.substr(0, result.length() - 2) + class CodeTable: var entries: Dictionary = {} var counter: int = 0 @@ -42,20 +43,23 @@ class CodeTable: return self.entries.get(index, null) func to_string() -> String: - var result: String = 'CodeTable:\n' + var result: String = "CodeTable:\n" for id in self.entries: - result += str(id) + ': ' + self.entries[id].to_string() + '\n' - result += 'Counter: ' + str(self.counter) + '\n' + result += str(id) + ": " + self.entries[id].to_string() + "\n" + result += "Counter: " + str(self.counter) + "\n" return result + func log2(value: float) -> float: return log(value) / log(2.0) + func get_bits_number_for(value: int) -> int: if value == 0: return 1 return int(ceil(log2(value + 1))) + func initialize_color_code_table(colors: PoolByteArray) -> CodeTable: var result_code_table: CodeTable = CodeTable.new() for color_id in colors: @@ -67,9 +71,11 @@ func initialize_color_code_table(colors: PoolByteArray) -> CodeTable: result_code_table.counter = clear_code_index + 2 return result_code_table + # compression and decompression done with source: # http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp + func compress_lzw(image: PoolByteArray, colors: PoolByteArray) -> Array: # Initialize code table var code_table: CodeTable = initialize_color_code_table(colors) @@ -83,7 +89,7 @@ func compress_lzw(image: PoolByteArray, colors: PoolByteArray) -> Array: var clear_code_index: int = pow(2, get_bits_number_for(last_color_index)) var index_stream: PoolByteArray = image var current_code_size: int = get_bits_number_for(clear_code_index) - var binary_code_stream = lsbbitpacker.LSB_LZWBitPacker.new() + var binary_code_stream = lsbbitpacker.LSBLZWBitPacker.new() # initialize with Clear Code binary_code_stream.write_bits(clear_code_index, current_code_size) @@ -94,15 +100,15 @@ func compress_lzw(image: PoolByteArray, colors: PoolByteArray) -> Array: # while data_index < index_stream.size(): # Get the next index from the index stream. - var K: CodeEntry = CodeEntry.new([index_stream[data_index]]) + var k: CodeEntry = CodeEntry.new([index_stream[data_index]]) data_index += 1 - # Is index buffer + K in our code table? - var new_index_buffer: CodeEntry = index_buffer.add(K) - if code_table.has(new_index_buffer): # if YES - # Add K to the end of the index buffer + # Is index buffer + k in our code table? + var new_index_buffer: CodeEntry = index_buffer.add(k) + if code_table.has(new_index_buffer): # if YES + # Add k to the end of the index buffer index_buffer = new_index_buffer - else: # if NO - # Add a row for index buffer + K into our code table + else: # if NO + # Add a row for index buffer + k into our code table binary_code_stream.write_bits(code_table.find(index_buffer), current_code_size) # We don't want to add new code to code table if we've exceeded 4095 @@ -128,8 +134,8 @@ func compress_lzw(image: PoolByteArray, colors: PoolByteArray) -> Array: if new_code_size_candidate > current_code_size: current_code_size = new_code_size_candidate - # Index buffer is set to K - index_buffer = K + # Index buffer is set to k + index_buffer = k # Output code for contents of index buffer binary_code_stream.write_bits(code_table.find(index_buffer), current_code_size) @@ -140,10 +146,11 @@ func compress_lzw(image: PoolByteArray, colors: PoolByteArray) -> Array: return [binary_code_stream.pack(), min_code_size] + func decompress_lzw(code_stream_data: PoolByteArray, min_code_size: int, colors: PoolByteArray) -> PoolByteArray: var code_table: CodeTable = initialize_color_code_table(colors) var index_stream: PoolByteArray = PoolByteArray([]) - var binary_code_stream = lsbbitunpacker.LSB_LZWBitUnpacker.new(code_stream_data) + var binary_code_stream = lsbbitunpacker.LSBLZWBitUnpacker.new(code_stream_data) var current_code_size: int = min_code_size + 1 var clear_code_index: int = pow(2, min_code_size) @@ -168,29 +175,29 @@ func decompress_lzw(code_stream_data: PoolByteArray, min_code_size: int, colors: code_table = initialize_color_code_table(colors) current_code_size = min_code_size + 1 code = binary_code_stream.read_bits(current_code_size) - elif code == clear_code_index + 1: # Stop when detected EOI Code. + elif code == clear_code_index + 1: # Stop when detected EOI Code. break # is CODE in the code table? var code_entry: CodeEntry = code_table.get(code) - if code_entry != null: # if YES + if code_entry != null: # if YES # output {CODE} to index stream index_stream.append_array(code_entry.sequence) - # let K be the first index in {CODE} - var K: CodeEntry = CodeEntry.new([code_entry.sequence[0]]) + # let k be the first index in {CODE} + var k: CodeEntry = CodeEntry.new([code_entry.sequence[0]]) # warning-ignore:return_value_discarded - # add {PREVCODE} + K to the code table - code_table.add(code_table.get(prevcode).add(K)) + # add {PREVCODE} + k to the code table + code_table.add(code_table.get(prevcode).add(k)) # set PREVCODE = CODE prevcode = code - else: # if NO - # let K be the first index of {PREVCODE} + else: # if NO + # let k be the first index of {PREVCODE} var prevcode_entry: CodeEntry = code_table.get(prevcode) - var K: CodeEntry = CodeEntry.new([prevcode_entry.sequence[0]]) - # output {PREVCODE} + K to index stream - index_stream.append_array(prevcode_entry.add(K).sequence) - # add {PREVCODE} + K to code table + var k: CodeEntry = CodeEntry.new([prevcode_entry.sequence[0]]) + # output {PREVCODE} + k to index stream + index_stream.append_array(prevcode_entry.add(k).sequence) + # add {PREVCODE} + k to code table # warning-ignore:return_value_discarded - code_table.add(prevcode_entry.add(K)) + code_table.add(prevcode_entry.add(k)) # set PREVCODE = CODE prevcode = code diff --git a/addons/gdgifexporter/quantization/median_cut.gd b/addons/gdgifexporter/quantization/median_cut.gd index 36135b408..4610f03db 100644 --- a/addons/gdgifexporter/quantization/median_cut.gd +++ b/addons/gdgifexporter/quantization/median_cut.gd @@ -1,9 +1,9 @@ extends Reference - -var converter = preload('../converter.gd').new() +var converter = preload("../converter.gd").new() var transparency := false + func longest_axis(colors: Array) -> int: var start := [255, 255, 255] var end := [0, 0, 0] @@ -11,11 +11,11 @@ func longest_axis(colors: Array) -> int: for i in 3: start[i] = min(color[i], start[i]) end[i] = max(color[i], end[i]) - + var max_r = end[0] - start[0] var max_g = end[1] - start[1] var max_b = end[2] - start[2] - + if max_r > max_g: if max_r > max_b: return 0 @@ -24,22 +24,23 @@ func longest_axis(colors: Array) -> int: return 1 return 2 + func get_median(colors: Array) -> Vector3: return colors[colors.size() >> 1] func median_cut(colors: Array) -> Array: var axis := longest_axis(colors) - + var axis_sort := [] for color in colors: axis_sort.append(color[axis]) axis_sort.sort() - + var cut := axis_sort.size() >> 1 var median: int = axis_sort[cut] axis_sort = [] - + var left_colors := [] var right_colors := [] @@ -51,6 +52,7 @@ func median_cut(colors: Array) -> Array: return [left_colors, right_colors] + func average_color(bucket: Array) -> Array: var r := 0 var g := 0 @@ -61,6 +63,7 @@ func average_color(bucket: Array) -> Array: b += color[2] return [r / bucket.size(), g / bucket.size(), b / bucket.size()] + func average_colors(buckets: Array) -> Dictionary: var avg_colors := {} for bucket in buckets: @@ -68,6 +71,7 @@ func average_colors(buckets: Array) -> Dictionary: avg_colors[average_color(bucket)] = avg_colors.size() return avg_colors + func pixels_to_colors(image: Image) -> Array: image.lock() var result := [] @@ -81,6 +85,7 @@ func pixels_to_colors(image: Image) -> Array: image.unlock() return result + func remove_smallest_bucket(buckets: Array) -> Array: if buckets.size() == 0: return buckets @@ -91,17 +96,19 @@ func remove_smallest_bucket(buckets: Array) -> Array: buckets.remove(i_of_smallest_bucket) return buckets + func remove_empty_buckets(buckets: Array) -> Array: if buckets.size() == 0: return buckets - + var i := buckets.find([]) while i != -1: buckets.remove(i) i = buckets.find([]) - + return buckets + # quantizes to gif ready codes func quantize(image: Image) -> Array: var pixels = pixels_to_colors(image) @@ -137,14 +144,14 @@ func quantize(image: Image) -> Array: buckets = [] done_buckets = [] - + if transparency: if all_buckets.size() == pow(2, dimensions): all_buckets = remove_smallest_bucket(all_buckets) - + # dictionaries are only for speed. var color_array := average_colors(all_buckets).keys() - + # if pixel_to_colors detected that the image has transparent pixels # then add transparency color at the beginning so it will be properly # exported. diff --git a/assets/graphics/cursor.png.import b/assets/graphics/cursor.png.import index f9eb676bb..3ea87ca12 100644 --- a/assets/graphics/cursor.png.import +++ b/assets/graphics/cursor.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/dotted_line.png.import b/assets/graphics/dotted_line.png.import index a5869898a..e37bc2484 100644 --- a/assets/graphics/dotted_line.png.import +++ b/assets/graphics/dotted_line.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/icons/icon.png.import b/assets/graphics/icons/icon.png.import index f90e2b84e..29af9a99a 100644 --- a/assets/graphics/icons/icon.png.import +++ b/assets/graphics/icons/icon.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/clone.png.import b/assets/graphics/layers/clone.png.import index 923dff271..5241134ac 100644 --- a/assets/graphics/layers/clone.png.import +++ b/assets/graphics/layers/clone.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/delete.png.import b/assets/graphics/layers/delete.png.import index d95b7b5a8..55dc45540 100644 --- a/assets/graphics/layers/delete.png.import +++ b/assets/graphics/layers/delete.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/layer_invisible.png.import b/assets/graphics/layers/layer_invisible.png.import index 3487df768..3cb9cc47b 100644 --- a/assets/graphics/layers/layer_invisible.png.import +++ b/assets/graphics/layers/layer_invisible.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/layer_visible.png.import b/assets/graphics/layers/layer_visible.png.import index bdf336bca..3f3a47df6 100644 --- a/assets/graphics/layers/layer_visible.png.import +++ b/assets/graphics/layers/layer_visible.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/linked_layer.png.import b/assets/graphics/layers/linked_layer.png.import index 614cc10fc..635f6fcb2 100644 --- a/assets/graphics/layers/linked_layer.png.import +++ b/assets/graphics/layers/linked_layer.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/lock.png.import b/assets/graphics/layers/lock.png.import index 4ad5c3960..ad321455a 100644 --- a/assets/graphics/layers/lock.png.import +++ b/assets/graphics/layers/lock.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/merge_down.png.import b/assets/graphics/layers/merge_down.png.import index 3156fd851..fbd4883da 100644 --- a/assets/graphics/layers/merge_down.png.import +++ b/assets/graphics/layers/merge_down.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/move_down.png.import b/assets/graphics/layers/move_down.png.import index b135cc44e..6df051ce4 100644 --- a/assets/graphics/layers/move_down.png.import +++ b/assets/graphics/layers/move_down.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/move_up.png.import b/assets/graphics/layers/move_up.png.import index 010ea4801..b7dfeff71 100644 --- a/assets/graphics/layers/move_up.png.import +++ b/assets/graphics/layers/move_up.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/new.png.import b/assets/graphics/layers/new.png.import index 2f17c53cd..148317df3 100644 --- a/assets/graphics/layers/new.png.import +++ b/assets/graphics/layers/new.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/unlinked_layer.png.import b/assets/graphics/layers/unlinked_layer.png.import index 0ef6274dc..bf88889d8 100644 --- a/assets/graphics/layers/unlinked_layer.png.import +++ b/assets/graphics/layers/unlinked_layer.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/layers/unlock.png.import b/assets/graphics/layers/unlock.png.import index 3a404b132..a1cb0bb44 100644 --- a/assets/graphics/layers/unlock.png.import +++ b/assets/graphics/layers/unlock.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/color_defaults.png.import b/assets/graphics/misc/color_defaults.png.import index e4889ab00..e73c99df0 100644 --- a/assets/graphics/misc/color_defaults.png.import +++ b/assets/graphics/misc/color_defaults.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/color_switch.png.import b/assets/graphics/misc/color_switch.png.import index 3685bb93b..183792000 100644 --- a/assets/graphics/misc/color_switch.png.import +++ b/assets/graphics/misc/color_switch.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/horizontal_mirror_off.png.import b/assets/graphics/misc/horizontal_mirror_off.png.import index dbdc58840..e0d0bd615 100644 --- a/assets/graphics/misc/horizontal_mirror_off.png.import +++ b/assets/graphics/misc/horizontal_mirror_off.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/horizontal_mirror_on.png.import b/assets/graphics/misc/horizontal_mirror_on.png.import index 675872c7b..e863fc54b 100644 --- a/assets/graphics/misc/horizontal_mirror_on.png.import +++ b/assets/graphics/misc/horizontal_mirror_on.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/icon_reload.png.import b/assets/graphics/misc/icon_reload.png.import index 59f64c3a1..53b233cd3 100644 --- a/assets/graphics/misc/icon_reload.png.import +++ b/assets/graphics/misc/icon_reload.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/landscape.png.import b/assets/graphics/misc/landscape.png.import index ea3427496..bd0822c9b 100644 --- a/assets/graphics/misc/landscape.png.import +++ b/assets/graphics/misc/landscape.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/lock_aspect.png.import b/assets/graphics/misc/lock_aspect.png.import index 71869aabe..a9edbf1ca 100644 --- a/assets/graphics/misc/lock_aspect.png.import +++ b/assets/graphics/misc/lock_aspect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/lock_aspect_2.png.import b/assets/graphics/misc/lock_aspect_2.png.import index db5150699..7ffd84671 100644 --- a/assets/graphics/misc/lock_aspect_2.png.import +++ b/assets/graphics/misc/lock_aspect_2.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/lock_aspect_guides.png.import b/assets/graphics/misc/lock_aspect_guides.png.import index 103e2ab46..1ecc4c44f 100644 --- a/assets/graphics/misc/lock_aspect_guides.png.import +++ b/assets/graphics/misc/lock_aspect_guides.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/portrait.png.import b/assets/graphics/misc/portrait.png.import index 1845bb671..18a48b5df 100644 --- a/assets/graphics/misc/portrait.png.import +++ b/assets/graphics/misc/portrait.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/vertical_mirror_off.png.import b/assets/graphics/misc/vertical_mirror_off.png.import index 018ce2474..74424094c 100644 --- a/assets/graphics/misc/vertical_mirror_off.png.import +++ b/assets/graphics/misc/vertical_mirror_off.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/misc/vertical_mirror_on.png.import b/assets/graphics/misc/vertical_mirror_on.png.import index b526d7998..9c38fb234 100644 --- a/assets/graphics/misc/vertical_mirror_on.png.import +++ b/assets/graphics/misc/vertical_mirror_on.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/palette/add.png.import b/assets/graphics/palette/add.png.import index 76c606bc0..496837aff 100644 --- a/assets/graphics/palette/add.png.import +++ b/assets/graphics/palette/add.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/palette/edit.png.import b/assets/graphics/palette/edit.png.import index 698418730..8b20d2a08 100644 --- a/assets/graphics/palette/edit.png.import +++ b/assets/graphics/palette/edit.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/splash.png.import b/assets/graphics/splash.png.import index 077e71605..7358eef0f 100644 --- a/assets/graphics/splash.png.import +++ b/assets/graphics/splash.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/splash_screen/artworks/kamilayza.png.import b/assets/graphics/splash_screen/artworks/kamilayza.png.import index 227ace71d..c87419d55 100644 --- a/assets/graphics/splash_screen/artworks/kamilayza.png.import +++ b/assets/graphics/splash_screen/artworks/kamilayza.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/splash_screen/artworks/roroto.png.import b/assets/graphics/splash_screen/artworks/roroto.png.import index b12c9487f..3110bf0a4 100644 --- a/assets/graphics/splash_screen/artworks/roroto.png.import +++ b/assets/graphics/splash_screen/artworks/roroto.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/splash_screen/artworks/wishdream.png.import b/assets/graphics/splash_screen/artworks/wishdream.png.import index 769f77be3..0517eb187 100644 --- a/assets/graphics/splash_screen/artworks/wishdream.png.import +++ b/assets/graphics/splash_screen/artworks/wishdream.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/splash_screen/discord.png.import b/assets/graphics/splash_screen/discord.png.import index 3c504c5d5..4b4deb559 100644 --- a/assets/graphics/splash_screen/discord.png.import +++ b/assets/graphics/splash_screen/discord.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/splash_screen/github_32px.png.import b/assets/graphics/splash_screen/github_32px.png.import index dcf2a2ea1..4d6bad785 100644 --- a/assets/graphics/splash_screen/github_32px.png.import +++ b/assets/graphics/splash_screen/github_32px.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/splash_screen/orama_64x64.png.import b/assets/graphics/splash_screen/orama_64x64.png.import index 2996aed9d..dd5cd7e10 100644 --- a/assets/graphics/splash_screen/orama_64x64.png.import +++ b/assets/graphics/splash_screen/orama_64x64.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/splash_screen/patreon_mark_white.png.import b/assets/graphics/splash_screen/patreon_mark_white.png.import index d0504ad4e..c6528b667 100644 --- a/assets/graphics/splash_screen/patreon_mark_white.png.import +++ b/assets/graphics/splash_screen/patreon_mark_white.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/copy_frame.png.import b/assets/graphics/timeline/copy_frame.png.import index b7ccf2b66..dfdb65667 100644 --- a/assets/graphics/timeline/copy_frame.png.import +++ b/assets/graphics/timeline/copy_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/expandable.png.import b/assets/graphics/timeline/expandable.png.import index 18dc9a311..cdc6565d0 100644 --- a/assets/graphics/timeline/expandable.png.import +++ b/assets/graphics/timeline/expandable.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/go_to_first_frame.png.import b/assets/graphics/timeline/go_to_first_frame.png.import index e6422fe5b..beec7394f 100644 --- a/assets/graphics/timeline/go_to_first_frame.png.import +++ b/assets/graphics/timeline/go_to_first_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/go_to_last_frame.png.import b/assets/graphics/timeline/go_to_last_frame.png.import index b467e1dc8..cbcb5f063 100644 --- a/assets/graphics/timeline/go_to_last_frame.png.import +++ b/assets/graphics/timeline/go_to_last_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/loop.png.import b/assets/graphics/timeline/loop.png.import index 2e151a2d1..7114da2dc 100644 --- a/assets/graphics/timeline/loop.png.import +++ b/assets/graphics/timeline/loop.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/loop_none.png.import b/assets/graphics/timeline/loop_none.png.import index 018779d8e..004c25f4f 100644 --- a/assets/graphics/timeline/loop_none.png.import +++ b/assets/graphics/timeline/loop_none.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/loop_pingpong.png.import b/assets/graphics/timeline/loop_pingpong.png.import index 235f30588..0a07bd2d4 100644 --- a/assets/graphics/timeline/loop_pingpong.png.import +++ b/assets/graphics/timeline/loop_pingpong.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/move_arrow.png.import b/assets/graphics/timeline/move_arrow.png.import index eaa227dda..11753e33d 100644 --- a/assets/graphics/timeline/move_arrow.png.import +++ b/assets/graphics/timeline/move_arrow.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/new_frame.png.import b/assets/graphics/timeline/new_frame.png.import index 26a7818af..b91a30f42 100644 --- a/assets/graphics/timeline/new_frame.png.import +++ b/assets/graphics/timeline/new_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/next_frame.png.import b/assets/graphics/timeline/next_frame.png.import index 883a9d205..808075ea6 100644 --- a/assets/graphics/timeline/next_frame.png.import +++ b/assets/graphics/timeline/next_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/onion_skinning.png.import b/assets/graphics/timeline/onion_skinning.png.import index ae6fc120c..4ee2361ed 100644 --- a/assets/graphics/timeline/onion_skinning.png.import +++ b/assets/graphics/timeline/onion_skinning.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/onion_skinning_off.png.import b/assets/graphics/timeline/onion_skinning_off.png.import index 72a503afb..f3246b9f7 100644 --- a/assets/graphics/timeline/onion_skinning_off.png.import +++ b/assets/graphics/timeline/onion_skinning_off.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/pause.png.import b/assets/graphics/timeline/pause.png.import index 7bcd39738..68611c12b 100644 --- a/assets/graphics/timeline/pause.png.import +++ b/assets/graphics/timeline/pause.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/play.png.import b/assets/graphics/timeline/play.png.import index 6b55cc81d..b5f0e0536 100644 --- a/assets/graphics/timeline/play.png.import +++ b/assets/graphics/timeline/play.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/play_backwards.png.import b/assets/graphics/timeline/play_backwards.png.import index 533d3ec4b..5a6e588ea 100644 --- a/assets/graphics/timeline/play_backwards.png.import +++ b/assets/graphics/timeline/play_backwards.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/previous_frame.png.import b/assets/graphics/timeline/previous_frame.png.import index 23d364619..0b8637a10 100644 --- a/assets/graphics/timeline/previous_frame.png.import +++ b/assets/graphics/timeline/previous_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/remove_frame.png.import b/assets/graphics/timeline/remove_frame.png.import index f833409ac..78d98dc5f 100644 --- a/assets/graphics/timeline/remove_frame.png.import +++ b/assets/graphics/timeline/remove_frame.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/timeline/tag.png.import b/assets/graphics/timeline/tag.png.import index 0f15161b0..260dcb614 100644 --- a/assets/graphics/timeline/tag.png.import +++ b/assets/graphics/timeline/tag.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=true diff --git a/assets/graphics/tools/bucket.png.import b/assets/graphics/tools/bucket.png.import index ceabd010c..9755194dd 100644 --- a/assets/graphics/tools/bucket.png.import +++ b/assets/graphics/tools/bucket.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/colorpicker.png.import b/assets/graphics/tools/colorpicker.png.import index 6977b8b42..6eadc05f0 100644 --- a/assets/graphics/tools/colorpicker.png.import +++ b/assets/graphics/tools/colorpicker.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/colorselect.png.import b/assets/graphics/tools/colorselect.png.import index 0c49ef5ba..7e58ed9c0 100644 --- a/assets/graphics/tools/colorselect.png.import +++ b/assets/graphics/tools/colorselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/bucket.png.import b/assets/graphics/tools/cursors/bucket.png.import index 9d4e9fbcf..ec044c133 100644 --- a/assets/graphics/tools/cursors/bucket.png.import +++ b/assets/graphics/tools/cursors/bucket.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/colorpicker.png.import b/assets/graphics/tools/cursors/colorpicker.png.import index 182614183..600c3796b 100644 --- a/assets/graphics/tools/cursors/colorpicker.png.import +++ b/assets/graphics/tools/cursors/colorpicker.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/colorselect.png.import b/assets/graphics/tools/cursors/colorselect.png.import index c58a43ad2..679b575be 100644 --- a/assets/graphics/tools/cursors/colorselect.png.import +++ b/assets/graphics/tools/cursors/colorselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/ellipseselect.png.import b/assets/graphics/tools/cursors/ellipseselect.png.import index 08e7d5bd7..77b82c422 100644 --- a/assets/graphics/tools/cursors/ellipseselect.png.import +++ b/assets/graphics/tools/cursors/ellipseselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/ellipsetool.png.import b/assets/graphics/tools/cursors/ellipsetool.png.import index 98f2889ca..fb317a10b 100644 --- a/assets/graphics/tools/cursors/ellipsetool.png.import +++ b/assets/graphics/tools/cursors/ellipsetool.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/eraser.png.import b/assets/graphics/tools/cursors/eraser.png.import index 6411db51f..5f2a9ae9b 100644 --- a/assets/graphics/tools/cursors/eraser.png.import +++ b/assets/graphics/tools/cursors/eraser.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/lasso.png.import b/assets/graphics/tools/cursors/lasso.png.import index a03e61a0e..bba12ea12 100644 --- a/assets/graphics/tools/cursors/lasso.png.import +++ b/assets/graphics/tools/cursors/lasso.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/linetool.png.import b/assets/graphics/tools/cursors/linetool.png.import index 4d95b3cdf..70557bfc4 100644 --- a/assets/graphics/tools/cursors/linetool.png.import +++ b/assets/graphics/tools/cursors/linetool.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/magicwand.png.import b/assets/graphics/tools/cursors/magicwand.png.import index abec05c9d..aed1e8433 100644 --- a/assets/graphics/tools/cursors/magicwand.png.import +++ b/assets/graphics/tools/cursors/magicwand.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/move.png.import b/assets/graphics/tools/cursors/move.png.import index f356c6e66..124d185ca 100644 --- a/assets/graphics/tools/cursors/move.png.import +++ b/assets/graphics/tools/cursors/move.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/pan.png.import b/assets/graphics/tools/cursors/pan.png.import index 28f2ce473..20b972874 100644 --- a/assets/graphics/tools/cursors/pan.png.import +++ b/assets/graphics/tools/cursors/pan.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/pencil.png.import b/assets/graphics/tools/cursors/pencil.png.import index f2b5f3e3c..2570a59fc 100644 --- a/assets/graphics/tools/cursors/pencil.png.import +++ b/assets/graphics/tools/cursors/pencil.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/polygonselect.png.import b/assets/graphics/tools/cursors/polygonselect.png.import index 8ead8f236..0f5d41405 100644 --- a/assets/graphics/tools/cursors/polygonselect.png.import +++ b/assets/graphics/tools/cursors/polygonselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/rectangletool.png.import b/assets/graphics/tools/cursors/rectangletool.png.import index ceed837b8..c69af75ce 100644 --- a/assets/graphics/tools/cursors/rectangletool.png.import +++ b/assets/graphics/tools/cursors/rectangletool.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/rectselect.png.import b/assets/graphics/tools/cursors/rectselect.png.import index 250769cc1..c44bafdb5 100644 --- a/assets/graphics/tools/cursors/rectselect.png.import +++ b/assets/graphics/tools/cursors/rectselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/shading.png.import b/assets/graphics/tools/cursors/shading.png.import index f935c94d7..495be5b57 100644 --- a/assets/graphics/tools/cursors/shading.png.import +++ b/assets/graphics/tools/cursors/shading.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/cursors/zoom.png.import b/assets/graphics/tools/cursors/zoom.png.import index 57fddb502..344657753 100644 --- a/assets/graphics/tools/cursors/zoom.png.import +++ b/assets/graphics/tools/cursors/zoom.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/ellipseselect.png.import b/assets/graphics/tools/ellipseselect.png.import index 18cb21254..3a81a7e71 100644 --- a/assets/graphics/tools/ellipseselect.png.import +++ b/assets/graphics/tools/ellipseselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/ellipsetool.png.import b/assets/graphics/tools/ellipsetool.png.import index 4150850ab..0688bcc0a 100644 --- a/assets/graphics/tools/ellipsetool.png.import +++ b/assets/graphics/tools/ellipsetool.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/eraser.png.import b/assets/graphics/tools/eraser.png.import index 1ac9bd402..a3dc3a62b 100644 --- a/assets/graphics/tools/eraser.png.import +++ b/assets/graphics/tools/eraser.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/lasso.png.import b/assets/graphics/tools/lasso.png.import index 13c2f701a..a92385972 100644 --- a/assets/graphics/tools/lasso.png.import +++ b/assets/graphics/tools/lasso.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/linetool.png.import b/assets/graphics/tools/linetool.png.import index ddff4272c..36f0f9e9d 100644 --- a/assets/graphics/tools/linetool.png.import +++ b/assets/graphics/tools/linetool.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/magicwand.png.import b/assets/graphics/tools/magicwand.png.import index 6b0088fb0..e59bacb18 100644 --- a/assets/graphics/tools/magicwand.png.import +++ b/assets/graphics/tools/magicwand.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/move.png.import b/assets/graphics/tools/move.png.import index 1ed0bc7f7..3802ffd8a 100644 --- a/assets/graphics/tools/move.png.import +++ b/assets/graphics/tools/move.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/pan.png.import b/assets/graphics/tools/pan.png.import index 770a09c19..e29bca6e2 100644 --- a/assets/graphics/tools/pan.png.import +++ b/assets/graphics/tools/pan.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/pencil.png.import b/assets/graphics/tools/pencil.png.import index ed3cc98c6..22472d1b8 100644 --- a/assets/graphics/tools/pencil.png.import +++ b/assets/graphics/tools/pencil.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/polygonselect.png.import b/assets/graphics/tools/polygonselect.png.import index d701cd4da..bb102074f 100644 --- a/assets/graphics/tools/polygonselect.png.import +++ b/assets/graphics/tools/polygonselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/rectangletool.png.import b/assets/graphics/tools/rectangletool.png.import index 47da099fb..a4e5b5123 100644 --- a/assets/graphics/tools/rectangletool.png.import +++ b/assets/graphics/tools/rectangletool.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/rectselect.png.import b/assets/graphics/tools/rectselect.png.import index 14d498784..9bf682ed6 100644 --- a/assets/graphics/tools/rectselect.png.import +++ b/assets/graphics/tools/rectselect.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/shading.png.import b/assets/graphics/tools/shading.png.import index 33a9c4af8..8745d9009 100644 --- a/assets/graphics/tools/shading.png.import +++ b/assets/graphics/tools/shading.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/tool_background.png.import b/assets/graphics/tools/tool_background.png.import index 5ef542e65..471ff2b22 100644 --- a/assets/graphics/tools/tool_background.png.import +++ b/assets/graphics/tools/tool_background.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/assets/graphics/tools/zoom.png.import b/assets/graphics/tools/zoom.png.import index 8a16a2f0f..8186e2b95 100644 --- a/assets/graphics/tools/zoom.png.import +++ b/assets/graphics/tools/zoom.png.import @@ -28,6 +28,7 @@ process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false process/invert_color=false +process/normal_map_invert_y=false stream=false size_limit=0 detect_3d=false diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index 0666e2649..74d04a1f2 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -1,85 +1,88 @@ extends Node - -enum GradientDirection {TOP, BOTTOM, LEFT, RIGHT} +enum GradientDirection { TOP, BOTTOM, LEFT, RIGHT } -func scale3X(sprite : Image, tol : float = 50) -> Image: +func scale_3x(sprite: Image, tol: float = 50) -> Image: var scaled := Image.new() - scaled.create(sprite.get_width()*3, sprite.get_height()*3, false, Image.FORMAT_RGBA8) + scaled.create(sprite.get_width() * 3, sprite.get_height() * 3, false, Image.FORMAT_RGBA8) scaled.lock() sprite.lock() - var a : Color - var b : Color - var c : Color - var d : Color - var e : Color - var f : Color - var g : Color - var h : Color - var i : Color + var a: Color + var b: Color + var c: Color + var d: Color + var e: Color + var f: Color + var g: Color + var h: Color + var i: Color - for x in range(1,sprite.get_width()-1): - for y in range(1,sprite.get_height()-1): - var xs : float = 3*x - var ys : float = 3*y + for x in range(1, sprite.get_width() - 1): + for y in range(1, sprite.get_height() - 1): + var xs: float = 3 * x + var ys: float = 3 * y - a = sprite.get_pixel(x-1,y-1) - b = sprite.get_pixel(x,y-1) - c = sprite.get_pixel(x+1,y-1) - d = sprite.get_pixel(x-1,y) - e = sprite.get_pixel(x,y) - f = sprite.get_pixel(x+1,y) - g = sprite.get_pixel(x-1,y+1) - h = sprite.get_pixel(x,y+1) - i = sprite.get_pixel(x+1,y+1) + a = sprite.get_pixel(x - 1, y - 1) + b = sprite.get_pixel(x, y - 1) + c = sprite.get_pixel(x + 1, y - 1) + d = sprite.get_pixel(x - 1, y) + e = sprite.get_pixel(x, y) + f = sprite.get_pixel(x + 1, y) + g = sprite.get_pixel(x - 1, y + 1) + h = sprite.get_pixel(x, y + 1) + i = sprite.get_pixel(x + 1, y + 1) - var db : bool = similarColors(d, b, tol) - var dh : bool = similarColors(d, h, tol) - var bf : bool = similarColors(f, b, tol) - var ec : bool = similarColors(e, c, tol) - var ea : bool = similarColors(e, a, tol) - var fh : bool = similarColors(f, h, tol) - var eg : bool = similarColors(e, g, tol) - var ei : bool = similarColors(e, i, tol) + var db: bool = similar_colors(d, b, tol) + var dh: bool = similar_colors(d, h, tol) + var bf: bool = similar_colors(f, b, tol) + var ec: bool = similar_colors(e, c, tol) + var ea: bool = similar_colors(e, a, tol) + var fh: bool = similar_colors(f, h, tol) + var eg: bool = similar_colors(e, g, tol) + var ei: bool = similar_colors(e, i, tol) - scaled.set_pixel(xs-1, ys-1, d if (db and !dh and !bf) else e ) - scaled.set_pixel(xs, ys-1, b if (db and !dh and !bf and !ec) or - (bf and !db and !fh and !ea) else e) - scaled.set_pixel(xs+1, ys-1, f if (bf and !db and !fh) else e) - scaled.set_pixel(xs-1, ys, d if (dh and !fh and !db and !ea) or - (db and !dh and !bf and !eg) else e) - scaled.set_pixel(xs, ys, e); - scaled.set_pixel(xs+1, ys, f if (bf and !db and !fh and !ei) or - (fh and !bf and !dh and !ec) else e) - scaled.set_pixel(xs-1, ys+1, d if (dh and !fh and !db) else e) - scaled.set_pixel(xs, ys+1, h if (fh and !bf and !dh and !eg) or - (dh and !fh and !db and !ei) else e) - scaled.set_pixel(xs+1, ys+1, f if (fh and !bf and !dh) else e) + scaled.set_pixel(xs - 1, ys - 1, d if (db and !dh and !bf) else e) + scaled.set_pixel( + xs, ys - 1, b if (db and !dh and !bf and !ec) or (bf and !db and !fh and !ea) else e + ) + scaled.set_pixel(xs + 1, ys - 1, f if (bf and !db and !fh) else e) + scaled.set_pixel( + xs - 1, ys, d if (dh and !fh and !db and !ea) or (db and !dh and !bf and !eg) else e + ) + scaled.set_pixel(xs, ys, e) + scaled.set_pixel( + xs + 1, ys, f if (bf and !db and !fh and !ei) or (fh and !bf and !dh and !ec) else e + ) + scaled.set_pixel(xs - 1, ys + 1, d if (dh and !fh and !db) else e) + scaled.set_pixel( + xs, ys + 1, h if (fh and !bf and !dh and !eg) or (dh and !fh and !db and !ei) else e + ) + scaled.set_pixel(xs + 1, ys + 1, f if (fh and !bf and !dh) else e) scaled.unlock() sprite.unlock() return scaled -func rotxel(sprite : Image, angle : float, pivot : Vector2) -> void: +func rotxel(sprite: Image, angle: float, pivot: Vector2) -> void: # If angle is simple, then nn rotation is the best - if angle == 0 || angle == PI/2 || angle == PI || angle == 2*PI: + if angle == 0 || angle == PI / 2 || angle == PI || angle == 2 * PI: nn_rotate(sprite, angle, pivot) return - var aux : Image = Image.new() + var aux: Image = Image.new() aux.copy_from(sprite) - var ox : int - var oy : int - var p : Color + var ox: int + var oy: int + var p: Color aux.lock() sprite.lock() for x in sprite.get_size().x: for y in sprite.get_size().y: - var dx = 3*(x - pivot.x) - var dy = 3*(y - pivot.y) - var found_pixel : bool = false + var dx = 3 * (x - pivot.x) + var dy = 3 * (y - pivot.y) + var found_pixel: bool = false for k in range(9): var i = -1 + k % 3 # warning-ignore:integer_division @@ -87,95 +90,182 @@ func rotxel(sprite : Image, angle : float, pivot : Vector2) -> void: var dir = atan2(dy + j, dx + i) var mag = sqrt(pow(dx + i, 2) + pow(dy + j, 2)) dir -= angle - ox = round(pivot.x*3 + 1 + mag*cos(dir)) - oy = round(pivot.y*3 + 1 + mag*sin(dir)) + ox = round(pivot.x * 3 + 1 + mag * cos(dir)) + oy = round(pivot.y * 3 + 1 + mag * sin(dir)) - if (sprite.get_width() % 2 != 0): + if sprite.get_width() % 2 != 0: ox += 1 oy += 1 - if (ox >= 0 && ox < sprite.get_width()*3 - && oy >= 0 && oy < sprite.get_height()*3): - found_pixel = true - break + if ( + ox >= 0 + && ox < sprite.get_width() * 3 + && oy >= 0 + && oy < sprite.get_height() * 3 + ): + found_pixel = true + break if !found_pixel: - sprite.set_pixel(x, y, Color(0,0,0,0)) + sprite.set_pixel(x, y, Color(0, 0, 0, 0)) continue - var fil : int = oy % 3 - var col : int = ox % 3 - var index : int = col + 3*fil + var fil: int = oy % 3 + var col: int = ox % 3 + var index: int = col + 3 * fil - ox = round((ox - 1)/3.0); - oy = round((oy - 1)/3.0); - var a : Color - var b : Color - var c : Color - var d : Color - var e : Color - var f : Color - var g : Color - var h : Color - var i : Color - if (ox == 0 || ox == sprite.get_width() - 1 || - oy == 0 || oy == sprite.get_height() - 1): - p = aux.get_pixel(ox, oy) + ox = round((ox - 1) / 3.0) + oy = round((oy - 1) / 3.0) + var a: Color + var b: Color + var c: Color + var d: Color + var e: Color + var f: Color + var g: Color + var h: Color + var i: Color + if ox == 0 || ox == sprite.get_width() - 1 || oy == 0 || oy == sprite.get_height() - 1: + p = aux.get_pixel(ox, oy) else: - a = aux.get_pixel(ox-1,oy-1); - b = aux.get_pixel(ox,oy-1); - c = aux.get_pixel(ox+1,oy-1); - d = aux.get_pixel(ox-1,oy); - e = aux.get_pixel(ox,oy); - f = aux.get_pixel(ox+1,oy); - g = aux.get_pixel(ox-1,oy+1); - h = aux.get_pixel(ox,oy+1); - i = aux.get_pixel(ox+1,oy+1); + a = aux.get_pixel(ox - 1, oy - 1) + b = aux.get_pixel(ox, oy - 1) + c = aux.get_pixel(ox + 1, oy - 1) + d = aux.get_pixel(ox - 1, oy) + e = aux.get_pixel(ox, oy) + f = aux.get_pixel(ox + 1, oy) + g = aux.get_pixel(ox - 1, oy + 1) + h = aux.get_pixel(ox, oy + 1) + i = aux.get_pixel(ox + 1, oy + 1) - match(index): + match index: 0: - p = d if (similarColors(d,b) && !similarColors(d,h) - && !similarColors(b,f)) else e; + p = ( + d + if ( + similar_colors(d, b) + && !similar_colors(d, h) + && !similar_colors(b, f) + ) + else e + ) 1: - p = b if ((similarColors(d,b) && !similarColors(d,h) && - !similarColors(b,f) && !similarColors(e,c)) || - (similarColors(b,f) && !similarColors(d,b) && - !similarColors(f,h) && !similarColors(e,a))) else e; + p = ( + b + if ( + ( + similar_colors(d, b) + && !similar_colors(d, h) + && !similar_colors(b, f) + && !similar_colors(e, c) + ) + || ( + similar_colors(b, f) + && !similar_colors(d, b) + && !similar_colors(f, h) + && !similar_colors(e, a) + ) + ) + else e + ) 2: - p = f if (similarColors(b,f) && !similarColors(d,b) && - !similarColors(f,h)) else e; + p = ( + f + if ( + similar_colors(b, f) + && !similar_colors(d, b) + && !similar_colors(f, h) + ) + else e + ) 3: - p = d if ((similarColors(d,h) && !similarColors(f,h) && - !similarColors(d,b) && !similarColors(e,a)) || - (similarColors(d,b) && !similarColors(d,h) && - !similarColors(b,f) && !similarColors(e,g))) else e; + p = ( + d + if ( + ( + similar_colors(d, h) + && !similar_colors(f, h) + && !similar_colors(d, b) + && !similar_colors(e, a) + ) + || ( + similar_colors(d, b) + && !similar_colors(d, h) + && !similar_colors(b, f) + && !similar_colors(e, g) + ) + ) + else e + ) 4: p = e 5: - p = f if((similarColors(b,f) && !similarColors(d,b) && - !similarColors(f,h) && !similarColors(e,i)) - || (similarColors(f,h) && !similarColors(b,f) && - !similarColors(d,h) && !similarColors(e,c))) else e; + p = ( + f + if ( + ( + similar_colors(b, f) + && !similar_colors(d, b) + && !similar_colors(f, h) + && !similar_colors(e, i) + ) + || ( + similar_colors(f, h) + && !similar_colors(b, f) + && !similar_colors(d, h) + && !similar_colors(e, c) + ) + ) + else e + ) 6: - p = d if (similarColors(d,h) && !similarColors(f,h) && - !similarColors(d,b)) else e; + p = ( + d + if ( + similar_colors(d, h) + && !similar_colors(f, h) + && !similar_colors(d, b) + ) + else e + ) 7: - p = h if ((similarColors(f,h) && !similarColors(f,b) && - !similarColors(d,h) && !similarColors(e,g)) - || (similarColors(d,h) && !similarColors(f,h) && - !similarColors(d,b) && !similarColors(e,i))) else e; + p = ( + h + if ( + ( + similar_colors(f, h) + && !similar_colors(f, b) + && !similar_colors(d, h) + && !similar_colors(e, g) + ) + || ( + similar_colors(d, h) + && !similar_colors(f, h) + && !similar_colors(d, b) + && !similar_colors(e, i) + ) + ) + else e + ) 8: - p = f if (similarColors(f,h) && !similarColors(f,b) && - !similarColors(d,h)) else e; + p = ( + f + if ( + similar_colors(f, h) + && !similar_colors(f, b) + && !similar_colors(d, h) + ) + else e + ) sprite.set_pixel(x, y, p) sprite.unlock() aux.unlock() -func fake_rotsprite(sprite : Image, angle : float, pivot : Vector2) -> void: +func fake_rotsprite(sprite: Image, angle: float, pivot: Vector2) -> void: var selected_sprite := Image.new() selected_sprite.copy_from(sprite) - selected_sprite.copy_from(scale3X(selected_sprite)) + selected_sprite.copy_from(scale_3x(selected_sprite)) nn_rotate(selected_sprite, angle, pivot * 3) # warning-ignore:integer_division # warning-ignore:integer_division @@ -183,8 +273,8 @@ func fake_rotsprite(sprite : Image, angle : float, pivot : Vector2) -> void: sprite.blit_rect(selected_sprite, Rect2(Vector2.ZERO, selected_sprite.get_size()), Vector2.ZERO) -func nn_rotate(sprite : Image, angle : float, pivot : Vector2) -> void: - var aux : Image = Image.new() +func nn_rotate(sprite: Image, angle: float, pivot: Vector2) -> void: + var aux: Image = Image.new() aux.copy_from(sprite) sprite.lock() aux.lock() @@ -192,44 +282,57 @@ func nn_rotate(sprite : Image, angle : float, pivot : Vector2) -> void: var oy: int for x in range(sprite.get_width()): for y in range(sprite.get_height()): - ox = (x - pivot.x)*cos(angle) + (y - pivot.y)*sin(angle) + pivot.x - oy = -(x - pivot.x)*sin(angle) + (y - pivot.y)*cos(angle) + pivot.y + ox = (x - pivot.x) * cos(angle) + (y - pivot.y) * sin(angle) + pivot.x + oy = -(x - pivot.x) * sin(angle) + (y - pivot.y) * cos(angle) + pivot.y if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height(): sprite.set_pixel(x, y, aux.get_pixel(ox, oy)) else: - sprite.set_pixel(x, y, Color(0,0,0,0)) + sprite.set_pixel(x, y, Color(0, 0, 0, 0)) sprite.unlock() aux.unlock() -func similarColors(c1 : Color, c2 : Color, tol : float = 100) -> bool: - var dist = colorDistance(c1, c2) +func similar_colors(c1: Color, c2: Color, tol: float = 100) -> bool: + var dist = color_distance(c1, c2) return dist <= tol -func colorDistance(c1 : Color, c2 : Color) -> float: - return sqrt(pow((c1.r - c2.r)*255, 2) + pow((c1.g - c2.g)*255, 2) - + pow((c1.b - c2.b)*255, 2) + pow((c1.a - c2.a)*255, 2)) +func color_distance(c1: Color, c2: Color) -> float: + return sqrt( + ( + pow((c1.r - c2.r) * 255, 2) + + pow((c1.g - c2.g) * 255, 2) + + pow((c1.b - c2.b) * 255, 2) + + pow((c1.a - c2.a) * 255, 2) + ) + ) + # Image effects -func scale_image(width : int, height : int, interpolation : int) -> void: + +func scale_image(width: int, height: int, interpolation: int) -> void: general_do_scale(width, height) for f in Global.current_project.frames: for i in range(f.cels.size() - 1, -1, -1): var sprite := Image.new() sprite.copy_from(f.cels[i].image) - # Different method for scale3x + # Different method for scale_3x if interpolation == 5: - var times : Vector2 = Vector2(ceil(width/(3.0*sprite.get_width())),ceil(height/(3.0*sprite.get_height()))) - for _j in range(max(times.x,times.y)): - sprite.copy_from(scale3X(sprite)) + var times: Vector2 = Vector2( + ceil(width / (3.0 * sprite.get_width())), + ceil(height / (3.0 * sprite.get_height())) + ) + for _j in range(max(times.x, times.y)): + sprite.copy_from(scale_3x(sprite)) sprite.resize(width, height, 0) else: sprite.resize(width, height, interpolation) Global.current_project.undo_redo.add_do_property(f.cels[i].image, "data", sprite.data) - Global.current_project.undo_redo.add_undo_property(f.cels[i].image, "data", f.cels[i].image.data) + Global.current_project.undo_redo.add_undo_property( + f.cels[i].image, "data", f.cels[i].image.data + ) general_undo_scale() @@ -239,17 +342,19 @@ func centralize() -> void: # Find used rect of the current frame (across all of the layers) var used_rect := Rect2() for cel in Global.current_project.frames[Global.current_project.current_frame].cels: - var cel_rect : Rect2 = cel.image.get_used_rect() + var cel_rect: Rect2 = cel.image.get_used_rect() if not cel_rect.has_no_area(): used_rect = cel_rect if used_rect.has_no_area() else used_rect.merge(cel_rect) if used_rect.has_no_area(): return - var offset : Vector2 = (0.5 * (Global.current_project.size - used_rect.size)).floor() + var offset: Vector2 = (0.5 * (Global.current_project.size - used_rect.size)).floor() general_do_centralize() for c in Global.current_project.frames[Global.current_project.current_frame].cels: var sprite := Image.new() - sprite.create(Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8) + sprite.create( + Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8 + ) sprite.blend_rect(c.image, used_rect, offset) Global.current_project.undo_redo.add_do_property(c.image, "data", sprite.data) Global.current_project.undo_redo.add_undo_property(c.image, "data", c.image.data) @@ -261,12 +366,12 @@ func crop_image() -> void: var used_rect := Rect2() for f in Global.current_project.frames: for cel in f.cels: - cel.image.unlock() # May be unneeded now, but keep it just in case - var cel_used_rect : Rect2 = cel.image.get_used_rect() - if cel_used_rect == Rect2(0, 0, 0, 0): # If the cel has no content + cel.image.unlock() # May be unneeded now, but keep it just in case + var cel_used_rect: Rect2 = cel.image.get_used_rect() + if cel_used_rect == Rect2(0, 0, 0, 0): # If the cel has no content continue - if used_rect == Rect2(0, 0, 0, 0): # If we still haven't found the first cel with content + if used_rect == Rect2(0, 0, 0, 0): # If we still haven't found the first cel with content used_rect = cel_used_rect else: used_rect = used_rect.merge(cel_used_rect) @@ -281,33 +386,37 @@ func crop_image() -> void: # Loop through all the cels to crop them for f in Global.current_project.frames: for cel in f.cels: - var sprite : Image = cel.image.get_rect(used_rect) + var sprite: Image = cel.image.get_rect(used_rect) Global.current_project.undo_redo.add_do_property(cel.image, "data", sprite.data) Global.current_project.undo_redo.add_undo_property(cel.image, "data", cel.image.data) general_undo_scale() -func resize_canvas(width : int, height : int, offset_x : int, offset_y : int) -> void: +func resize_canvas(width: int, height: int, offset_x: int, offset_y: int) -> void: general_do_scale(width, height) for f in Global.current_project.frames: for c in f.cels: var sprite := Image.new() sprite.create(width, height, false, Image.FORMAT_RGBA8) - sprite.blend_rect(c.image, Rect2(Vector2.ZERO, Global.current_project.size), Vector2(offset_x, offset_y)) + sprite.blend_rect( + c.image, + Rect2(Vector2.ZERO, Global.current_project.size), + Vector2(offset_x, offset_y) + ) Global.current_project.undo_redo.add_do_property(c.image, "data", sprite.data) Global.current_project.undo_redo.add_undo_property(c.image, "data", c.image.data) general_undo_scale() -func general_do_scale(width : int, height : int) -> void: +func general_do_scale(width: int, height: int) -> void: var project: Project = Global.current_project var size := Vector2(width, height).floor() var x_ratio = project.size.x / width var y_ratio = project.size.y / height - var bitmap : BitMap + var bitmap: BitMap bitmap = project.resize_bitmap(project.selection_bitmap, size) var new_x_symmetry_point = project.x_symmetry_point / x_ratio @@ -335,8 +444,12 @@ func general_undo_scale() -> void: project.undo_redo.add_undo_property(project, "selection_bitmap", project.selection_bitmap) project.undo_redo.add_undo_property(project, "x_symmetry_point", project.x_symmetry_point) project.undo_redo.add_undo_property(project, "y_symmetry_point", project.y_symmetry_point) - project.undo_redo.add_undo_property(project.x_symmetry_axis, "points", project.x_symmetry_axis.points) - project.undo_redo.add_undo_property(project.y_symmetry_axis, "points", project.y_symmetry_axis.points) + project.undo_redo.add_undo_property( + project.x_symmetry_axis, "points", project.x_symmetry_axis.points + ) + project.undo_redo.add_undo_property( + project.y_symmetry_axis, "points", project.y_symmetry_axis.points + ) project.undo_redo.add_undo_method(Global, "undo") project.undo_redo.add_do_method(Global, "redo") project.undo_redo.commit_action() @@ -355,50 +468,15 @@ func general_undo_centralize() -> void: project.undo_redo.commit_action() -# TO BE REMOVED -# func invert_image_colors(image : Image, affect_selection : bool, project : Project, red := true, green := true, blue := true, alpha := false) -> void: -# image.lock() -# for x in project.size.x: -# for y in project.size.y: -# var pos := Vector2(x, y) -# if affect_selection and !project.can_pixel_get_drawn(pos): -# continue -# var px_color := image.get_pixelv(pos) -# # Manually invert each color channel -# if red: -# px_color.r = 1.0 - px_color.r -# if green: -# px_color.g = 1.0 - px_color.g -# if blue: -# px_color.b = 1.0 - px_color.b -# if alpha: -# px_color.a = 1.0 - px_color.a -# image.set_pixelv(pos, px_color) - - -# TO BE REMOVED -# func desaturate_image(image : Image, affect_selection : bool, project : Project, red := true, green := true, blue := true, alpha := false) -> void: -# image.lock() -# for x in project.size.x: -# for y in project.size.y: -# var pos := Vector2(x, y) -# if affect_selection and !project.can_pixel_get_drawn(pos): -# continue -# var px_color := image.get_pixelv(pos) -# var gray = px_color.v -# if red: -# px_color.r = gray -# if green: -# px_color.g = gray -# if blue: -# px_color.b = gray -# if alpha: -# px_color.a = gray - -# image.set_pixelv(pos, px_color) - - -func generate_outline(image : Image, affect_selection : bool, project : Project, outline_color : Color, thickness : int, diagonal : bool, inside_image : bool) -> void: +func generate_outline( + image: Image, + affect_selection: bool, + project: Project, + outline_color: Color, + thickness: int, + diagonal: bool, + inside_image: bool +) -> void: if image.is_invisible(): return var new_image := Image.new() @@ -417,117 +495,144 @@ func generate_outline(image : Image, affect_selection : bool, project : Project, for i in range(1, thickness + 1): if inside_image: - var outline_pos : Vector2 = pos + Vector2.LEFT # Left + var outline_pos: Vector2 = pos + Vector2.LEFT # Left if outline_pos.x < 0 || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + Vector2.RIGHT * (i - 1) + var new_pos: Vector2 = pos + Vector2.RIGHT * (i - 1) if new_pos.x < Global.current_project.size.x: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) - outline_pos = pos + Vector2.RIGHT # Right - if outline_pos.x >= Global.current_project.size.x || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + Vector2.LEFT * (i - 1) + outline_pos = pos + Vector2.RIGHT # Right + if ( + outline_pos.x >= Global.current_project.size.x + || image.get_pixelv(outline_pos).a == 0 + ): + var new_pos: Vector2 = pos + Vector2.LEFT * (i - 1) if new_pos.x >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) - outline_pos = pos + Vector2.UP # Up + outline_pos = pos + Vector2.UP # Up if outline_pos.y < 0 || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + Vector2.DOWN * (i - 1) + var new_pos: Vector2 = pos + Vector2.DOWN * (i - 1) if new_pos.y < Global.current_project.size.y: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) - outline_pos = pos + Vector2.DOWN # Down - if outline_pos.y >= Global.current_project.size.y || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + Vector2.UP * (i - 1) + outline_pos = pos + Vector2.DOWN # Down + if ( + outline_pos.y >= Global.current_project.size.y + || image.get_pixelv(outline_pos).a == 0 + ): + var new_pos: Vector2 = pos + Vector2.UP * (i - 1) if new_pos.y >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) if diagonal: - outline_pos = pos + (Vector2.LEFT + Vector2.UP) # Top left - if (outline_pos.x < 0 && outline_pos.y < 0) || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + (Vector2.RIGHT + Vector2.DOWN) * (i - 1) - if new_pos.x < Global.current_project.size.x && new_pos.y < Global.current_project.size.y: + outline_pos = pos + (Vector2.LEFT + Vector2.UP) # Top left + if ( + (outline_pos.x < 0 && outline_pos.y < 0) + || image.get_pixelv(outline_pos).a == 0 + ): + var new_pos: Vector2 = pos + (Vector2.RIGHT + Vector2.DOWN) * (i - 1) + if ( + new_pos.x < Global.current_project.size.x + && new_pos.y < Global.current_project.size.y + ): var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) - outline_pos = pos + (Vector2.LEFT + Vector2.DOWN) # Bottom left - if (outline_pos.x < 0 && outline_pos.y >= Global.current_project.size.y) || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + (Vector2.RIGHT + Vector2.UP) * (i - 1) + outline_pos = pos + (Vector2.LEFT + Vector2.DOWN) # Bottom left + if ( + (outline_pos.x < 0 && outline_pos.y >= Global.current_project.size.y) + || image.get_pixelv(outline_pos).a == 0 + ): + var new_pos: Vector2 = pos + (Vector2.RIGHT + Vector2.UP) * (i - 1) if new_pos.x < Global.current_project.size.x && new_pos.y >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) - outline_pos = pos + (Vector2.RIGHT + Vector2.UP) # Top right - if (outline_pos.x >= Global.current_project.size.x && outline_pos.y < 0) || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + (Vector2.LEFT + Vector2.DOWN) * (i - 1) + outline_pos = pos + (Vector2.RIGHT + Vector2.UP) # Top right + if ( + (outline_pos.x >= Global.current_project.size.x && outline_pos.y < 0) + || image.get_pixelv(outline_pos).a == 0 + ): + var new_pos: Vector2 = pos + (Vector2.LEFT + Vector2.DOWN) * (i - 1) if new_pos.x >= 0 && new_pos.y < Global.current_project.size.y: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) - outline_pos = pos + (Vector2.RIGHT + Vector2.DOWN) # Bottom right - if (outline_pos.x >= Global.current_project.size.x && outline_pos.y >= Global.current_project.size.y) || image.get_pixelv(outline_pos).a == 0: - var new_pos : Vector2 = pos + (Vector2.LEFT + Vector2.UP) * (i - 1) + outline_pos = pos + (Vector2.RIGHT + Vector2.DOWN) # Bottom right + if ( + ( + outline_pos.x >= Global.current_project.size.x + && outline_pos.y >= Global.current_project.size.y + ) + || image.get_pixelv(outline_pos).a == 0 + ): + var new_pos: Vector2 = pos + (Vector2.LEFT + Vector2.UP) * (i - 1) if new_pos.x >= 0 && new_pos.y >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a > 0: new_image.set_pixelv(new_pos, outline_color) else: - var new_pos : Vector2 = pos + Vector2.LEFT * i # Left + var new_pos: Vector2 = pos + Vector2.LEFT * i # Left if new_pos.x >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) - new_pos = pos + Vector2.RIGHT * i # Right + new_pos = pos + Vector2.RIGHT * i # Right if new_pos.x < Global.current_project.size.x: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) - new_pos = pos + Vector2.UP * i # Up + new_pos = pos + Vector2.UP * i # Up if new_pos.y >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) - new_pos = pos + Vector2.DOWN * i # Down + new_pos = pos + Vector2.DOWN * i # Down if new_pos.y < Global.current_project.size.y: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) if diagonal: - new_pos = pos + (Vector2.LEFT + Vector2.UP) * i # Top left + new_pos = pos + (Vector2.LEFT + Vector2.UP) * i # Top left if new_pos.x >= 0 && new_pos.y >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) - new_pos = pos + (Vector2.LEFT + Vector2.DOWN) * i # Bottom left + new_pos = pos + (Vector2.LEFT + Vector2.DOWN) * i # Bottom left if new_pos.x >= 0 && new_pos.y < Global.current_project.size.y: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) - new_pos = pos + (Vector2.RIGHT + Vector2.UP) * i # Top right + new_pos = pos + (Vector2.RIGHT + Vector2.UP) * i # Top right if new_pos.x < Global.current_project.size.x && new_pos.y >= 0: var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) - new_pos = pos + (Vector2.RIGHT + Vector2.DOWN) * i # Bottom right - if new_pos.x < Global.current_project.size.x && new_pos.y < Global.current_project.size.y: + new_pos = pos + (Vector2.RIGHT + Vector2.DOWN) * i # Bottom right + if ( + new_pos.x < Global.current_project.size.x + && new_pos.y < Global.current_project.size.y + ): var new_pixel = image.get_pixelv(new_pos) if new_pixel.a == 0: new_image.set_pixelv(new_pos, outline_color) @@ -537,51 +642,20 @@ func generate_outline(image : Image, affect_selection : bool, project : Project, image.copy_from(new_image) -# TO BE REMOVED -# func adjust_hsv(img: Image, delta_h : float, delta_s : float, delta_v : float, affect_selection : bool, project : Project) -> void: -# img.lock() -# for x in project.size.x: -# for y in project.size.y: -# var pos := Vector2(x, y) -# if affect_selection and !project.can_pixel_get_drawn(pos): -# continue -# var c : Color = img.get_pixelv(pos) -# # Hue -# var hue = range_lerp(c.h,0,1,-180,180) -# hue = hue + delta_h - -# while(hue >= 180): -# hue -= 360 -# while(hue < -180): -# hue += 360 - -# # Saturation -# var sat = c.s -# if delta_s > 0: -# sat = range_lerp(delta_s,0,100,c.s,1) -# elif delta_s < 0: -# sat = range_lerp(delta_s,-100,0,0,c.s) - -# # Value -# var val = c.v -# if delta_v > 0: -# val = range_lerp(delta_v,0,100,c.v,1) -# elif delta_v < 0: -# val = range_lerp(delta_v,-100,0,0,c.v) - -# c.h = range_lerp(hue,-180,180,0,1) -# c.s = sat -# c.v = val -# img.set_pixelv(pos, c) - - -func generate_gradient(image : Image, colors : Array, steps : int, direction : int, affect_selection : bool, project : Project) -> void: +func generate_gradient( + image: Image, + colors: Array, + steps: int, + direction: int, + affect_selection: bool, + project: Project +) -> void: if colors.size() < 2: return var t = 1.0 / (steps - 1) for i in range(1, steps - 1): - var color : Color + var color: Color color = colors[-1].linear_interpolate(colors[0], t * i) colors.insert(1, color) @@ -605,7 +679,7 @@ func generate_gradient(image : Image, colors : Array, steps : int, direction : i var start = i * gradient_size var end = (i + 1) * gradient_size for yy in range(start, end): - var pos : Vector2 = Vector2(xx, yy) + draw_rectangle.position + var pos: Vector2 = Vector2(xx, yy) + draw_rectangle.position if selection and !project.selection_bitmap.get_bit(pos): continue image.set_pixelv(pos, colors[i]) @@ -617,7 +691,7 @@ func generate_gradient(image : Image, colors : Array, steps : int, direction : i var start = i * gradient_size var end = (i + 1) * gradient_size for xx in range(start, end): - var pos : Vector2 = Vector2(xx, yy) + draw_rectangle.position + var pos: Vector2 = Vector2(xx, yy) + draw_rectangle.position if selection and !project.selection_bitmap.get_bit(pos): continue image.set_pixelv(pos, colors[i]) diff --git a/src/Autoload/Export.gd b/src/Autoload/Export.gd index 73258a6d7..798aa8b3e 100644 --- a/src/Autoload/Export.gd +++ b/src/Autoload/Export.gd @@ -1,44 +1,42 @@ extends Node +enum ExportTab { FRAME = 0, SPRITESHEET = 1, ANIMATION = 2 } +enum Orientation { ROWS = 0, COLUMNS = 1 } +enum AnimationType { MULTIPLE_FILES = 0, ANIMATED = 1 } +enum AnimationDirection { FORWARD = 0, BACKWARDS = 1, PING_PONG = 2 } +enum FileFormat { PNG = 0, GIF = 1 } + # Gif exporter const GIFExporter = preload("res://addons/gdgifexporter/exporter.gd") const MedianCutQuantization = preload("res://addons/gdgifexporter/quantization/median_cut.gd") -enum ExportTab { FRAME = 0, SPRITESHEET = 1, ANIMATION = 2 } -var current_tab : int = ExportTab.FRAME - +var current_tab: int = ExportTab.FRAME # Frame options var frame_number := 0 - # All frames and their layers processed/blended into images -var processed_images = [] # Image[] +var processed_images = [] # Image[] # Spritesheet options -var frame_current_tag := 0 # Export only current frame tag +var frame_current_tag := 0 # Export only current frame tag var number_of_frames := 1 -enum Orientation { ROWS = 0, COLUMNS = 1 } -var orientation : int = Orientation.ROWS -# How many rows/columns before new line is added -var lines_count := 1 +var orientation: int = Orientation.ROWS -# Animation options -enum AnimationType { MULTIPLE_FILES = 0, ANIMATED = 1 } -var animation_type : int = AnimationType.MULTIPLE_FILES -enum AnimationDirection { FORWARD = 0, BACKWARDS = 1, PING_PONG = 2 } -var direction : int = AnimationDirection.FORWARD +var lines_count := 1 # How many rows/columns before new line is added + +var animation_type: int = AnimationType.MULTIPLE_FILES +var direction: int = AnimationDirection.FORWARD # Options var resize := 100 -var interpolation := 0 # Image.Interpolation -var new_dir_for_each_frame_tag : bool = true # you don't need to store this after export +var interpolation := 0 # Image.Interpolation +var new_dir_for_each_frame_tag: bool = true # you don't need to store this after export # Export directory path and export file name var directory_path := "" var file_name := "untitled" -var file_format : int = FileFormat.PNG -enum FileFormat { PNG = 0, GIF = 1} +var file_format: int = FileFormat.PNG -var was_exported : bool = false +var was_exported: bool = false # Export coroutine signal var stop_export = false @@ -71,7 +69,9 @@ func process_frame() -> void: processed_images.clear() var frame = Global.current_project.frames[frame_number - 1] var image := Image.new() - image.create(Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8) + image.create( + Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8 + ) blend_layers(image, frame) processed_images.append(image) @@ -83,7 +83,7 @@ func process_spritesheet() -> void: if frame_current_tag > 0: var frame_start = Global.current_project.animation_tags[frame_current_tag - 1].from var frame_end = Global.current_project.animation_tags[frame_current_tag - 1].to - frames = Global.current_project.frames.slice(frame_start-1, frame_end-1, 1, true) + frames = Global.current_project.frames.slice(frame_start - 1, frame_end - 1, 1, true) else: frames = Global.current_project.frames @@ -91,8 +91,16 @@ func process_spritesheet() -> void: number_of_frames = frames.size() # If rows mode selected calculate columns count and vice versa - var spritesheet_columns = lines_count if orientation == Orientation.ROWS else frames_divided_by_spritesheet_lines() - var spritesheet_rows = lines_count if orientation == Orientation.COLUMNS else frames_divided_by_spritesheet_lines() + var spritesheet_columns = ( + lines_count + if orientation == Orientation.ROWS + else frames_divided_by_spritesheet_lines() + ) + var spritesheet_rows = ( + lines_count + if orientation == Orientation.COLUMNS + else frames_divided_by_spritesheet_lines() + ) var width = Global.current_project.size.x * spritesheet_columns var height = Global.current_project.size.y * spritesheet_rows @@ -131,12 +139,14 @@ func process_animation() -> void: processed_images.clear() for frame in Global.current_project.frames: var image := Image.new() - image.create(Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8) + image.create( + Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8 + ) blend_layers(image, frame) processed_images.append(image) -func export_processed_images(ignore_overwrites: bool, export_dialog: AcceptDialog ) -> bool: +func export_processed_images(ignore_overwrites: bool, export_dialog: AcceptDialog) -> bool: # Stop export if directory path or file name are not valid var dir = Directory.new() if not dir.dir_exists(directory_path) or not file_name.is_valid_filename(): @@ -147,17 +157,25 @@ func export_processed_images(ignore_overwrites: bool, export_dialog: AcceptDialo var export_paths = [] for i in range(processed_images.size()): stop_export = false - var multiple_files := true if (current_tab == ExportTab.ANIMATION and animation_type == AnimationType.MULTIPLE_FILES) else false + var multiple_files := ( + true + if ( + current_tab == ExportTab.ANIMATION + and animation_type == AnimationType.MULTIPLE_FILES + ) + else false + ) var export_path = create_export_path(multiple_files, i + 1) - # If user want to create new directory for each animation tag then check if directories exist and create them if not + # If user want to create new directory for each animation tag then check + # if directories exist and create them if not if multiple_files and new_dir_for_each_frame_tag: var frame_tag_directory := Directory.new() if not frame_tag_directory.dir_exists(export_path.get_base_dir()): frame_tag_directory.open(directory_path) frame_tag_directory.make_dir(export_path.get_base_dir().get_file()) # Check if the file already exists - var fileCheck = File.new() - if fileCheck.file_exists(export_path): + var file_check: File = File.new() + if file_check.file_exists(export_path): # Ask user if he want's to overwrite the file if not was_exported or (was_exported and not ignore_overwrites): # Overwrite existing file? @@ -181,11 +199,17 @@ func export_processed_images(ignore_overwrites: bool, export_dialog: AcceptDialo else: if gif_export_thread.is_active(): gif_export_thread.wait_to_finish() - gif_export_thread.start(self, "export_gif", {"export_dialog": export_dialog, "export_paths": export_paths}) + gif_export_thread.start( + self, "export_gif", {"export_dialog": export_dialog, "export_paths": export_paths} + ) else: for i in range(processed_images.size()): if OS.get_name() == "HTML5": - JavaScript.download_buffer(processed_images[i].save_png_to_buffer(), export_paths[i].get_file(), "image/png") + JavaScript.download_buffer( + processed_images[i].save_png_to_buffer(), + export_paths[i].get_file(), + "image/png" + ) else: var err = processed_images[i].save_png(export_paths[i]) if err != OK: @@ -196,7 +220,9 @@ func export_processed_images(ignore_overwrites: bool, export_dialog: AcceptDialo # Store settings for quick export and when the dialog is opened again was_exported = true Global.current_project.was_exported = true - Global.top_menu_container.file_menu.set_item_text(6, tr("Export") + " %s" % (file_name + file_format_string(file_format))) + Global.top_menu_container.file_menu.set_item_text( + 6, tr("Export") + " %s" % (file_name + file_format_string(file_format)) + ) # Only show when not exporting gif - gif export finishes in thread if not (current_tab == ExportTab.ANIMATION and animation_type == AnimationType.ANIMATED): @@ -206,29 +232,54 @@ func export_processed_images(ignore_overwrites: bool, export_dialog: AcceptDialo func export_gif(args: Dictionary) -> void: # Export progress popup - export_progress_fraction = 100 / processed_images.size() # one fraction per each frame, one fraction for write to disk + # One fraction per each frame, one fraction for write to disk + export_progress_fraction = 100 / processed_images.size() export_progress = 0.0 args["export_dialog"].set_export_progress_bar(export_progress) args["export_dialog"].toggle_export_progress_popup(true) # Export and save gif - var exporter = GIFExporter.new(processed_images[0].get_width(), processed_images[0].get_height()) + var exporter = GIFExporter.new( + processed_images[0].get_width(), processed_images[0].get_height() + ) match direction: AnimationDirection.FORWARD: for i in range(processed_images.size()): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) + write_frame_to_gif( + processed_images[i], + Global.current_project.frames[i].duration * (1 / Global.current_project.fps), + exporter, + args["export_dialog"] + ) AnimationDirection.BACKWARDS: for i in range(processed_images.size() - 1, -1, -1): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) + write_frame_to_gif( + processed_images[i], + Global.current_project.frames[i].duration * (1 / Global.current_project.fps), + exporter, + args["export_dialog"] + ) AnimationDirection.PING_PONG: export_progress_fraction = 100 / (processed_images.size() * 2) for i in range(0, processed_images.size()): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) + write_frame_to_gif( + processed_images[i], + Global.current_project.frames[i].duration * (1 / Global.current_project.fps), + exporter, + args["export_dialog"] + ) for i in range(processed_images.size() - 2, 0, -1): - write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"]) + write_frame_to_gif( + processed_images[i], + Global.current_project.frames[i].duration * (1 / Global.current_project.fps), + exporter, + args["export_dialog"] + ) if OS.get_name() == "HTML5": - JavaScript.download_buffer(exporter.export_file_data(), args["export_paths"][0], "image/gif") + JavaScript.download_buffer( + exporter.export_file_data(), args["export_paths"][0], "image/gif" + ) else: var file: File = File.new() @@ -239,9 +290,9 @@ func export_gif(args: Dictionary) -> void: Global.notification_label("File(s) exported") -func write_frame_to_gif(image: Image, wait_time: float, exporter: Reference, export_dialog: Node) -> void: +func write_frame_to_gif(image: Image, wait_time: float, exporter: Reference, dialog: Node) -> void: exporter.add_frame(image, wait_time, MedianCutQuantization) - increase_export_progress(export_dialog) + increase_export_progress(dialog) func increase_export_progress(export_dialog: Node) -> void: @@ -253,17 +304,21 @@ func scale_processed_images() -> void: for processed_image in processed_images: if resize != 100: processed_image.unlock() - processed_image.resize(processed_image.get_size().x * resize / 100, processed_image.get_size().y * resize / 100, interpolation) + processed_image.resize( + processed_image.get_size().x * resize / 100, + processed_image.get_size().y * resize / 100, + interpolation + ) -func file_format_string(format_enum : int) -> String: +func file_format_string(format_enum: int) -> String: match format_enum: - 0: # PNG - return '.png' - 1: # GIF - return '.gif' + 0: # PNG + return ".png" + 1: # GIF + return ".gif" _: - return '' + return "" func create_export_path(multifile: bool, frame: int = 0) -> String: @@ -283,7 +338,9 @@ func create_export_path(multifile: bool, frame: int = 0) -> String: # Add frame tag if frame has one # (frame - start_id + 1) Makes frames id to start from 1 in each frame tag directory path += "_" + frame_tag_dir + "_" + String(frame - start_id + 1) - return directory_path.plus_file(frame_tag_dir).plus_file(path + file_format_string(file_format)) + return directory_path.plus_file(frame_tag_dir).plus_file( + path + file_format_string(file_format) + ) else: # Add frame tag if frame has one # (frame - start_id + 1) Makes frames id to start from 1 in each frame tag @@ -294,19 +351,22 @@ func create_export_path(multifile: bool, frame: int = 0) -> String: return directory_path.plus_file(path + file_format_string(file_format)) -func get_proccessed_image_animation_tag_and_start_id(processed_image_id : int) -> Array: +func get_proccessed_image_animation_tag_and_start_id(processed_image_id: int) -> Array: var result_animation_tag_and_start_id = null for animation_tag in Global.current_project.animation_tags: # Check if processed image is in frame tag and assign frame tag and start id if yes # Then stop - if (processed_image_id + 1) >= animation_tag.from and (processed_image_id + 1) <= animation_tag.to: + if ( + (processed_image_id + 1) >= animation_tag.from + and (processed_image_id + 1) <= animation_tag.to + ): result_animation_tag_and_start_id = [animation_tag.name, animation_tag.from] break return result_animation_tag_and_start_id # Blends canvas layers into passed image starting from the origin position -func blend_layers(image : Image, frame : Frame, origin : Vector2 = Vector2(0, 0)) -> void: +func blend_layers(image: Image, frame: Frame, origin: Vector2 = Vector2(0, 0)) -> void: image.lock() var layer_i := 0 for cel in frame.cels: @@ -314,12 +374,14 @@ func blend_layers(image : Image, frame : Frame, origin : Vector2 = Vector2(0, 0) var cel_image := Image.new() cel_image.copy_from(cel.image) cel_image.lock() - if cel.opacity < 1: # If we have cel transparency + if cel.opacity < 1: # If we have cel transparency for xx in cel_image.get_size().x: for yy in cel_image.get_size().y: var pixel_color := cel_image.get_pixel(xx, yy) - var alpha : float = pixel_color.a * cel.opacity - cel_image.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha)) + var alpha: float = pixel_color.a * cel.opacity + cel_image.set_pixel( + xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha) + ) image.blend_rect(cel_image, Rect2(Vector2.ZERO, Global.current_project.size), origin) cel_image.unlock() layer_i += 1 diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index a672f2328..e9cf2edaa 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -1,25 +1,25 @@ extends Node - -enum GridTypes {CARTESIAN, ISOMETRIC, ALL} -enum PressureSensitivity {NONE, ALPHA, SIZE, ALPHA_AND_SIZE} -enum ThemeTypes {DARK, BLUE, CARAMEL, LIGHT} -enum TileMode {NONE, BOTH, X_AXIS, Y_AXIS} -enum PanelLayout {AUTO, WIDESCREEN, TALLSCREEN} -enum IconColorFrom {THEME, CUSTOM} -enum ButtonSize {SMALL, BIG} +enum GridTypes { CARTESIAN, ISOMETRIC, ALL } +enum PressureSensitivity { NONE, ALPHA, SIZE, ALPHA_AND_SIZE } +enum ThemeTypes { DARK, BLUE, CARAMEL, LIGHT } +enum TileMode { NONE, BOTH, X_AXIS, Y_AXIS } +enum PanelLayout { AUTO, WIDESCREEN, TALLSCREEN } +enum IconColorFrom { THEME, CUSTOM } +enum ButtonSize { SMALL, BIG } var root_directory := "." -var window_title := "" setget title_changed # Why doesn't Godot have get_window_title()? +var window_title := "" setget title_changed # Why doesn't Godot have get_window_title()? var config_cache := ConfigFile.new() var XDGDataPaths = preload("res://src/XDGDataPaths.gd") -var directory_module : Reference +var directory_module: Reference -var projects := [] # Array of Projects -var current_project : Project +var projects := [] # Array of Projects +var current_project: Project var current_project_index := 0 setget project_changed var panel_layout = PanelLayout.AUTO +var ui_tooltips := {} # Canvas related stuff var layers_changed_skip := false @@ -38,11 +38,11 @@ var smooth_zoom := true var shrink := 1.0 var dim_on_popup := true -var theme_type : int = ThemeTypes.DARK +var theme_type: int = ThemeTypes.DARK var modulate_icon_color := Color.gray -var icon_color_from : int = IconColorFrom.THEME +var icon_color_from: int = IconColorFrom.THEME var custom_icon_color := Color.gray -var tool_button_size : int = ButtonSize.SMALL +var tool_button_size: int = ButtonSize.SMALL var default_image_width := 64 var default_image_height := 64 @@ -56,7 +56,7 @@ var grid_offset_x := 0 var grid_offset_y := 0 var grid_draw_over_tile_mode := false var grid_color := Color.black -var pixel_grid_show_at_zoom := 1500.0 # percentage +var pixel_grid_show_at_zoom := 1500.0 # percentage var pixel_grid_color := Color("91212121") var guide_color := Color.purple var checker_size := 10 @@ -103,67 +103,69 @@ var palettes := {} # Nodes var notification_label_node = preload("res://src/UI/NotificationLabel.tscn") -onready var root : Node = get_tree().get_root() -onready var control : Node = root.get_node("Control") +onready var root: Node = get_tree().get_root() +onready var control: Node = root.get_node("Control") -onready var left_cursor : Sprite = control.find_node("LeftCursor") -onready var right_cursor : Sprite = control.find_node("RightCursor") -onready var canvas : Canvas = control.find_node("Canvas") -onready var tabs : Tabs = control.find_node("Tabs") -onready var main_viewport : ViewportContainer = control.find_node("ViewportContainer") -onready var second_viewport : ViewportContainer = control.find_node("ViewportContainer2") -onready var canvas_preview_container : Container = control.find_node("CanvasPreviewContainer") -onready var small_preview_viewport : ViewportContainer = canvas_preview_container.find_node("PreviewViewportContainer") -onready var camera : Camera2D = main_viewport.find_node("Camera2D") -onready var camera2 : Camera2D = control.find_node("Camera2D2") -onready var camera_preview : Camera2D = control.find_node("CameraPreview") +onready var left_cursor: Sprite = control.find_node("LeftCursor") +onready var right_cursor: Sprite = control.find_node("RightCursor") +onready var canvas: Canvas = control.find_node("Canvas") +onready var tabs: Tabs = control.find_node("Tabs") +onready var main_viewport: ViewportContainer = control.find_node("ViewportContainer") +onready var second_viewport: ViewportContainer = control.find_node("ViewportContainer2") +onready var canvas_preview_container: Container = control.find_node("CanvasPreviewContainer") +onready var small_preview_viewport: ViewportContainer = canvas_preview_container.find_node( + "PreviewViewportContainer" +) +onready var camera: Camera2D = main_viewport.find_node("Camera2D") +onready var camera2: Camera2D = control.find_node("Camera2D2") +onready var camera_preview: Camera2D = control.find_node("CameraPreview") onready var cameras = [Global.camera, Global.camera2, Global.camera_preview] -onready var horizontal_ruler : BaseButton = control.find_node("HorizontalRuler") -onready var vertical_ruler : BaseButton = control.find_node("VerticalRuler") -onready var transparent_checker : ColorRect = control.find_node("TransparentChecker") -onready var preview_zoom_slider : VSlider = control.find_node("PreviewZoomSlider") +onready var horizontal_ruler: BaseButton = control.find_node("HorizontalRuler") +onready var vertical_ruler: BaseButton = control.find_node("VerticalRuler") +onready var transparent_checker: ColorRect = control.find_node("TransparentChecker") +onready var preview_zoom_slider: VSlider = control.find_node("PreviewZoomSlider") -onready var tool_panel : Panel = control.find_node("ToolPanel") -onready var right_panel : Panel = control.find_node("RightPanel") -onready var brushes_popup : Popup = control.find_node("BrushesPopup") -onready var patterns_popup : Popup = control.find_node("PatternsPopup") -onready var palette_panel : PalettePanel = control.find_node("PalettePanel") +onready var tool_panel: Panel = control.find_node("ToolPanel") +onready var right_panel: Panel = control.find_node("RightPanel") +onready var brushes_popup: Popup = control.find_node("BrushesPopup") +onready var patterns_popup: Popup = control.find_node("PatternsPopup") +onready var palette_panel: PalettePanel = control.find_node("PalettePanel") -onready var top_menu_container : Panel = control.find_node("TopMenuContainer") -onready var rotation_level_button : Button = control.find_node("RotationLevel") -onready var rotation_level_spinbox : SpinBox = control.find_node("RotationSpinbox") -onready var zoom_level_button : Button = control.find_node("ZoomLevel") -onready var zoom_level_spinbox : SpinBox = control.find_node("ZoomSpinbox") -onready var cursor_position_label : Label = control.find_node("CursorPosition") -onready var current_frame_mark_label : Label = control.find_node("CurrentFrameMark") +onready var top_menu_container: Panel = control.find_node("TopMenuContainer") +onready var rotation_level_button: Button = control.find_node("RotationLevel") +onready var rotation_level_spinbox: SpinBox = control.find_node("RotationSpinbox") +onready var zoom_level_button: Button = control.find_node("ZoomLevel") +onready var zoom_level_spinbox: SpinBox = control.find_node("ZoomSpinbox") +onready var cursor_position_label: Label = control.find_node("CursorPosition") +onready var current_frame_mark_label: Label = control.find_node("CurrentFrameMark") -onready var animation_timeline : Panel = control.find_node("AnimationTimeline") -onready var animation_timer : Timer = animation_timeline.find_node("AnimationTimer") -onready var frame_ids : HBoxContainer = animation_timeline.find_node("FrameIDs") -onready var play_forward : BaseButton = animation_timeline.find_node("PlayForward") -onready var play_backwards : BaseButton = animation_timeline.find_node("PlayBackwards") -onready var layers_container : VBoxContainer = animation_timeline.find_node("LayersContainer") -onready var frames_container : VBoxContainer = animation_timeline.find_node("FramesContainer") -onready var tag_container : Control = animation_timeline.find_node("TagContainer") -onready var remove_frame_button : BaseButton = animation_timeline.find_node("DeleteFrame") -onready var move_left_frame_button : BaseButton = animation_timeline.find_node("MoveLeft") -onready var move_right_frame_button : BaseButton = animation_timeline.find_node("MoveRight") -onready var remove_layer_button : BaseButton = animation_timeline.find_node("RemoveLayer") -onready var move_up_layer_button : BaseButton = animation_timeline.find_node("MoveUpLayer") -onready var move_down_layer_button : BaseButton = animation_timeline.find_node("MoveDownLayer") -onready var merge_down_layer_button : BaseButton = animation_timeline.find_node("MergeDownLayer") -onready var layer_opacity_slider : HSlider = animation_timeline.find_node("OpacitySlider") -onready var layer_opacity_spinbox : SpinBox = animation_timeline.find_node("OpacitySpinBox") +onready var animation_timeline: Panel = control.find_node("AnimationTimeline") +onready var animation_timer: Timer = animation_timeline.find_node("AnimationTimer") +onready var frame_ids: HBoxContainer = animation_timeline.find_node("FrameIDs") +onready var play_forward: BaseButton = animation_timeline.find_node("PlayForward") +onready var play_backwards: BaseButton = animation_timeline.find_node("PlayBackwards") +onready var layers_container: VBoxContainer = animation_timeline.find_node("LayersContainer") +onready var frames_container: VBoxContainer = animation_timeline.find_node("FramesContainer") +onready var tag_container: Control = animation_timeline.find_node("TagContainer") +onready var remove_frame_button: BaseButton = animation_timeline.find_node("DeleteFrame") +onready var move_left_frame_button: BaseButton = animation_timeline.find_node("MoveLeft") +onready var move_right_frame_button: BaseButton = animation_timeline.find_node("MoveRight") +onready var remove_layer_button: BaseButton = animation_timeline.find_node("RemoveLayer") +onready var move_up_layer_button: BaseButton = animation_timeline.find_node("MoveUpLayer") +onready var move_down_layer_button: BaseButton = animation_timeline.find_node("MoveDownLayer") +onready var merge_down_layer_button: BaseButton = animation_timeline.find_node("MergeDownLayer") +onready var layer_opacity_slider: HSlider = animation_timeline.find_node("OpacitySlider") +onready var layer_opacity_spinbox: SpinBox = animation_timeline.find_node("OpacitySpinBox") -onready var open_sprites_dialog : FileDialog = control.find_node("OpenSprite") -onready var save_sprites_dialog : FileDialog = control.find_node("SaveSprite") -onready var save_sprites_html5_dialog : ConfirmationDialog = control.find_node("SaveSpriteHTML5") -onready var export_dialog : AcceptDialog = control.find_node("ExportDialog") -onready var preferences_dialog : AcceptDialog = control.find_node("PreferencesDialog") -onready var error_dialog : AcceptDialog = control.find_node("ErrorDialog") -onready var quit_and_save_dialog : ConfirmationDialog = control.find_node("QuitAndSaveDialog") +onready var open_sprites_dialog: FileDialog = control.find_node("OpenSprite") +onready var save_sprites_dialog: FileDialog = control.find_node("SaveSprite") +onready var save_sprites_html5_dialog: ConfirmationDialog = control.find_node("SaveSpriteHTML5") +onready var export_dialog: AcceptDialog = control.find_node("ExportDialog") +onready var preferences_dialog: AcceptDialog = control.find_node("PreferencesDialog") +onready var error_dialog: AcceptDialog = control.find_node("ErrorDialog") +onready var quit_and_save_dialog: ConfirmationDialog = control.find_node("QuitAndSaveDialog") -onready var current_version : String = ProjectSettings.get_setting("application/config/Version") +onready var current_version: String = ProjectSettings.get_setting("application/config/Version") func _ready() -> void: @@ -180,34 +182,48 @@ func _ready() -> void: projects.append(Project.new()) projects[0].layers.append(Layer.new()) current_project = projects[0] + for node in get_tree().get_nodes_in_group("UIButtons"): + var tooltip: String = node.hint_tooltip + if !tooltip.empty() and node.shortcut: + ui_tooltips[node] = tooltip -func notification_label(text : String) -> void: - var notification : Label = notification_label_node.instance() +func notification_label(text: String) -> void: + var notification: Label = notification_label_node.instance() notification.text = tr(text) notification.rect_position = Vector2(70, animation_timeline.rect_position.y) notification.theme = control.theme get_tree().get_root().add_child(notification) -func general_undo(project : Project = current_project) -> void: +func general_undo(project: Project = current_project) -> void: project.undos -= 1 - var action_name : String = project.undo_redo.get_current_action_name() + var action_name: String = project.undo_redo.get_current_action_name() notification_label("Undo: %s" % action_name) -func general_redo(project : Project = current_project) -> void: - if project.undos < project.undo_redo.get_version(): # If we did undo and then redo +func general_redo(project: Project = current_project) -> void: + if project.undos < project.undo_redo.get_version(): # If we did undo and then redo project.undos = project.undo_redo.get_version() if control.redone: - var action_name : String = project.undo_redo.get_current_action_name() + var action_name: String = project.undo_redo.get_current_action_name() notification_label("Redo: %s" % action_name) -func undo(_frame_index := -1, _layer_index := -1, project : Project = current_project) -> void: +func undo(_frame_index := -1, _layer_index := -1, project: Project = current_project) -> void: general_undo(project) - var action_name : String = project.undo_redo.get_current_action_name() - if action_name == "Draw" or action_name == "Draw Shape" or action_name == "Rectangle Select" or action_name == "Move Selection" or action_name == "Scale" or action_name == "Centralize" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel": + var action_name: String = project.undo_redo.get_current_action_name() + if ( + action_name == "Draw" + or action_name == "Draw Shape" + or action_name == "Rectangle Select" + or action_name == "Move Selection" + or action_name == "Scale" + or action_name == "Centralize" + or action_name == "Merge Layer" + or action_name == "Link Cel" + or action_name == "Unlink Cel" + ): if _layer_index > -1 and _frame_index > -1: canvas.update_texture(_layer_index, _frame_index, project) else: @@ -224,13 +240,13 @@ func undo(_frame_index := -1, _layer_index := -1, project : Project = current_pr elif "Frame" in action_name: # This actually means that frames.size is one, but it hasn't been updated yet - if project.frames.size() == 2: # Stop animating + if project.frames.size() == 2: # Stop animating play_forward.pressed = false play_backwards.pressed = false animation_timer.stop() elif "Move Cels" == action_name: - project.frames = project.frames # to call frames_changed + project.frames = project.frames # to call frames_changed canvas.update() if !project.has_changed: @@ -239,10 +255,20 @@ func undo(_frame_index := -1, _layer_index := -1, project : Project = current_pr self.window_title = window_title + "(*)" -func redo(_frame_index := -1, _layer_index := -1, project : Project = current_project) -> void: +func redo(_frame_index := -1, _layer_index := -1, project: Project = current_project) -> void: general_redo(project) - var action_name : String = project.undo_redo.get_current_action_name() - if action_name == "Draw" or action_name == "Draw Shape" or action_name == "Rectangle Select" or action_name == "Move Selection" or action_name == "Scale" or action_name == "Centralize" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel": + var action_name: String = project.undo_redo.get_current_action_name() + if ( + action_name == "Draw" + or action_name == "Draw Shape" + or action_name == "Rectangle Select" + or action_name == "Move Selection" + or action_name == "Scale" + or action_name == "Centralize" + or action_name == "Merge Layer" + or action_name == "Link Cel" + or action_name == "Unlink Cel" + ): if _layer_index > -1 and _frame_index > -1: canvas.update_texture(_layer_index, _frame_index, project) else: @@ -258,13 +284,13 @@ func redo(_frame_index := -1, _layer_index := -1, project : Project = current_pr cursor_position_label.text = "[%s×%s]" % [project.size.x, project.size.y] elif "Frame" in action_name: - if project.frames.size() == 1: # Stop animating + if project.frames.size() == 1: # Stop animating play_forward.pressed = false play_backwards.pressed = false animation_timer.stop() elif "Move Cels" == action_name: - project.frames = project.frames # to call frames_changed + project.frames = project.frames # to call frames_changed canvas.update() if !project.has_changed: @@ -273,31 +299,47 @@ func redo(_frame_index := -1, _layer_index := -1, project : Project = current_pr self.window_title = window_title + "(*)" -func title_changed(value : String) -> void: +func title_changed(value: String) -> void: window_title = value OS.set_window_title(value) -func project_changed(value : int) -> void: +func project_changed(value: int) -> void: canvas.selection.transform_content_confirm() current_project_index = value current_project = projects[value] current_project.change_project() -func dialog_open(open : bool) -> void: +func dialog_open(open: bool) -> void: if open: can_draw = false if dim_on_popup: - control.get_node("ModulateTween").interpolate_property(control, "modulate", control.modulate, Color(0.5, 0.5, 0.5), 0.1, Tween.TRANS_LINEAR, Tween.EASE_OUT) + control.get_node("ModulateTween").interpolate_property( + control, + "modulate", + control.modulate, + Color(0.5, 0.5, 0.5), + 0.1, + Tween.TRANS_LINEAR, + Tween.EASE_OUT + ) else: can_draw = true - control.get_node("ModulateTween").interpolate_property(control, "modulate", control.modulate, Color.white, 0.1, Tween.TRANS_LINEAR, Tween.EASE_OUT) + control.get_node("ModulateTween").interpolate_property( + control, + "modulate", + control.modulate, + Color.white, + 0.1, + Tween.TRANS_LINEAR, + Tween.EASE_OUT + ) control.get_node("ModulateTween").start() -func disable_button(button : BaseButton, disable : bool) -> void: +func disable_button(button: BaseButton, disable: bool) -> void: button.disabled = disable if disable: button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN @@ -314,167 +356,19 @@ func disable_button(button : BaseButton, disable : bool) -> void: break -func change_button_texturerect(texture_button : TextureRect, new_file_name : String) -> void: +func change_button_texturerect(texture_button: TextureRect, new_file_name: String) -> void: var file_name := texture_button.texture.resource_path.get_basename().get_file() var directory_path := texture_button.texture.resource_path.get_basename().replace(file_name, "") texture_button.texture = load(directory_path.plus_file(new_file_name)) func update_hint_tooltips() -> void: - var tool_buttons = control.find_node("ToolButtons") + var tool_buttons: Container = control.find_node("ToolButtons") + tool_buttons.update_hintooltips() - var rect_select : BaseButton = tool_buttons.find_node("RectSelect") - rect_select.hint_tooltip = tr("""Rectangular Selection - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_rectangle_select_tool")[0].as_text(), InputMap.get_action_list("right_rectangle_select_tool")[0].as_text()] - - var ellipse_select : BaseButton = tool_buttons.find_node("EllipseSelect") - ellipse_select.hint_tooltip = tr("""Elliptical Selection - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_ellipse_select_tool")[0].as_text(), InputMap.get_action_list("right_ellipse_select_tool")[0].as_text()] + for tip in ui_tooltips: + tip.hint_tooltip = tr(ui_tooltips[tip]) % tip.shortcut.get_as_text() - var polygon_select : BaseButton = tool_buttons.find_node("PolygonSelect") - polygon_select.hint_tooltip = tr("""Polygonal Selection -Double-click to connect the last point to the starting point - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_polygon_select_tool")[0].as_text(), InputMap.get_action_list("right_polygon_select_tool")[0].as_text()] - - - var color_select : BaseButton = tool_buttons.find_node("ColorSelect") - color_select.hint_tooltip = tr("""Select By Color - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_color_select_tool")[0].as_text(), InputMap.get_action_list("right_color_select_tool")[0].as_text()] - - - var magic_wand : BaseButton = tool_buttons.find_node("MagicWand") - magic_wand.hint_tooltip = tr("""Magic Wand - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_magic_wand_tool")[0].as_text(), InputMap.get_action_list("right_magic_wand_tool")[0].as_text()] - - - var lasso : BaseButton = tool_buttons.find_node("Lasso") - lasso.hint_tooltip = tr("""Lasso / Free Select Tool - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_lasso_tool")[0].as_text(), InputMap.get_action_list("right_lasso_tool")[0].as_text()] - - - var move_select : BaseButton = tool_buttons.find_node("Move") - move_select.hint_tooltip = tr("""Move - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_move_tool")[0].as_text(), InputMap.get_action_list("right_move_tool")[0].as_text()] - - - var zoom_tool : BaseButton = tool_buttons.find_node("Zoom") - zoom_tool.hint_tooltip = tr("""Zoom - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_zoom_tool")[0].as_text(), InputMap.get_action_list("right_zoom_tool")[0].as_text()] - - var pan_tool : BaseButton = tool_buttons.find_node("Pan") - pan_tool.hint_tooltip = tr("""Pan - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_pan_tool")[0].as_text(), InputMap.get_action_list("right_pan_tool")[0].as_text()] - - var color_picker : BaseButton = tool_buttons.find_node("ColorPicker") - color_picker.hint_tooltip = tr("""Color Picker -Select a color from a pixel of the sprite - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_colorpicker_tool")[0].as_text(), InputMap.get_action_list("right_colorpicker_tool")[0].as_text()] - - var pencil : BaseButton = tool_buttons.find_node("Pencil") - pencil.hint_tooltip = tr("""Pencil - -%s for left mouse button -%s for right mouse button - -Hold %s to make a line""") % [InputMap.get_action_list("left_pencil_tool")[0].as_text(), InputMap.get_action_list("right_pencil_tool")[0].as_text(), "Shift"] - - var eraser : BaseButton = tool_buttons.find_node("Eraser") - eraser.hint_tooltip = tr("""Eraser - -%s for left mouse button -%s for right mouse button - -Hold %s to make a line""") % [InputMap.get_action_list("left_eraser_tool")[0].as_text(), InputMap.get_action_list("right_eraser_tool")[0].as_text(), "Shift"] - - var bucket : BaseButton = tool_buttons.find_node("Bucket") - bucket.hint_tooltip = tr("""Bucket - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_fill_tool")[0].as_text(), InputMap.get_action_list("right_fill_tool")[0].as_text()] - - var ld : BaseButton = tool_buttons.find_node("Shading") - ld.hint_tooltip = tr("""Shading Tool - -%s for left mouse button -%s for right mouse button""") % [InputMap.get_action_list("left_shading_tool")[0].as_text(), InputMap.get_action_list("right_shading_tool")[0].as_text()] - - var linetool : BaseButton = tool_buttons.find_node("LineTool") - linetool.hint_tooltip = tr("""Line Tool - -%s for left mouse button -%s for right mouse button - -Hold %s to snap the angle of the line -Hold %s to center the shape on the click origin -Hold %s to displace the shape's origin""") % [InputMap.get_action_list("left_linetool_tool")[0].as_text(), InputMap.get_action_list("right_linetool_tool")[0].as_text(), "Shift", "Ctrl", "Alt"] - - var recttool : BaseButton = tool_buttons.find_node("RectangleTool") - recttool.hint_tooltip = tr("""Rectangle Tool - -%s for left mouse button -%s for right mouse button - -Hold %s to create a 1:1 shape -Hold %s to center the shape on the click origin -Hold %s to displace the shape's origin""") % [InputMap.get_action_list("left_rectangletool_tool")[0].as_text(), InputMap.get_action_list("right_rectangletool_tool")[0].as_text(), "Shift", "Ctrl", "Alt"] - - var ellipsetool : BaseButton = tool_buttons.find_node("EllipseTool") - ellipsetool.hint_tooltip = tr("""Ellipse Tool - -%s for left mouse button -%s for right mouse button - -Hold %s to create a 1:1 shape -Hold %s to center the shape on the click origin -Hold %s to displace the shape's origin""") % [InputMap.get_action_list("left_ellipsetool_tool")[0].as_text(), InputMap.get_action_list("right_ellipsetool_tool")[0].as_text(), "Shift", "Ctrl", "Alt"] - - var color_switch : BaseButton = control.find_node("ColorSwitch") - color_switch.hint_tooltip = tr("""Switch left and right colors -(%s)""") % InputMap.get_action_list("switch_colors")[0].as_text() - - var first_frame : BaseButton = control.find_node("FirstFrame") - first_frame.hint_tooltip = tr("""Jump to the first frame -(%s)""") % InputMap.get_action_list("go_to_first_frame")[0].as_text() - - var previous_frame : BaseButton = control.find_node("PreviousFrame") - previous_frame.hint_tooltip = tr("""Go to the previous frame -(%s)""") % InputMap.get_action_list("go_to_previous_frame")[0].as_text() - - play_backwards.hint_tooltip = tr("""Play the animation backwards (from end to beginning) -(%s)""") % InputMap.get_action_list("play_backwards")[0].as_text() - - play_forward.hint_tooltip = tr("""Play the animation forward (from beginning to end) -(%s)""") % InputMap.get_action_list("play_forward")[0].as_text() - - var next_frame : BaseButton = control.find_node("NextFrame") - next_frame.hint_tooltip = tr("""Go to the next frame -(%s)""") % InputMap.get_action_list("go_to_next_frame")[0].as_text() - - var last_frame : BaseButton = control.find_node("LastFrame") - last_frame.hint_tooltip = tr("""Jump to the last frame -(%s)""") % InputMap.get_action_list("go_to_last_frame")[0].as_text() - - -func is_cjk(locale : String) -> bool: +func is_cjk(locale: String) -> bool: return "zh" in locale or "ko" in locale or "ja" in locale diff --git a/src/Autoload/HTML5FileExchange.gd b/src/Autoload/HTML5FileExchange.gd index 332248b1a..1b78f6a95 100644 --- a/src/Autoload/HTML5FileExchange.gd +++ b/src/Autoload/HTML5FileExchange.gd @@ -2,22 +2,23 @@ extends Node # Code taken and modified from https://github.com/Pukkah/HTML5-File-Exchange-for-Godot # Thanks to Pukkah from GitHub for providing the original code -signal InFocus +signal in_focus func _ready() -> void: - if OS.get_name() == "HTML5" and OS.has_feature('JavaScript'): + if OS.get_name() == "HTML5" and OS.has_feature("JavaScript"): _define_js() -func _notification(notification:int) -> void: +func _notification(notification: int) -> void: if notification == MainLoop.NOTIFICATION_WM_FOCUS_IN: - emit_signal("InFocus") + emit_signal("in_focus") func _define_js() -> void: # Define JS script - JavaScript.eval(""" + JavaScript.eval( + """ var fileData; var fileType; var fileName; @@ -41,7 +42,7 @@ func _define_js() -> void: fileData = evt.target.result; } } - }); + }); } function upload_palette() { canceled = true; @@ -67,7 +68,7 @@ func _define_js() -> void: fileData = evt.target.result; } } - }); + }); } function upload_shader() { canceled = true; @@ -88,23 +89,25 @@ func _define_js() -> void: fileData = evt.target.result; } } - }); + }); } - """, true) + """, + true + ) func load_image() -> void: - if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'): + if OS.get_name() != "HTML5" or !OS.has_feature("JavaScript"): return # Execute JS function - JavaScript.eval("upload_image();", true) # Opens prompt for choosing file + JavaScript.eval("upload_image();", true) # Opens prompt for choosing file - yield(self, "InFocus") # Wait until JS prompt is closed + yield(self, "in_focus") # Wait until JS prompt is closed - yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load + yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load - if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file + if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file return # Use data from png data @@ -113,7 +116,7 @@ func load_image() -> void: image_data = JavaScript.eval("fileData;", true) if image_data != null: break - yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data + yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data var image_type = JavaScript.eval("fileType;", true) var image_name = JavaScript.eval("fileName;", true) @@ -138,17 +141,17 @@ func load_image() -> void: func load_palette() -> void: - if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'): + if OS.get_name() != "HTML5" or !OS.has_feature("JavaScript"): return # Execute JS function - JavaScript.eval("upload_palette();", true) # Opens prompt for choosing file + JavaScript.eval("upload_palette();", true) # Opens prompt for choosing file - yield(self, "InFocus") # Wait until JS prompt is closed + yield(self, "in_focus") # Wait until JS prompt is closed - yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load + yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load - if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file + if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file return # Use data from palette file data @@ -157,7 +160,7 @@ func load_palette() -> void: palette_data = JavaScript.eval("fileData;", true) if palette_data != null: break - yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data + yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data var file_type = JavaScript.eval("fileType;", true) var file_name = JavaScript.eval("fileName;", true) @@ -177,7 +180,7 @@ func load_palette() -> void: if !err: Global.palette_container.import_image_palette(file_name, image) "application/json": - var palette : Palette = Palette.new().deserialize(palette_data) + var palette: Palette = Palette.new().deserialize(palette_data) palette.source_path = file_name Global.palette_container.attempt_to_import_palette(palette) var invalid_type: @@ -186,17 +189,17 @@ func load_palette() -> void: func load_shader() -> void: - if OS.get_name() != "HTML5" or !OS.has_feature('JavaScript'): + if OS.get_name() != "HTML5" or !OS.has_feature("JavaScript"): return # Execute JS function - JavaScript.eval("upload_shader();", true) # Opens prompt for choosing file + JavaScript.eval("upload_shader();", true) # Opens prompt for choosing file - yield(self, "InFocus") # Wait until JS prompt is closed + yield(self, "in_focus") # Wait until JS prompt is closed - yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load + yield(get_tree().create_timer(0.5), "timeout") # Give some time for async JS data load - if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file + if JavaScript.eval("canceled;", true): # If File Dialog closed w/o file return # Use data from png data @@ -205,7 +208,7 @@ func load_shader() -> void: file_data = JavaScript.eval("fileData;", true) if file_data != null: break - yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data + yield(get_tree().create_timer(1.0), "timeout") # Need more time to load data # var file_type = JavaScript.eval("fileType;", true) var file_name = JavaScript.eval("fileName;", true) @@ -215,4 +218,3 @@ func load_shader() -> void: var shader_effect_dialog = Global.control.get_node("Dialogs/ImageEffects/ShaderEffect") shader_effect_dialog.change_shader(shader, file_name.get_basename()) - diff --git a/src/Autoload/Import.gd b/src/Autoload/Import.gd index 80b17e9c3..e8d5225df 100644 --- a/src/Autoload/Import.gd +++ b/src/Autoload/Import.gd @@ -21,14 +21,14 @@ extends Node # # Returns null if the directory gave an error opening. # -func get_brush_files_from_directory(directory: String): # -> Array +func get_brush_files_from_directory(directory: String): # -> Array var base_png_files := [] # list of files in the base directory var subdirectories := [] # list of subdirectories to process. - var randomised_subdir_files_map : Dictionary = {} - var nonrandomised_subdir_files_map : Dictionary = {} + var randomised_subdir_files_map: Dictionary = {} + var nonrandomised_subdir_files_map: Dictionary = {} - var main_directory : Directory = Directory.new() + var main_directory: Directory = Directory.new() var err := main_directory.open(directory) if err != OK: return null @@ -36,11 +36,11 @@ func get_brush_files_from_directory(directory: String): # -> Array # Build first the list of base png files and all subdirectories to # scan later (skip navigational . and ..) main_directory.list_dir_begin(true) - var fname : String = main_directory.get_next() + var fname: String = main_directory.get_next() while fname != "": if main_directory.current_is_dir(): subdirectories.append(fname) - else: # Filter for pngs + else: # Filter for pngs if fname.get_extension().to_lower() == "png": base_png_files.append(fname) @@ -50,7 +50,7 @@ func get_brush_files_from_directory(directory: String): # -> Array # Now we iterate over subdirectories! for subdirectory in subdirectories: - var the_directory : Directory = Directory.new() + var the_directory: Directory = Directory.new() # Holds names of files that make this # a component of a randomised brush ^.^ @@ -89,9 +89,9 @@ func get_brush_files_from_directory(directory: String): # -> Array # The tooltip name is what shows up on the tooltip # and is probably in this case the name of the containing # randomised directory. -func add_randomised_brush(fpaths : Array, tooltip_name : String) -> void: +func add_randomised_brush(fpaths: Array, tooltip_name: String) -> void: # Attempt to load the images from the file paths. - var loaded_images : Array = [] + var loaded_images: Array = [] for filen in fpaths: var image := Image.new() var err := image.load(filen) @@ -107,6 +107,7 @@ func add_randomised_brush(fpaths : Array, tooltip_name : String) -> void: # to use. Brushes.add_file_brush(loaded_images, tooltip_name) + # Add a plain brush from the given path to the list of brushes. # Taken, again, from find_brushes func add_plain_brush(path: String, tooltip_name: String) -> void: @@ -127,14 +128,14 @@ func add_plain_brush(path: String, tooltip_name: String) -> void: # is on a file-by-file basis nyaaaa ^.^ func import_brushes(priority_ordered_search_path: Array) -> void: # Maps for files in the base directory (name : true) - var processed_basedir_paths : Dictionary = {} - var randomised_brush_subdirectories : Dictionary = {} + var processed_basedir_paths: Dictionary = {} + var randomised_brush_subdirectories: Dictionary = {} # Map from a subdirectory to a map similar to processed_basedir_files # i.e. once a filename has been dealt with, set it to true. - var processed_subdir_paths : Dictionary = {} + var processed_subdir_paths: Dictionary = {} # Sets of results of get_brush_files_from_directory - var all_available_paths : Array = [] + var all_available_paths: Array = [] for directory in priority_ordered_search_path: all_available_paths.append(get_brush_files_from_directory(directory)) @@ -145,20 +146,19 @@ func import_brushes(priority_ordered_search_path: Array) -> void: var current_main_directory: String = priority_ordered_search_path[i] if available_brush_file_information != null: # The brush files in the main directory - var main_directory_file_paths : Array = available_brush_file_information[0] + var main_directory_file_paths: Array = available_brush_file_information[0] # The subdirectory/list-of-randomised-brush-files # map for this directory - var randomised_brush_subdirectory_map : Dictionary = available_brush_file_information[1] + var randomised_brush_subdirectory_map: Dictionary = available_brush_file_information[1] # Map for subdirectories to non-randomised-brush files nyaa - var nonrandomised_brush_subdirectory_map : Dictionary = available_brush_file_information[2] + var nonrandomised_brush_subdir_map: Dictionary = available_brush_file_information[2] # Iterate over components and do stuff with them! nyaa # first for the main directory path... for subfile in main_directory_file_paths: if not (subfile in processed_basedir_paths): add_plain_brush( - current_main_directory.plus_file(subfile), - subfile.get_basename() + current_main_directory.plus_file(subfile), subfile.get_basename() ) processed_basedir_paths[subfile] = true @@ -170,35 +170,33 @@ func import_brushes(priority_ordered_search_path: Array) -> void: # random brush directory data system, so they can be # opened nya for non_extended_path in randomised_brush_subdirectory_map[randomised_subdir]: - full_paths.append(current_main_directory.plus_file( - randomised_subdir - ).plus_file( - non_extended_path - )) + full_paths.append( + current_main_directory.plus_file(randomised_subdir).plus_file( + non_extended_path + ) + ) # Now load! add_randomised_brush(full_paths, randomised_subdir) # and mark that we are done in the overall map ^.^ randomised_brush_subdirectories[randomised_subdir] = true # Now to iterate over the nonrandom brush files inside directories - for nonrandomised_subdir in nonrandomised_brush_subdirectory_map: + for nonrandomised_subdir in nonrandomised_brush_subdir_map: # initialise the set-map for this one if not already present :) if not (nonrandomised_subdir in processed_subdir_paths): processed_subdir_paths[nonrandomised_subdir] = {} # Get the paths within this subdirectory to check if they are # processed or not and if not, then process them. - var relpaths_of_contained_nonrandom_brushes : Array = nonrandomised_brush_subdirectory_map[nonrandomised_subdir] - for relative_path in relpaths_of_contained_nonrandom_brushes: + var relpaths_of_nonrandom_brushes: Array = nonrandomised_brush_subdir_map[nonrandomised_subdir] + for relative_path in relpaths_of_nonrandom_brushes: if not (relative_path in processed_subdir_paths[nonrandomised_subdir]): # We are not yet processed - var full_path : String = current_main_directory.plus_file( - nonrandomised_subdir - ).plus_file( + var full_path: String = current_main_directory.plus_file(nonrandomised_subdir).plus_file( relative_path ) # Add the path with the tooltip including the directory - add_plain_brush(full_path, nonrandomised_subdir.plus_file( - relative_path - ).get_basename()) + add_plain_brush( + full_path, nonrandomised_subdir.plus_file(relative_path).get_basename() + ) # Mark this as a processed relpath processed_subdir_paths[nonrandomised_subdir][relative_path] = true diff --git a/src/Autoload/OpenSave.gd b/src/Autoload/OpenSave.gd index b2930f703..6715e12bd 100644 --- a/src/Autoload/OpenSave.gd +++ b/src/Autoload/OpenSave.gd @@ -1,11 +1,11 @@ extends Node - -var current_save_paths := [] # Array of strings +var current_save_paths := [] # Array of strings # Stores a filename of a backup file in user:// until user saves manually -var backup_save_paths := [] # Array of strings +var backup_save_paths := [] # Array of strings +var preview_dialog_tscn = preload("res://src/UI/Dialogs/PreviewDialog.tscn") -onready var autosave_timer : Timer +onready var autosave_timer: Timer func _ready() -> void: @@ -17,28 +17,30 @@ func _ready() -> void: update_autosave() -func handle_loading_files(files : PoolStringArray) -> void: +func handle_loading_files(files: PoolStringArray) -> void: for file in files: file = file.replace("\\", "/") - var file_ext : String = file.get_extension().to_lower() - if file_ext == "pxo": # Pixelorama project file + var file_ext: String = file.get_extension().to_lower() + if file_ext == "pxo": # Pixelorama project file open_pxo_file(file) - elif file_ext == "tres" or file_ext == "gpl" or file_ext == "pal" or file_ext == "json": # Palettes + elif file_ext == "tres" or file_ext == "gpl" or file_ext == "pal" or file_ext == "json": Palettes.import_palette(file) - else: # Image files + else: # Image files var image := Image.new() var err := image.load(file) - if err != OK: # An error occured - var file_name : String = file.get_file() - Global.error_dialog.set_text(tr("Can't load file '%s'.\nError code: %s") % [file_name, str(err)]) + if err != OK: # An error occured + var file_name: String = file.get_file() + Global.error_dialog.set_text( + tr("Can't load file '%s'.\nError code: %s") % [file_name, str(err)] + ) Global.error_dialog.popup_centered() Global.dialog_open(true) continue handle_loading_image(file, image) -func handle_loading_image(file : String, image : Image) -> void: - var preview_dialog : ConfirmationDialog = preload("res://src/UI/Dialogs/PreviewDialog.tscn").instance() +func handle_loading_image(file: String, image: Image) -> void: + var preview_dialog: ConfirmationDialog = preview_dialog_tscn.instance() preview_dialog.path = file preview_dialog.image = image Global.control.add_child(preview_dialog) @@ -46,11 +48,11 @@ func handle_loading_image(file : String, image : Image) -> void: Global.dialog_open(true) -func open_pxo_file(path : String, untitled_backup : bool = false, replace_empty : bool = true) -> void: +func open_pxo_file(path: String, untitled_backup: bool = false, replace_empty: bool = true) -> void: var file := File.new() var err := file.open_compressed(path, File.READ, File.COMPRESSION_ZSTD) if err == ERR_FILE_UNRECOGNIZED: - err = file.open(path, File.READ) # If the file is not compressed open it raw (pre-v0.7) + err = file.open(path, File.READ) # If the file is not compressed open it raw (pre-v0.7) if err != OK: Global.error_dialog.set_text(tr("File failed to open. Error code %s") % err) @@ -59,8 +61,8 @@ func open_pxo_file(path : String, untitled_backup : bool = false, replace_empty file.close() return - var empty_project : bool = Global.current_project.is_empty() and replace_empty - var new_project : Project + var empty_project: bool = Global.current_project.is_empty() and replace_empty + var new_project: Project if empty_project: new_project = Global.current_project new_project.frames = [] @@ -84,8 +86,10 @@ func open_pxo_file(path : String, untitled_backup : bool = false, replace_empty for frame in new_project.frames: for cel in frame.cels: var buffer := file.get_buffer(new_project.size.x * new_project.size.y * 4) - cel.image.create_from_data(new_project.size.x, new_project.size.y, false, Image.FORMAT_RGBA8, buffer) - cel.image = cel.image # Just to call image_changed + cel.image.create_from_data( + new_project.size.x, new_project.size.y, false, Image.FORMAT_RGBA8, buffer + ) + cel.image = cel.image # Just to call image_changed if dict.result.has("brushes"): for brush in dict.result.brushes: @@ -104,8 +108,8 @@ func open_pxo_file(path : String, untitled_backup : bool = false, replace_empty else: if dict.error == OK and dict.result.has("fps"): Global.animation_timeline.fps_spinbox.value = dict.result.fps - new_project.frames = new_project.frames # Just to call frames_changed - new_project.layers = new_project.layers # Just to call layers_changed + new_project.frames = new_project.frames # Just to call frames_changed + new_project.layers = new_project.layers # Just to call layers_changed Global.canvas.camera_zoom() if not untitled_backup: @@ -128,7 +132,7 @@ func open_pxo_file(path : String, untitled_backup : bool = false, replace_empty # For pxo files older than v0.8 -func open_old_pxo_file(file : File, new_project : Project, first_line : String) -> void: +func open_old_pxo_file(file: File, new_project: Project, first_line: String) -> void: # var file_version := file.get_line() # Example, "v0.7.10-beta" var file_version := first_line var file_ver_splitted := file_version.split("-") @@ -140,15 +144,14 @@ func open_old_pxo_file(file : File, new_project : Project, first_line : String) var file_major_version = int(file_ver_splitted_numbers[0].replace("v", "")) var file_minor_version = int(file_ver_splitted_numbers[1]) var file_patch_version := 0 - var _file_status_version : String if file_ver_splitted_numbers.size() > 2: file_patch_version = int(file_ver_splitted_numbers[2]) - if file_ver_splitted.size() > 1: - _file_status_version = file_ver_splitted[1] if file_major_version == 0 and file_minor_version < 5: - Global.notification_label("File is from an older version of Pixelorama, as such it might not work properly") + Global.notification_label( + "File is from an older version of Pixelorama, as such it might not work properly" + ) var new_guides := true if file_major_version == 0: @@ -167,19 +170,26 @@ func open_old_pxo_file(file : File, new_project : Project, first_line : String) var layer_new_cels_linked := file.get_8() linked_cels.append(file.get_var()) - var l := Layer.new(layer_name, layer_visibility, layer_lock, HBoxContainer.new(), layer_new_cels_linked, []) + var l := Layer.new( + layer_name, + layer_visibility, + layer_lock, + HBoxContainer.new(), + layer_new_cels_linked, + [] + ) new_project.layers.append(l) global_layer_line = file.get_line() var frame_line := file.get_line() - while frame_line == "--": # Load frames + while frame_line == "--": # Load frames var frame_class := Frame.new() var width := file.get_16() var height := file.get_16() var layer_i := 0 var layer_line := file.get_line() - while layer_line == "-": # Load layers + while layer_line == "-": # Load layers var buffer := file.get_buffer(width * height * 4) if file_major_version == 0 and file_minor_version < 7: var layer_name_old_version = file.get_line() @@ -194,16 +204,17 @@ func open_old_pxo_file(file : File, new_project : Project, first_line : String) frame_class.cels.append(Cel.new(image, cel_opacity)) if file_major_version >= 0 and file_minor_version >= 7: if frame in linked_cels[layer_i]: + var linked_cel: Cel = new_project.layers[layer_i].linked_cels[0].cels[layer_i] new_project.layers[layer_i].linked_cels.append(frame_class) - frame_class.cels[layer_i].image = new_project.layers[layer_i].linked_cels[0].cels[layer_i].image - frame_class.cels[layer_i].image_texture = new_project.layers[layer_i].linked_cels[0].cels[layer_i].image_texture + frame_class.cels[layer_i].image = linked_cel.image + frame_class.cels[layer_i].image_texture = linked_cel.image_texture layer_i += 1 layer_line = file.get_line() if !new_guides: - var guide_line := file.get_line() # "guideline" no pun intended - while guide_line == "|": # Load guides + var guide_line := file.get_line() # "guideline" no pun intended + while guide_line == "|": # Load guides var guide := Guide.new() guide.type = file.get_8() if guide.type == guide.Types.HORIZONTAL: @@ -223,8 +234,8 @@ func open_old_pxo_file(file : File, new_project : Project, first_line : String) frame += 1 if new_guides: - var guide_line := file.get_line() # "guideline" no pun intended - while guide_line == "|": # Load guides + var guide_line := file.get_line() # "guideline" no pun intended + while guide_line == "|": # Load guides var guide := Guide.new() guide.type = file.get_8() if guide.type == guide.Types.HORIZONTAL: @@ -263,31 +274,42 @@ func open_old_pxo_file(file : File, new_project : Project, first_line : String) var tag_line := file.get_line() while tag_line == ".T/": var tag_name := file.get_line() - var tag_color : Color = file.get_var() + var tag_color: Color = file.get_var() var tag_from := file.get_8() var tag_to := file.get_8() - new_project.animation_tags.append(AnimationTag.new(tag_name, tag_color, tag_from, tag_to)) - new_project.animation_tags = new_project.animation_tags # To execute animation_tags_changed() + new_project.animation_tags.append( + AnimationTag.new(tag_name, tag_color, tag_from, tag_to) + ) + new_project.animation_tags = new_project.animation_tags # To execute animation_tags_changed() tag_line = file.get_line() -func save_pxo_file(path : String, autosave : bool, use_zstd_compression := true, project : Project = Global.current_project) -> void: +func save_pxo_file( + path: String, + autosave: bool, + use_zstd_compression := true, + project: Project = Global.current_project +) -> void: if !autosave: project.name = path.get_file() var serialized_data = project.serialize() if !serialized_data: - Global.error_dialog.set_text(tr("File failed to save. Converting project data to dictionary failed.")) + Global.error_dialog.set_text( + tr("File failed to save. Converting project data to dictionary failed.") + ) Global.error_dialog.popup_centered() Global.dialog_open(true) return var to_save = JSON.print(serialized_data) if !to_save: - Global.error_dialog.set_text(tr("File failed to save. Converting dictionary to JSON failed.")) + Global.error_dialog.set_text( + tr("File failed to save. Converting dictionary to JSON failed.") + ) Global.error_dialog.popup_centered() Global.dialog_open(true) return - var file : File = File.new() + var file: File = File.new() var err if use_zstd_compression: err = file.open_compressed(path, File.WRITE, File.COMPRESSION_ZSTD) @@ -314,7 +336,7 @@ func save_pxo_file(path : String, autosave : bool, use_zstd_compression := true, file.close() - if OS.get_name() == "HTML5" and OS.has_feature('JavaScript') and !autosave: + if OS.get_name() == "HTML5" and OS.has_feature("JavaScript") and !autosave: err = file.open(path, File.READ) if !err: var file_data = Array(file.get_buffer(file.get_len())) @@ -346,7 +368,7 @@ func save_pxo_file(path : String, autosave : bool, use_zstd_compression := true, save_project_to_recent_list(path) -func open_image_as_new_tab(path : String, image : Image) -> void: +func open_image_as_new_tab(path: String, image: Image) -> void: var project = Project.new([], path.get_file(), image.get_size()) project.layers.append(Layer.new()) Global.projects.append(project) @@ -359,19 +381,21 @@ func open_image_as_new_tab(path : String, image : Image) -> void: set_new_tab(project, path) -func open_image_as_spritesheet_tab(path : String, image : Image, horizontal : int, vertical : int) -> void: +func open_image_as_spritesheet_tab(path: String, image: Image, horiz: int, vert: int) -> void: var project = Project.new([], path.get_file()) project.layers.append(Layer.new()) Global.projects.append(project) - horizontal = min(horizontal, image.get_size().x) - vertical = min(vertical, image.get_size().y) - var frame_width := image.get_size().x / horizontal - var frame_height := image.get_size().y / vertical - for yy in range(vertical): - for xx in range(horizontal): + horiz = min(horiz, image.get_size().x) + vert = min(vert, image.get_size().y) + var frame_width := image.get_size().x / horiz + var frame_height := image.get_size().y / vert + for yy in range(vert): + for xx in range(horiz): var frame := Frame.new() var cropped_image := Image.new() - cropped_image = image.get_rect(Rect2(frame_width * xx, frame_height * yy, frame_width, frame_height)) + cropped_image = image.get_rect( + Rect2(frame_width * xx, frame_height * yy, frame_width, frame_height) + ) project.size = cropped_image.get_size() cropped_image.convert(Image.FORMAT_RGBA8) frame.cels.append(Cel.new(cropped_image, 1)) @@ -387,7 +411,9 @@ func open_image_as_spritesheet_tab(path : String, image : Image, horizontal : in set_new_tab(project, path) -func open_image_as_spritesheet_layer(_path : String, image : Image, file_name : String, horizontal : int, vertical : int, start_frame : int) -> void: +func open_image_as_spritesheet_layer( + _path: String, image: Image, file_name: String, horizontal: int, vertical: int, start_frame: int +) -> void: # data needed to slice images horizontal = min(horizontal, image.get_size().x) vertical = min(vertical, image.get_size().y) @@ -395,36 +421,42 @@ func open_image_as_spritesheet_layer(_path : String, image : Image, file_name : var frame_height := image.get_size().y / vertical # resize canvas to if "frame_width" or "frame_height" is too large - var project_width :int = max(frame_width, Global.current_project.size.x) - var project_height :int = max(frame_height, Global.current_project.size.y) - DrawingAlgos.resize_canvas(project_width, project_height,0 ,0) + var project_width: int = max(frame_width, Global.current_project.size.x) + var project_height: int = max(frame_height, Global.current_project.size.y) + DrawingAlgos.resize_canvas(project_width, project_height, 0, 0) # slice images - var image_no :int = 0 + var image_no: int = 0 for yy in range(vertical): for xx in range(horizontal): var cropped_image := Image.new() - cropped_image = image.get_rect(Rect2(frame_width * xx, frame_height * yy, frame_width, frame_height)) + cropped_image = image.get_rect( + Rect2(frame_width * xx, frame_height * yy, frame_width, frame_height) + ) if (start_frame + (image_no)) < Global.current_project.frames.size(): # if frames are already present then fill those first if image_no == 0: open_image_as_new_layer(cropped_image, file_name, start_frame + image_no) else: - open_image_at_frame(cropped_image, Global.current_project.layers.size() - 1, start_frame + image_no) + open_image_at_frame( + cropped_image, + Global.current_project.layers.size() - 1, + start_frame + image_no + ) else: # if no more frames are present then start making new frames open_image_as_new_frame(cropped_image, Global.current_project.layers.size() - 1) image_no += 1 -func open_image_at_frame(image : Image, layer_index := 0, frame_index := 0) -> void: +func open_image_at_frame(image: Image, layer_index := 0, frame_index := 0) -> void: var project = Global.current_project image.crop(project.size.x, project.size.y) project.undos += 1 project.undo_redo.create_action("Replaced Frame") - var frames :Array = [] + var frames: Array = [] # create a duplicate of "project.frames" for i in project.frames.size(): var frame := Frame.new() @@ -449,10 +481,10 @@ func open_image_at_frame(image : Image, layer_index := 0, frame_index := 0) -> v project.undo_redo.commit_action() -func open_image_as_new_frame(image : Image, layer_index := 0) -> void: +func open_image_as_new_frame(image: Image, layer_index := 0) -> void: var project = Global.current_project image.crop(project.size.x, project.size.y) - var new_frames : Array = project.frames.duplicate() + var new_frames: Array = project.frames.duplicate() var frame := Frame.new() for i in project.layers.size(): @@ -481,16 +513,16 @@ func open_image_as_new_frame(image : Image, layer_index := 0) -> void: project.undo_redo.commit_action() -func open_image_as_new_layer(image : Image, file_name : String, frame_index := 0) -> void: +func open_image_as_new_layer(image: Image, file_name: String, frame_index := 0) -> void: var project = Global.current_project image.crop(project.size.x, project.size.y) - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() var layer := Layer.new(file_name) Global.current_project.undos += 1 Global.current_project.undo_redo.create_action("Add Layer") for i in project.frames.size(): - var new_cels : Array = project.frames[i].cels.duplicate(true) + var new_cels: Array = project.frames[i].cels.duplicate(true) if i == frame_index: image.convert(Image.FORMAT_RGBA8) new_cels.append(Cel.new(image, 1)) @@ -502,7 +534,6 @@ func open_image_as_new_layer(image : Image, file_name : String, frame_index := 0 project.undo_redo.add_do_property(project.frames[i], "cels", new_cels) project.undo_redo.add_undo_property(project.frames[i], "cels", project.frames[i].cels) - new_layers.append(layer) project.undo_redo.add_do_property(project, "current_layer", new_layers.size() - 1) @@ -518,11 +549,17 @@ func open_image_as_new_layer(image : Image, file_name : String, frame_index := 0 project.undo_redo.commit_action() -func set_new_tab(project : Project, path : String) -> void: +func set_new_tab(project: Project, path: String) -> void: Global.tabs.current_tab = Global.tabs.get_tab_count() - 1 Global.canvas.camera_zoom() - Global.window_title = path.get_file() + " (" + tr("imported") + ") - Pixelorama " + Global.current_version + Global.window_title = ( + path.get_file() + + " (" + + tr("imported") + + ") - Pixelorama " + + Global.current_version + ) if project.has_changed: Global.window_title = Global.window_title + "(*)" var file_name := path.get_basename().get_file() @@ -535,7 +572,8 @@ func set_new_tab(project : Project, path : String) -> void: func update_autosave() -> void: autosave_timer.stop() - autosave_timer.wait_time = Global.autosave_interval * 60 # Interval parameter is in minutes, wait_time is seconds + # Interval parameter is in minutes, wait_time is seconds + autosave_timer.wait_time = Global.autosave_interval * 60 if Global.enable_autosave: autosave_timer.start() @@ -553,7 +591,7 @@ func _on_Autosave_timeout() -> void: # Backup paths are stored in two ways: # 1) User already manually saved and defined a save path -> {current_save_path, backup_save_path} # 2) User didn't manually saved, "untitled" backup is stored -> {backup_save_path, backup_save_path} -func store_backup_path(i : int) -> void: +func store_backup_path(i: int) -> void: if current_save_paths[i] != "": # Remove "untitled" backup if it existed on this project instance if Global.config_cache.has_section_key("backups", backup_save_paths[i]): @@ -566,7 +604,7 @@ func store_backup_path(i : int) -> void: Global.config_cache.save("user://cache.ini") -func remove_backup(i : int) -> void: +func remove_backup(i: int) -> void: # Remove backup file if backup_save_paths[i] != "": if current_save_paths[i] != "": @@ -577,7 +615,7 @@ func remove_backup(i : int) -> void: backup_save_paths[i] = "" -func remove_backup_by_path(project_path : String, backup_path : String) -> void: +func remove_backup_by_path(project_path: String, backup_path: String) -> void: Directory.new().remove(backup_path) if Global.config_cache.has_section_key("backups", project_path): Global.config_cache.erase_section_key("backups", project_path) @@ -586,7 +624,7 @@ func remove_backup_by_path(project_path : String, backup_path : String) -> void: Global.config_cache.save("user://cache.ini") -func reload_backup_file(project_paths : Array, backup_paths : Array) -> void: +func reload_backup_file(project_paths: Array, backup_paths: Array) -> void: assert(project_paths.size() == backup_paths.size()) # Clear non-existant backups var existing_backups_count := 0 @@ -609,16 +647,20 @@ func reload_backup_file(project_paths : Array, backup_paths : Array) -> void: backup_save_paths[i] = backup_paths[i] # If project path is the same as backup save path -> the backup was untitled - if project_paths[i] != backup_paths[i]: # If the user has saved + if project_paths[i] != backup_paths[i]: # If the user has saved current_save_paths[i] = project_paths[i] - Global.window_title = project_paths[i].get_file() + " - Pixelorama(*) " + Global.current_version + Global.window_title = ( + project_paths[i].get_file() + + " - Pixelorama(*) " + + Global.current_version + ) Global.current_project.has_changed = true Global.notification_label("Backup reloaded") -func save_project_to_recent_list(path : String) -> void: - var top_menu_container : Panel = Global.top_menu_container +func save_project_to_recent_list(path: String) -> void: + var top_menu_container: Panel = Global.top_menu_container if path.get_file().substr(0, 7) == "backup-" or path == "": return diff --git a/src/Autoload/Palettes.gd b/src/Autoload/Palettes.gd index 7fc9baa6b..0de97db48 100644 --- a/src/Autoload/Palettes.gd +++ b/src/Autoload/Palettes.gd @@ -1,25 +1,19 @@ extends Node -const DEFAULT_PALETTE_NAME = "Default" - # Presets for creating a new palette enum NewPalettePresetType { - Empty = 0, - FromCurrentPalette = 1, - FromCurrentSprite = 2, - FromCurrentSelection = 3 + EMPTY = 0, + FROM_CURRENT_PALETTE = 1, + FROM_CURRENT_SPRITE = 2, + FROM_CURRENT_SELECTION = 3 } # Color options when user creates a new palette from current sprite or selection -enum GetColorsFrom { - CurrentFrame = 0, - CurrentCel = 1, - AllFrames = 2 -} +enum GetColorsFrom { CURRENT_FRAME = 0, CURRENT_CEL = 1, ALL_FRAMES = 2 } +const DEFAULT_PALETTE_NAME = "Default" # All available palettes var palettes := {} - # Currently displayed palette var current_palette = null @@ -31,7 +25,6 @@ var right_selected_color := -1 func _ready() -> void: load_palettes() - pass func get_palettes() -> Dictionary: @@ -92,17 +85,29 @@ func save_palette(palette: Palette) -> String: return save_path -func create_new_palette(preset: int, name: String, comment: String, width: int, height: int, add_alpha_colors: bool, get_colors_from: int) -> void: +func create_new_palette( + preset: int, + name: String, + comment: String, + width: int, + height: int, + add_alpha_colors: bool, + get_colors_from: int +) -> void: check_palette_settings_values(name, width, height) match preset: - NewPalettePresetType.Empty: + NewPalettePresetType.EMPTY: create_new_empty_palette(name, comment, width, height) - NewPalettePresetType.FromCurrentPalette: + NewPalettePresetType.FROM_CURRENT_PALETTE: create_new_palette_from_current_palette(name, comment) - NewPalettePresetType.FromCurrentSprite: - create_new_palette_from_current_sprite(name, comment, width, height, add_alpha_colors, get_colors_from) - NewPalettePresetType.FromCurrentSelection: - create_new_palette_from_current_selection(name, comment, width, height, add_alpha_colors, get_colors_from) + NewPalettePresetType.FROM_CURRENT_SPRITE: + create_new_palette_from_current_sprite( + name, comment, width, height, add_alpha_colors, get_colors_from + ) + NewPalettePresetType.FROM_CURRENT_SELECTION: + create_new_palette_from_current_selection( + name, comment, width, height, add_alpha_colors, get_colors_from + ) func create_new_empty_palette(name: String, comment: String, width: int, height: int) -> void: @@ -122,7 +127,14 @@ func create_new_palette_from_current_palette(name: String, comment: String) -> v select_palette(palette_path) -func create_new_palette_from_current_selection(name: String, comment: String, width: int, height: int, add_alpha_colors: bool, get_colors_from: int): +func create_new_palette_from_current_selection( + name: String, + comment: String, + width: int, + height: int, + add_alpha_colors: bool, + get_colors_from: int +): var new_palette: Palette = Palette.new(name, width, height, comment) var current_project = Global.current_project var pixels := [] @@ -134,7 +146,14 @@ func create_new_palette_from_current_selection(name: String, comment: String, wi fill_new_palette_with_colors(pixels, new_palette, add_alpha_colors, get_colors_from) -func create_new_palette_from_current_sprite(name: String, comment: String, width: int, height: int, add_alpha_colors: bool, get_colors_from: int): +func create_new_palette_from_current_sprite( + name: String, + comment: String, + width: int, + height: int, + add_alpha_colors: bool, + get_colors_from: int +): var new_palette: Palette = Palette.new(name, width, height, comment) var current_project = Global.current_project var pixels := [] @@ -144,18 +163,20 @@ func create_new_palette_from_current_sprite(name: String, comment: String, width fill_new_palette_with_colors(pixels, new_palette, add_alpha_colors, get_colors_from) -func fill_new_palette_with_colors(pixels: Array, new_palette: Palette, add_alpha_colors: bool, get_colors_from: int): +func fill_new_palette_with_colors( + pixels: Array, new_palette: Palette, add_alpha_colors: bool, get_colors_from: int +): var current_project = Global.current_project var cels := [] match get_colors_from: - GetColorsFrom.CurrentCel: + GetColorsFrom.CURRENT_CEL: for cel_index in current_project.selected_cels: - var cel : Cel = current_project.frames[cel_index[0]].cels[cel_index[1]] + var cel: Cel = current_project.frames[cel_index[0]].cels[cel_index[1]] cels.append(cel) - GetColorsFrom.CurrentFrame: + GetColorsFrom.CURRENT_FRAME: for cel in current_project.frames[current_project.current_frame].cels: cels.append(cel) - GetColorsFrom.AllFrames: + GetColorsFrom.ALL_FRAMES: for frame in current_project.frames: for cel in frame.cels: cels.append(cel) @@ -167,7 +188,7 @@ func fill_new_palette_with_colors(pixels: Array, new_palette: Palette, add_alpha if cel_image.is_invisible(): continue for i in pixels: - var color : Color = cel_image.get_pixelv(i) + var color: Color = cel_image.get_pixelv(i) if color.a > 0: if not add_alpha_colors: color.a = 1 @@ -203,7 +224,10 @@ func current_palete_delete() -> void: func current_palette_add_color(mouse_button: int, start_index: int = 0) -> void: - if not current_palette.is_full() and (mouse_button == BUTTON_LEFT or mouse_button == BUTTON_RIGHT): + if ( + not current_palette.is_full() + and (mouse_button == BUTTON_LEFT or mouse_button == BUTTON_RIGHT) + ): # Get color on left or right tool var color = Tools.get_assigned_color(mouse_button) current_palette.add_color(color, start_index) @@ -305,15 +329,17 @@ func load_palettes() -> void: # get overwritten by those of the same name in user files search_locations.invert() priority_ordered_files.invert() - var default_palette_name = Global.config_cache.get_value("data", "last_palette", DEFAULT_PALETTE_NAME) + var default_palette_name = Global.config_cache.get_value( + "data", "last_palette", DEFAULT_PALETTE_NAME + ) for i in range(len(search_locations)): # If palette is not in palettes write path - make it's copy in the write path var make_copy := false if search_locations[i] != palettes_write_path: make_copy = true - var base_directory : String = search_locations[i] - var palette_files : Array = priority_ordered_files[i] + var base_directory: String = search_locations[i] + var palette_files: Array = priority_ordered_files[i] for file_name in palette_files: var palette: Palette = load(base_directory.plus_file(file_name)) if palette: @@ -349,7 +375,7 @@ func load_palettes() -> void: func get_palette_priority_file_map(looking_paths: Array) -> Array: var final_list := [] # Holds pattern files already found - var working_file_set : Dictionary = {} + var working_file_set: Dictionary = {} for search_directory in looking_paths: var to_add_files := [] var files = get_palette_files(search_directory) @@ -365,7 +391,7 @@ func get_palette_priority_file_map(looking_paths: Array) -> Array: # Get the palette files in a single directory. # if it does not exist, return [] -func get_palette_files(path : String ) -> Array: +func get_palette_files(path: String) -> Array: var dir := Directory.new() var results = [] @@ -379,7 +405,11 @@ func get_palette_files(path : String ) -> Array: var file_name = dir.get_next() if file_name == "": break - elif (not file_name.begins_with(".")) && file_name.to_lower().ends_with("tres") && not dir.current_is_dir(): + elif ( + (not file_name.begins_with(".")) + && file_name.to_lower().ends_with("tres") + && not dir.current_is_dir() + ): results.append(file_name) dir.list_dir_end() @@ -389,10 +419,10 @@ func get_palette_files(path : String ) -> Array: # Locate the highest priority palette by the given relative filename # If none is found in the directories, then do nothing and return null func get_best_palette_file_location(looking_paths: Array, fname: String): # -> String: - var priority_fmap : Array = get_palette_priority_file_map(looking_paths) + var priority_fmap: Array = get_palette_priority_file_map(looking_paths) for i in range(len(looking_paths)): - var base_path : String = looking_paths[i] - var the_files : Array = priority_fmap[i] + var base_path: String = looking_paths[i] + var the_files: Array = priority_fmap[i] if the_files.has(fname): return base_path.plus_file(fname) return null @@ -403,7 +433,7 @@ func import_palette(path: String) -> void: # If there is a palette with same name ignore import for now return - var palette : Palette = null + var palette: Palette = null match path.to_lower().get_extension(): "tres": palette = load(path) @@ -444,8 +474,8 @@ func import_palette(path: String) -> void: func import_gpl(path: String, text: String) -> Palette: # Refer to app/core/gimppalette-load.c of the GIMP for the "living spec" - var result : Palette = null - var lines = text.split('\n') + var result: Palette = null + var lines = text.split("\n") var line_number := 0 var palette_name := path.get_basename().get_file() var comments := "" @@ -458,8 +488,8 @@ func import_gpl(path: String, text: String) -> Palette: return result # Comments - if line.begins_with('#'): - comments += line.trim_prefix('#') + '\n' + if line.begins_with("#"): + comments += line.trim_prefix("#") + "\n" # Some programs output palette name in a comment for old format if line.begins_with("#Palette Name: "): palette_name = line.replace("#Palette Name: ", "") @@ -470,10 +500,10 @@ func import_gpl(path: String, text: String) -> Palette: continue elif line_number > 0 && line.length() >= 9: line = line.replace("\t", " ") - var color_data : PoolStringArray = line.split(" ", false, 4) - var red : float = color_data[0].to_float() / 255.0 - var green : float = color_data[1].to_float() / 255.0 - var blue : float = color_data[2].to_float() / 255.0 + var color_data: PoolStringArray = line.split(" ", false, 4) + var red: float = color_data[0].to_float() / 255.0 + var green: float = color_data[1].to_float() / 255.0 + var blue: float = color_data[2].to_float() / 255.0 var color = Color(red, green, blue) if color_data.size() >= 4: # Ignore color name for now - result.add_color(color, color_data[3]) @@ -484,7 +514,7 @@ func import_gpl(path: String, text: String) -> Palette: line_number += 1 if line_number > 0: - var height : int = ceil(colors.size() / 8.0) + var height: int = ceil(colors.size() / 8.0) result = Palette.new(palette_name, 8, height, comments) for color in colors: result.add_color(color) @@ -495,23 +525,23 @@ func import_gpl(path: String, text: String) -> Palette: func import_pal_palette(path: String, text: String) -> Palette: var result: Palette = null var colors := PoolColorArray() - var lines = text.split('\n') + var lines = text.split("\n") - if not 'JASC-PAL' in lines[0] or not '0100' in lines[1]: + if not "JASC-PAL" in lines[0] or not "0100" in lines[1]: return result var num_colors = int(lines[2]) for i in range(3, num_colors + 3): - var color_data = lines[i].split(' ') - var red : float = color_data[0].to_float() / 255.0 - var green : float = color_data[1].to_float() / 255.0 - var blue : float = color_data[2].to_float() / 255.0 + var color_data = lines[i].split(" ") + var red: float = color_data[0].to_float() / 255.0 + var green: float = color_data[1].to_float() / 255.0 + var blue: float = color_data[2].to_float() / 255.0 var color = Color(red, green, blue) colors.append(color) - var height : int = ceil(colors.size() / 8.0) + var height: int = ceil(colors.size() / 8.0) result = Palette.new(path.get_basename().get_file(), 8, height) for color in colors: result.add_color(color) @@ -519,7 +549,6 @@ func import_pal_palette(path: String, text: String) -> Palette: func import_image_palette(path: String, image: Image) -> Palette: - var colors := [] var height: int = image.get_height() var width: int = image.get_width() @@ -533,7 +562,7 @@ func import_image_palette(path: String, image: Image) -> Palette: colors.append(color) image.unlock() - var palette_height : int = ceil(colors.size() / 8.0) + var palette_height: int = ceil(colors.size() / 8.0) var result: Palette = Palette.new(path.get_basename().get_file(), 8, palette_height) for color in colors: result.add_color(color) @@ -554,7 +583,7 @@ func import_json_palette(text: String): result = null else: # If parse OK var data = result_json.result - if data.has("name"): # If data is 'valid' palette file + if data.has("name"): # If data is 'valid' palette file result.name = data.name if data.has("comments"): result.comment = data.comments diff --git a/src/Autoload/Tools.gd b/src/Autoload/Tools.gd index 2027cc3c7..7c2aa6a35 100644 --- a/src/Autoload/Tools.gd +++ b/src/Autoload/Tools.gd @@ -1,34 +1,62 @@ extends Node +signal color_changed(color, button) + +var pen_pressure := 1.0 +var control := false +var shift := false +var alt := false + +var _tools = { + "RectSelect": "res://src/Tools/SelectionTools/RectSelect.tscn", + "EllipseSelect": "res://src/Tools/SelectionTools/EllipseSelect.tscn", + "PolygonSelect": "res://src/Tools/SelectionTools/PolygonSelect.tscn", + "ColorSelect": "res://src/Tools/SelectionTools/ColorSelect.tscn", + "MagicWand": "res://src/Tools/SelectionTools/MagicWand.tscn", + "Lasso": "res://src/Tools/SelectionTools/Lasso.tscn", + "Move": "res://src/Tools/Move.tscn", + "Zoom": "res://src/Tools/Zoom.tscn", + "Pan": "res://src/Tools/Pan.tscn", + "ColorPicker": "res://src/Tools/ColorPicker.tscn", + "Pencil": "res://src/Tools/Pencil.tscn", + "Eraser": "res://src/Tools/Eraser.tscn", + "Bucket": "res://src/Tools/Bucket.tscn", + "Shading": "res://src/Tools/Shading.tscn", + "LineTool": "res://src/Tools/LineTool.tscn", + "RectangleTool": "res://src/Tools/RectangleTool.tscn", + "EllipseTool": "res://src/Tools/EllipseTool.tscn", +} +var _slots = {} +var _panels = {} +var _tool_buttons: Node +var _active_button := -1 +var _last_position := Vector2.INF + class Slot: - - var name : String - var kname : String - var tool_node : Node = null - var button : int - var color : Color + var name: String + var kname: String + var tool_node: Node = null + var button: int + var color: Color var pixel_perfect := false var horizontal_mirror := false var vertical_mirror := false - - func _init(slot_name : String) -> void: + func _init(slot_name: String) -> void: name = slot_name kname = name.replace(" ", "_").to_lower() load_config() - func save_config() -> void: var config := { - "pixel_perfect" : pixel_perfect, - "horizontal_mirror" : horizontal_mirror, - "vertical_mirror" : vertical_mirror, + "pixel_perfect": pixel_perfect, + "horizontal_mirror": horizontal_mirror, + "vertical_mirror": vertical_mirror, } Global.config_cache.set_value(kname, "slot", config) - func load_config() -> void: var config = Global.config_cache.get_value(kname, "slot", {}) pixel_perfect = config.get("pixel_perfect", pixel_perfect) @@ -36,39 +64,6 @@ class Slot: vertical_mirror = config.get("vertical_mirror", vertical_mirror) -signal color_changed(color, button) - -var _tools = { - "RectSelect" : "res://src/Tools/SelectionTools/RectSelect.tscn", - "EllipseSelect" : "res://src/Tools/SelectionTools/EllipseSelect.tscn", - "PolygonSelect" : "res://src/Tools/SelectionTools/PolygonSelect.tscn", - "ColorSelect" : "res://src/Tools/SelectionTools/ColorSelect.tscn", - "MagicWand" : "res://src/Tools/SelectionTools/MagicWand.tscn", - "Lasso" : "res://src/Tools/SelectionTools/Lasso.tscn", - "Move" : "res://src/Tools/Move.tscn", - "Zoom" : "res://src/Tools/Zoom.tscn", - "Pan" : "res://src/Tools/Pan.tscn", - "ColorPicker" : "res://src/Tools/ColorPicker.tscn", - "Pencil" : "res://src/Tools/Pencil.tscn", - "Eraser" : "res://src/Tools/Eraser.tscn", - "Bucket" : "res://src/Tools/Bucket.tscn", - "Shading" : "res://src/Tools/Shading.tscn", - "LineTool" : "res://src/Tools/LineTool.tscn", - "RectangleTool" : "res://src/Tools/RectangleTool.tscn", - "EllipseTool" : "res://src/Tools/EllipseTool.tscn", -} -var _slots = {} -var _panels = {} -var _tool_buttons : Node -var _active_button := -1 -var _last_position := Vector2.INF - -var pen_pressure := 1.0 -var control := false -var shift := false -var alt := false - - func _ready() -> void: _tool_buttons = Global.control.find_node("ToolButtons") _slots[BUTTON_LEFT] = Slot.new("Left tool") @@ -76,7 +71,9 @@ func _ready() -> void: _panels[BUTTON_LEFT] = Global.control.find_node("LeftPanelContainer", true, false) _panels[BUTTON_RIGHT] = Global.control.find_node("RightPanelContainer", true, false) - var tool_name : String = Global.config_cache.get_value(_slots[BUTTON_LEFT].kname, "tool", "Pencil") + var tool_name: String = Global.config_cache.get_value( + _slots[BUTTON_LEFT].kname, "tool", "Pencil" + ) if not tool_name in _tools: tool_name = "Pencil" set_tool(tool_name, BUTTON_LEFT) @@ -88,17 +85,20 @@ func _ready() -> void: update_tool_buttons() update_tool_cursors() - yield(get_tree(), "idle_frame") # Necessary for the color picker nodes to update their color values - var color_value : Color = Global.config_cache.get_value(_slots[BUTTON_LEFT].kname, "color", Color.black) + # Yield is necessary for the color picker nodes to update their color values + yield(get_tree(), "idle_frame") + var color_value: Color = Global.config_cache.get_value( + _slots[BUTTON_LEFT].kname, "color", Color.black + ) assign_color(color_value, BUTTON_LEFT, false) color_value = Global.config_cache.get_value(_slots[BUTTON_RIGHT].kname, "color", Color.white) assign_color(color_value, BUTTON_RIGHT, false) -func set_tool(name : String, button : int) -> void: +func set_tool(name: String, button: int) -> void: var slot = _slots[button] - var panel : Node = _panels[button] - var node : Node = load(_tools[name]).instance() + var panel: Node = _panels[button] + var node: Node = load(_tools[name]).instance() node.name = name node.tool_slot = slot slot.tool_node = node @@ -106,9 +106,9 @@ func set_tool(name : String, button : int) -> void: panel.add_child(slot.tool_node) -func assign_tool(name : String, button : int) -> void: +func assign_tool(name: String, button: int) -> void: var slot = _slots[button] - var panel : Node = _panels[button] + var panel: Node = _panels[button] if slot.tool_node != null: if slot.tool_node.name == name: @@ -134,8 +134,8 @@ func swap_color() -> void: assign_color(left, BUTTON_RIGHT, false) -func assign_color(color : Color, button : int, change_alpha := true) -> void: - var c : Color = _slots[button].color +func assign_color(color: Color, button: int, change_alpha := true) -> void: + var c: Color = _slots[button].color # This was requested by Issue #54 on GitHub if color.a == 0 and change_alpha: if color.r != c.r or color.g != c.g or color.b != c.b: @@ -145,11 +145,11 @@ func assign_color(color : Color, button : int, change_alpha := true) -> void: emit_signal("color_changed", color, button) -func get_assigned_color(button : int) -> Color: +func get_assigned_color(button: int) -> Color: return _slots[button].color -func set_button_size(button_size : int) -> void: +func set_button_size(button_size: int) -> void: if button_size == Global.ButtonSize.SMALL: for t in _tool_buttons.get_children(): t.rect_min_size = Vector2(24, 24) @@ -175,16 +175,23 @@ func set_button_size(button_size : int) -> void: func update_tool_buttons() -> void: for child in _tool_buttons.get_children(): - var left_background : NinePatchRect = child.get_node("BackgroundLeft") - var right_background : NinePatchRect = child.get_node("BackgroundRight") + var left_background: NinePatchRect = child.get_node("BackgroundLeft") + var right_background: NinePatchRect = child.get_node("BackgroundRight") left_background.visible = _slots[BUTTON_LEFT].tool_node.name == child.name right_background.visible = _slots[BUTTON_RIGHT].tool_node.name == child.name func update_tool_cursors() -> void: - var left_image = load("res://assets/graphics/tools/cursors/%s.png" % _slots[BUTTON_LEFT].tool_node.name.to_lower()) + var left_image = load( + "res://assets/graphics/tools/cursors/%s.png" % _slots[BUTTON_LEFT].tool_node.name.to_lower() + ) Global.left_cursor.texture = left_image - var right_image = load("res://assets/graphics/tools/cursors/%s.png" % _slots[BUTTON_RIGHT].tool_node.name.to_lower()) + var right_image = load( + ( + "res://assets/graphics/tools/cursors/%s.png" + % _slots[BUTTON_RIGHT].tool_node.name.to_lower() + ) + ) Global.right_cursor.texture = right_image @@ -200,7 +207,7 @@ func draw_preview() -> void: _slots[BUTTON_RIGHT].tool_node.draw_preview() -func handle_draw(position : Vector2, event : InputEvent) -> void: +func handle_draw(position: Vector2, event: InputEvent) -> void: if not (Global.can_draw and Global.has_focus): return @@ -234,7 +241,7 @@ func handle_draw(position : Vector2, event : InputEvent) -> void: if _active_button != -1: _slots[_active_button].tool_node.draw_move(draw_pos) - var project : Project = Global.current_project + var project: Project = Global.current_project var text := "[%s×%s]" % [project.size.x, project.size.y] if Global.has_focus: text += " %s, %s" % [position.x, position.y] diff --git a/src/Classes/AnimationTag.gd b/src/Classes/AnimationTag.gd index e66c413a1..a6cfb697a 100644 --- a/src/Classes/AnimationTag.gd +++ b/src/Classes/AnimationTag.gd @@ -1,11 +1,11 @@ -class_name AnimationTag extends Reference +class_name AnimationTag +extends Reference # A class for frame tag properties - -var name : String -var color : Color -var from : int -var to : int +var name: String +var color: Color +var from: int +var to: int func _init(_name, _color, _from, _to) -> void: diff --git a/src/Classes/Cel.gd b/src/Classes/Cel.gd index 76f4b08ee..c8c9a5d12 100644 --- a/src/Classes/Cel.gd +++ b/src/Classes/Cel.gd @@ -1,15 +1,15 @@ -class_name Cel extends Reference +class_name Cel +extends Reference # A class for cel properties. # The term "cel" comes from "celluloid" (https://en.wikipedia.org/wiki/Cel). # The "image" variable is where the image data of each cel are. - -var image : Image setget image_changed -var image_texture : ImageTexture -var opacity : float +var image: Image setget image_changed +var image_texture: ImageTexture +var opacity: float -func _init(_image := Image.new(), _opacity := 1.0, _image_texture : ImageTexture = null) -> void: +func _init(_image := Image.new(), _opacity := 1.0, _image_texture: ImageTexture = null) -> void: if _image_texture: image_texture = _image_texture else: @@ -18,7 +18,7 @@ func _init(_image := Image.new(), _opacity := 1.0, _image_texture : ImageTexture opacity = _opacity -func image_changed(value : Image) -> void: +func image_changed(value: Image) -> void: image = value if !image.is_empty(): image_texture.create_from_image(image, 0) diff --git a/src/Classes/Drawers.gd b/src/Classes/Drawers.gd index 099ad5e06..f7c3d603d 100644 --- a/src/Classes/Drawers.gd +++ b/src/Classes/Drawers.gd @@ -1,16 +1,29 @@ class_name Drawer +var pixel_perfect := false setget set_pixel_perfect +var horizontal_mirror := false +var vertical_mirror := false +var color_op := ColorOp.new() + +var simple_drawer := SimpleDrawer.new() +var pixel_perfect_drawers = [ + PixelPerfectDrawer.new(), + PixelPerfectDrawer.new(), + PixelPerfectDrawer.new(), + PixelPerfectDrawer.new() +] +var drawers = [simple_drawer, simple_drawer, simple_drawer, simple_drawer] + class ColorOp: var strength := 1.0 - func process(src: Color, _dst: Color) -> Color: return src class SimpleDrawer: - func set_pixel(image: Image, position: Vector2, color: Color, op : ColorOp) -> void: + func set_pixel(image: Image, position: Vector2, color: Color, op: ColorOp) -> void: var color_old := image.get_pixelv(position) var color_new := op.process(color, color_old) if not color_new.is_equal_approx(color_old): @@ -18,16 +31,14 @@ class SimpleDrawer: class PixelPerfectDrawer: - const neighbours = [Vector2(0, 1), Vector2(1, 0), Vector2(-1, 0), Vector2(0, -1)] - const corners = [Vector2(1, 1), Vector2(-1, -1), Vector2(-1, 1), Vector2(1, -1)] + const NEIGHBOURS = [Vector2(0, 1), Vector2(1, 0), Vector2(-1, 0), Vector2(0, -1)] + const CORNERS = [Vector2(1, 1), Vector2(-1, -1), Vector2(-1, 1), Vector2(1, -1)] var last_pixels = [null, null] - func reset() -> void: last_pixels = [null, null] - - func set_pixel(image: Image, position: Vector2, color: Color, op : ColorOp) -> void: + func set_pixel(image: Image, position: Vector2, color: Color, op: ColorOp) -> void: var color_old = image.get_pixelv(position) last_pixels.push_back([position, color_old]) image.set_pixelv(position, op.process(color, color_old)) @@ -38,21 +49,11 @@ class PixelPerfectDrawer: if corner == null or neighbour == null: return - if position - corner[0] in corners and position - neighbour[0] in neighbours: + if position - corner[0] in CORNERS and position - neighbour[0] in NEIGHBOURS: image.set_pixel(neighbour[0].x, neighbour[0].y, neighbour[1]) last_pixels[0] = corner -var pixel_perfect := false setget set_pixel_perfect -var horizontal_mirror := false -var vertical_mirror := false -var color_op := ColorOp.new() - -var simple_drawer := SimpleDrawer.new() -var pixel_perfect_drawers = [PixelPerfectDrawer.new(), PixelPerfectDrawer.new(), PixelPerfectDrawer.new(), PixelPerfectDrawer.new()] -var drawers = [simple_drawer, simple_drawer, simple_drawer, simple_drawer] - - func reset() -> void: for drawer in pixel_perfect_drawers: drawer.reset() @@ -67,7 +68,7 @@ func set_pixel_perfect(value: bool) -> void: func set_pixel(image: Image, position: Vector2, color: Color, ignore_mirroring := false) -> void: - var project : Project = Global.current_project + var project: Project = Global.current_project drawers[0].set_pixel(image, position, color, color_op) if ignore_mirroring: return diff --git a/src/Classes/Frame.gd b/src/Classes/Frame.gd index db5a97e09..6c73bcc36 100644 --- a/src/Classes/Frame.gd +++ b/src/Classes/Frame.gd @@ -1,9 +1,9 @@ -class_name Frame extends Reference +class_name Frame +extends Reference # A class for frame properties. # A frame is a collection of cels, for each layer. - -var cels : Array # An array of Cels +var cels: Array # An array of Cels var duration := 1.0 diff --git a/src/Classes/ImageEffect.gd b/src/Classes/ImageEffect.gd index 780b4a8bb..3dd8e3a1b 100644 --- a/src/Classes/ImageEffect.gd +++ b/src/Classes/ImageEffect.gd @@ -1,25 +1,27 @@ -class_name ImageEffect extends AcceptDialog +class_name ImageEffect +extends AcceptDialog # Parent class for all image effects # Methods that have "pass" are meant to be replaced by the inherited Scripts +enum { CEL, FRAME, ALL_FRAMES, ALL_PROJECTS } -enum {CEL, FRAME, ALL_FRAMES, ALL_PROJECTS} - -var affect : int = CEL -var current_cel : Image -var current_frame : Image -var preview_image : Image -var preview_texture : ImageTexture -var preview : TextureRect -var selection_checkbox : CheckBox -var affect_option_button : OptionButton +var affect: int = CEL +var current_cel: Image +var current_frame: Image +var preview_image: Image +var preview_texture: ImageTexture +var preview: TextureRect +var selection_checkbox: CheckBox +var affect_option_button: OptionButton func _ready() -> void: set_nodes() current_cel = Image.new() current_frame = Image.new() - current_frame.create(Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8) + current_frame.create( + Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8 + ) preview_image = Image.new() preview_texture = ImageTexture.new() connect("about_to_show", self, "_about_to_show") @@ -33,19 +35,20 @@ func _ready() -> void: func _about_to_show() -> void: Global.canvas.selection.transform_content_confirm() - current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image + var frame: Frame = Global.current_project.frames[Global.current_project.current_frame] + current_cel = frame.cels[Global.current_project.current_layer].image current_frame.resize(Global.current_project.size.x, Global.current_project.size.y) current_frame.fill(Color(0, 0, 0, 0)) - var frame = Global.current_project.frames[Global.current_project.current_frame] Export.blend_layers(current_frame, frame) update_preview() update_transparent_background_size() func _confirmed() -> void: - var project := Global.current_project + var project: Project = Global.current_project if affect == CEL: - if !project.layers[project.current_layer].can_layer_get_drawn(): # No changes if the layer is locked or invisible + # No changes if the layer is locked or invisible + if !project.layers[project.current_layer].can_layer_get_drawn(): return if project.selected_cels.size() == 1: Global.canvas.handle_undo("Draw") @@ -54,8 +57,8 @@ func _confirmed() -> void: else: Global.canvas.handle_undo("Draw", project, -1, -1) for cel_index in project.selected_cels: - var cel : Cel = project.frames[cel_index[0]].cels[cel_index[1]] - var cel_image : Image = cel.image + var cel: Cel = project.frames[cel_index[0]].cels[cel_index[1]] + var cel_image: Image = cel.image commit_action(cel_image) Global.canvas.handle_redo("Draw", project, -1, -1) elif affect == FRAME: @@ -89,7 +92,7 @@ func _confirmed() -> void: Global.canvas.handle_redo("Draw", _project, -1, -1) -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: pass @@ -97,11 +100,11 @@ func set_nodes() -> void: pass -func _on_SelectionCheckBox_toggled(_button_pressed : bool) -> void: +func _on_SelectionCheckBox_toggled(_button_pressed: bool) -> void: update_preview() -func _on_AffectOptionButton_item_selected(index : int) -> void: +func _on_AffectOptionButton_item_selected(index: int) -> void: affect = index update_preview() diff --git a/src/Classes/Layer.gd b/src/Classes/Layer.gd index d604c9877..0b455b376 100644 --- a/src/Classes/Layer.gd +++ b/src/Classes/Layer.gd @@ -1,16 +1,23 @@ -class_name Layer extends Reference +class_name Layer +extends Reference # A class for layer properties. - var name := "" var visible := true var locked := false -var frame_container : HBoxContainer +var frame_container: HBoxContainer var new_cels_linked := false -var linked_cels := [] # Array of Frames +var linked_cels := [] # Array of Frames -func _init(_name := "", _visible := true, _locked := false, _frame_container := HBoxContainer.new(), _new_cels_linked := false, _linked_cels := []) -> void: +func _init( + _name := "", + _visible := true, + _locked := false, + _frame_container := HBoxContainer.new(), + _new_cels_linked := false, + _linked_cels := [] +) -> void: name = _name visible = _visible locked = _locked diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index 7c132f3f0..1e6eb1ee1 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -1,44 +1,46 @@ -class_name Project extends Reference +class_name Project +extends Reference # A class for project properties. var name := "" setget name_changed -var size : Vector2 setget size_changed -var undo_redo : UndoRedo -var tile_mode : int = Global.TileMode.NONE -var tile_mode_rects := [] # Cached to avoid recalculation -var undos := 0 # The number of times we added undo properties +var size: Vector2 setget size_changed +var undo_redo: UndoRedo +var tile_mode: int = Global.TileMode.NONE +var tile_mode_rects := [] # Cached to avoid recalculation +var undos := 0 # The number of times we added undo properties var has_changed := false setget has_changed_changed -var frames := [] setget frames_changed # Array of Frames (that contain Cels) -var layers := [] setget layers_changed # Array of Layers +var frames := [] setget frames_changed # Array of Frames (that contain Cels) +var layers := [] setget layers_changed # Array of Layers var current_frame := 0 setget frame_changed var current_layer := 0 setget layer_changed -var selected_cels := [[0, 0]] # Array of Arrays of 2 integers (frame & layer) +var selected_cels := [[0, 0]] # Array of Arrays of 2 integers (frame & layer) -var animation_tags := [] setget animation_tags_changed # Array of AnimationTags -var guides := [] # Array of Guides -var brushes := [] # Array of Images +var animation_tags := [] setget animation_tags_changed # Array of AnimationTags +var guides := [] # Array of Guides +var brushes := [] # Array of Images var fps := 6.0 var x_symmetry_point var y_symmetry_point -var x_symmetry_axis : SymmetryGuide -var y_symmetry_axis : SymmetryGuide +var x_symmetry_axis: SymmetryGuide +var y_symmetry_axis: SymmetryGuide var selection_bitmap := BitMap.new() -# This is useful for when the selection is outside of the canvas boundaries, on the left and/or above (negative coords) +# This is useful for when the selection is outside of the canvas boundaries, +# on the left and/or above (negative coords) var selection_offset := Vector2.ZERO setget _selection_offset_changed var has_selection := false # For every camera (currently there are 3) -var cameras_rotation := [0.0, 0.0, 0.0] # Array of float -var cameras_zoom := [Vector2(0.15, 0.15), Vector2(0.15, 0.15), Vector2(0.15, 0.15)] # Array of Vector2 -var cameras_offset := [Vector2.ZERO, Vector2.ZERO, Vector2.ZERO] # Array of Vector2 -var cameras_zoom_max := [Vector2.ONE, Vector2.ONE, Vector2.ONE] # Array of Vector2 +var cameras_rotation := [0.0, 0.0, 0.0] # Array of float +var cameras_zoom := [Vector2(0.15, 0.15), Vector2(0.15, 0.15), Vector2(0.15, 0.15)] +var cameras_offset := [Vector2.ZERO, Vector2.ZERO, Vector2.ZERO] +var cameras_zoom_max := [Vector2.ONE, Vector2.ONE, Vector2.ONE] # Export directory path and export file name var directory_path := "" var file_name := "untitled" -var file_format : int = Export.FileFormat.PNG +var file_format: int = Export.FileFormat.PNG var was_exported := false var frame_button_node = preload("res://src/UI/Timeline/FrameButton.tscn") @@ -82,7 +84,9 @@ func _init(_frames := [], _name := tr("untitled"), _size := Vector2(64, 64)) -> if OS.get_name() == "HTML5": directory_path = "user://" else: - directory_path = Global.config_cache.get_value("data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)) + directory_path = Global.config_cache.get_value( + "data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP) + ) func commit_undo() -> void: @@ -109,7 +113,7 @@ func selection_bitmap_changed() -> void: Global.top_menu_container.edit_menu_button.get_popup().set_item_disabled(6, !has_selection) -func _selection_offset_changed(value : Vector2) -> void: +func _selection_offset_changed(value: Vector2) -> void: selection_offset = value Global.canvas.selection.marching_ants_outline.offset = selection_offset Global.canvas.selection.update_on_zoom(Global.camera.zoom.x) @@ -139,7 +143,7 @@ func change_project() -> void: layer_container.line_edit.text = layers[i].name Global.frames_container.add_child(layers[i].frame_container) - for j in range(frames.size()): # Create Cel buttons + for j in range(frames.size()): # Create Cel buttons var cel_button = cel_button_node.instance() cel_button.frame = j cel_button.layer = i @@ -149,23 +153,29 @@ func change_project() -> void: layers[i].frame_container.add_child(cel_button) - for j in range(frames.size()): # Create frame ID labels - var button : Button = frame_button_node.instance() + for j in range(frames.size()): # Create frame ID labels + var button: Button = frame_button_node.instance() button.frame = j button.rect_min_size.x = Global.animation_timeline.cel_size button.text = str(j + 1) if j == current_frame: - button.add_color_override("font_color", Global.control.theme.get_color("Selected Color", "Label")) + button.add_color_override( + "font_color", Global.control.theme.get_color("Selected Color", "Label") + ) Global.frame_ids.add_child(button) - var layer_button = Global.layers_container.get_child(Global.layers_container.get_child_count() - 1 - current_layer) + var layer_button = Global.layers_container.get_child( + Global.layers_container.get_child_count() - 1 - current_layer + ) layer_button.pressed = true Global.current_frame_mark_label.text = "%s/%s" % [str(current_frame + 1), frames.size()] Global.disable_button(Global.remove_frame_button, frames.size() == 1) Global.disable_button(Global.move_left_frame_button, frames.size() == 1 or current_frame == 0) - Global.disable_button(Global.move_right_frame_button, frames.size() == 1 or current_frame == frames.size() - 1) + Global.disable_button( + Global.move_right_frame_button, frames.size() == 1 or current_frame == frames.size() - 1 + ) toggle_layer_buttons_layers() toggle_layer_buttons_current_layer() @@ -191,7 +201,7 @@ func change_project() -> void: Global.canvas.update() Global.canvas.grid.update() - Global.transparent_checker._ready() + Global.transparent_checker.update_rect() Global.animation_timeline.fps_spinbox.value = fps Global.horizontal_ruler.update() Global.vertical_ruler.update() @@ -205,7 +215,9 @@ func change_project() -> void: if save_path != "": Global.open_sprites_dialog.current_path = save_path Global.save_sprites_dialog.current_path = save_path - Global.top_menu_container.file_menu.set_item_text(4, tr("Save") + " %s" % save_path.get_file()) + Global.top_menu_container.file_menu.set_item_text( + 4, tr("Save") + " %s" % save_path.get_file() + ) else: Global.top_menu_container.file_menu.set_item_text(4, tr("Save")) @@ -217,7 +229,9 @@ func change_project() -> void: if !was_exported: Global.top_menu_container.file_menu.set_item_text(6, tr("Export")) else: - Global.top_menu_container.file_menu.set_item_text(6, tr("Export") + " %s" % (file_name + Export.file_format_string(file_format))) + Global.top_menu_container.file_menu.set_item_text( + 6, tr("Export") + " %s" % (file_name + Export.file_format_string(file_format)) + ) for j in Global.TileMode.values(): Global.top_menu_container.tile_mode_submenu.set_item_checked(j, j == tile_mode) @@ -234,12 +248,20 @@ func change_project() -> void: for camera in Global.cameras: camera.zoom_max = cameras_zoom_max[i] if camera == Global.camera_preview: - Global.preview_zoom_slider.disconnect("value_changed", Global.canvas_preview_container, "_on_PreviewZoomSlider_value_changed") + Global.preview_zoom_slider.disconnect( + "value_changed", + Global.canvas_preview_container, + "_on_PreviewZoomSlider_value_changed" + ) Global.preview_zoom_slider.min_value = -camera.zoom_max.x - Global.preview_zoom_slider.connect("value_changed", Global.canvas_preview_container, "_on_PreviewZoomSlider_value_changed") + Global.preview_zoom_slider.connect( + "value_changed", + Global.canvas_preview_container, + "_on_PreviewZoomSlider_value_changed" + ) if camera == Global.camera: - Global.zoom_level_spinbox.min_value = 100.0/camera.zoom_max.x + Global.zoom_level_spinbox.min_value = 100.0 / camera.zoom_max.x camera.rotation = cameras_rotation[i] camera.zoom = cameras_zoom[i] camera.offset = cameras_offset[i] @@ -255,22 +277,26 @@ func serialize() -> Dictionary: for cel in layer.linked_cels: linked_cels.append(frames.find(cel)) - layer_data.append({ - "name" : layer.name, - "visible" : layer.visible, - "locked" : layer.locked, - "new_cels_linked" : layer.new_cels_linked, - "linked_cels" : linked_cels, - }) + layer_data.append( + { + "name": layer.name, + "visible": layer.visible, + "locked": layer.locked, + "new_cels_linked": layer.new_cels_linked, + "linked_cels": linked_cels, + } + ) var tag_data := [] for tag in animation_tags: - tag_data.append({ - "name" : tag.name, - "color" : tag.color.to_html(), - "from" : tag.from, - "to" : tag.to, - }) + tag_data.append( + { + "name": tag.name, + "color": tag.color.to_html(), + "from": tag.from, + "to": tag.to, + } + ) var guide_data := [] for guide in guides: @@ -282,49 +308,45 @@ func serialize() -> Dictionary: if guide.type == Guide.Types.HORIZONTAL: coords = guide.points[0].y - guide_data.append({"type" : guide.type, "pos" : coords}) + guide_data.append({"type": guide.type, "pos": coords}) var frame_data := [] for frame in frames: var cel_data := [] for cel in frame.cels: - cel_data.append({ - "opacity" : cel.opacity, -# "image_data" : cel.image.get_data() - }) - frame_data.append({ - "cels" : cel_data, - "duration" : frame.duration - }) + cel_data.append( + { + "opacity": cel.opacity, + # "image_data" : cel.image.get_data() + } + ) + frame_data.append({"cels": cel_data, "duration": frame.duration}) var brush_data := [] for brush in brushes: - brush_data.append({ - "size_x" : brush.get_size().x, - "size_y" : brush.get_size().y - }) + brush_data.append({"size_x": brush.get_size().x, "size_y": brush.get_size().y}) var project_data := { - "pixelorama_version" : Global.current_version, - "name" : name, - "size_x" : size.x, - "size_y" : size.y, - "save_path" : OpenSave.current_save_paths[Global.projects.find(self)], - "layers" : layer_data, - "tags" : tag_data, - "guides" : guide_data, - "symmetry_points" : [x_symmetry_point, y_symmetry_point], - "frames" : frame_data, - "brushes" : brush_data, - "export_directory_path" : directory_path, - "export_file_name" : file_name, - "export_file_format" : file_format, - "fps" : fps + "pixelorama_version": Global.current_version, + "name": name, + "size_x": size.x, + "size_y": size.y, + "save_path": OpenSave.current_save_paths[Global.projects.find(self)], + "layers": layer_data, + "tags": tag_data, + "guides": guide_data, + "symmetry_points": [x_symmetry_point, y_symmetry_point], + "frames": frame_data, + "brushes": brush_data, + "export_directory_path": directory_path, + "export_file_name": file_name, + "export_file_format": file_format, + "fps": fps } return project_data -func deserialize(dict : Dictionary) -> void: +func deserialize(dict: Dictionary) -> void: if dict.has("name"): name = dict.name if dict.has("size_x") and dict.has("size_y"): @@ -350,14 +372,22 @@ func deserialize(dict : Dictionary) -> void: frame_i += 1 if dict.has("layers"): - var layer_i := 0 + var layer_i := 0 for saved_layer in dict.layers: var linked_cels := [] for linked_cel_number in saved_layer.linked_cels: linked_cels.append(frames[linked_cel_number]) - frames[linked_cel_number].cels[layer_i].image = linked_cels[0].cels[layer_i].image - frames[linked_cel_number].cels[layer_i].image_texture = linked_cels[0].cels[layer_i].image_texture - var layer := Layer.new(saved_layer.name, saved_layer.visible, saved_layer.locked, HBoxContainer.new(), saved_layer.new_cels_linked, linked_cels) + var linked_cel: Cel = frames[linked_cel_number].cels[layer_i] + linked_cel.image = linked_cels[0].cels[layer_i].image + linked_cel.image_texture = linked_cels[0].cels[layer_i].image_texture + var layer := Layer.new( + saved_layer.name, + saved_layer.visible, + saved_layer.locked, + HBoxContainer.new(), + saved_layer.new_cels_linked, + linked_cels + ) layers.append(layer) layer_i += 1 if dict.has("tags"): @@ -394,17 +424,17 @@ func deserialize(dict : Dictionary) -> void: fps = dict.fps -func name_changed(value : String) -> void: +func name_changed(value: String) -> void: name = value Global.tabs.set_tab_title(Global.tabs.current_tab, name) -func size_changed(value : Vector2) -> void: +func size_changed(value: Vector2) -> void: size = value update_tile_mode_rects() -func frames_changed(value : Array) -> void: +func frames_changed(value: Array) -> void: Global.canvas.selection.transform_content_confirm() frames = value selected_cels.clear() @@ -418,7 +448,7 @@ func frames_changed(value : Array) -> void: Global.frames_container.add_child(layers[i].frame_container) for j in range(frames.size()): - var button : Button = frame_button_node.instance() + var button: Button = frame_button_node.instance() button.frame = j button.rect_min_size.x = Global.animation_timeline.cel_size button.text = str(j + 1) @@ -435,7 +465,7 @@ func frames_changed(value : Array) -> void: set_timeline_first_and_last_frames() -func layers_changed(value : Array) -> void: +func layers_changed(value: Array) -> void: layers = value if Global.layers_changed_skip: Global.layers_changed_skip = false @@ -467,9 +497,11 @@ func layers_changed(value : Array) -> void: layers[i].frame_container.add_child(cel_button) - var layer_button = Global.layers_container.get_child(Global.layers_container.get_child_count() - 1 - current_layer) + var layer_button = Global.layers_container.get_child( + Global.layers_container.get_child_count() - 1 - current_layer + ) layer_button.pressed = true - self.current_frame = current_frame # Call frame_changed to update UI + self.current_frame = current_frame # Call frame_changed to update UI toggle_layer_buttons_layers() @@ -481,17 +513,20 @@ func remove_cel_buttons() -> void: Global.frames_container.remove_child(container) -func frame_changed(value : int) -> void: +func frame_changed(value: int) -> void: Global.canvas.selection.transform_content_confirm() current_frame = value Global.current_frame_mark_label.text = "%s/%s" % [str(current_frame + 1), frames.size()] for i in frames.size(): var text_color := Color.white - if Global.theme_type == Global.ThemeTypes.CARAMEL || Global.theme_type == Global.ThemeTypes.LIGHT: + if ( + Global.theme_type == Global.ThemeTypes.CARAMEL + || Global.theme_type == Global.ThemeTypes.LIGHT + ): text_color = Color.black Global.frame_ids.get_child(i).add_color_override("font_color", text_color) - for layer in layers: # De-select all the other frames + for layer in layers: # De-select all the other frames if i < layer.frame_container.get_child_count(): layer.frame_container.get_child(i).pressed = false @@ -499,41 +534,49 @@ func frame_changed(value : int) -> void: selected_cels.append([current_frame, current_layer]) # Select the new frame for cel in selected_cels: - var _current_frame : int = cel[0] - var _current_layer : int = cel[1] - if _current_frame < Global.frame_ids.get_child_count(): - Global.frame_ids.get_child(_current_frame).add_color_override("font_color", Global.control.theme.get_color("Selected Color", "Label")) + var current_frame_tmp: int = cel[0] + var current_layer_tmp: int = cel[1] + if current_frame_tmp < Global.frame_ids.get_child_count(): + Global.frame_ids.get_child(current_frame_tmp).add_color_override( + "font_color", Global.control.theme.get_color("Selected Color", "Label") + ) if layers: - if _current_frame < layers[_current_layer].frame_container.get_child_count(): - layers[_current_layer].frame_container.get_child(_current_frame).pressed = true + if current_frame_tmp < layers[current_layer_tmp].frame_container.get_child_count(): + var fbutton = layers[current_layer_tmp].frame_container.get_child(current_frame_tmp) + fbutton.pressed = true Global.disable_button(Global.remove_frame_button, frames.size() == 1) Global.disable_button(Global.move_left_frame_button, frames.size() == 1 or current_frame == 0) - Global.disable_button(Global.move_right_frame_button, frames.size() == 1 or current_frame == frames.size() - 1) + Global.disable_button( + Global.move_right_frame_button, frames.size() == 1 or current_frame == frames.size() - 1 + ) if current_frame < frames.size(): - Global.layer_opacity_slider.value = frames[current_frame].cels[current_layer].opacity * 100 - Global.layer_opacity_spinbox.value = frames[current_frame].cels[current_layer].opacity * 100 + var cel_opacity: float = frames[current_frame].cels[current_layer].opacity + Global.layer_opacity_slider.value = cel_opacity * 100 + Global.layer_opacity_spinbox.value = cel_opacity * 100 Global.canvas.update() - Global.transparent_checker._ready() # To update the rect size + Global.transparent_checker.update_rect() -func layer_changed(value : int) -> void: +func layer_changed(value: int) -> void: Global.canvas.selection.transform_content_confirm() current_layer = value toggle_layer_buttons_current_layer() yield(Global.get_tree().create_timer(0.01), "timeout") - self.current_frame = current_frame # Call frame_changed to update UI + self.current_frame = current_frame # Call frame_changed to update UI for layer_button in Global.layers_container.get_children(): layer_button.pressed = false for cel in selected_cels: - var _current_layer : int = cel[1] - if _current_layer < Global.layers_container.get_child_count(): - var layer_button = Global.layers_container.get_child(Global.layers_container.get_child_count() - 1 - _current_layer) + var current_layer_tmp: int = cel[1] + if current_layer_tmp < Global.layers_container.get_child_count(): + var layer_button = Global.layers_container.get_child( + Global.layers_container.get_child_count() - 1 - current_layer_tmp + ) layer_button.pressed = true @@ -573,26 +616,28 @@ func toggle_layer_buttons_current_layer() -> void: Global.disable_button(Global.remove_layer_button, false) -func animation_tags_changed(value : Array) -> void: +func animation_tags_changed(value: Array) -> void: animation_tags = value for child in Global.tag_container.get_children(): child.queue_free() for tag in animation_tags: var tag_base_size = Global.animation_timeline.cel_size + 4 - var tag_c : Container = animation_tag_node.instance() + var tag_c: Container = animation_tag_node.instance() Global.tag_container.add_child(tag_c) tag_c.tag = tag - var tag_position : int = Global.tag_container.get_child_count() - 1 + var tag_position: int = Global.tag_container.get_child_count() - 1 Global.tag_container.move_child(tag_c, tag_position) tag_c.get_node("Label").text = tag.name tag_c.get_node("Label").modulate = tag.color tag_c.get_node("Line2D").default_color = tag.color - tag_c.rect_position.x = (tag.from - 1) * tag_base_size + 1 # Added 1 to answer to get starting position of next cel - var tag_size : int = tag.to - tag.from - tag_c.rect_min_size.x = (tag_size + 1) * tag_base_size - 4 # We dont need the 4 pixels at the end of last cel - tag_c.rect_position.y = 1 # To make top line of tag visible + # Added 1 to answer to get starting position of next cel + tag_c.rect_position.x = (tag.from - 1) * tag_base_size + 1 + var tag_size: int = tag.to - tag.from + # We dont need the 4 pixels at the end of last cel + tag_c.rect_min_size.x = (tag_size + 1) * tag_base_size - 4 + tag_c.rect_position.y = 1 # To make top line of tag visible tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0) tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32) @@ -612,7 +657,7 @@ func set_timeline_first_and_last_frames() -> void: Global.animation_timeline.last_frame = min(frames.size() - 1, tag.to - 1) -func has_changed_changed(value : bool) -> void: +func has_changed_changed(value: bool) -> void: has_changed = value if value: Global.tabs.set_tab_title(Global.tabs.current_tab, name + "(*)") @@ -633,10 +678,19 @@ func update_tile_mode_rects() -> void: func is_empty() -> bool: - return frames.size() == 1 and layers.size() == 1 and frames[0].cels[0].image.is_invisible() and animation_tags.size() == 0 + return ( + frames.size() == 1 + and layers.size() == 1 + and frames[0].cels[0].image.is_invisible() + and animation_tags.size() == 0 + ) -func can_pixel_get_drawn(pixel : Vector2, bitmap : BitMap = selection_bitmap, selection_position : Vector2 = Global.canvas.selection.big_bounding_rectangle.position) -> bool: +func can_pixel_get_drawn( + pixel: Vector2, + bitmap: BitMap = selection_bitmap, + selection_position: Vector2 = Global.canvas.selection.big_bounding_rectangle.position +) -> bool: if pixel.x < 0 or pixel.y < 0 or pixel.x >= size.x or pixel.y >= size.y: return false @@ -650,15 +704,16 @@ func can_pixel_get_drawn(pixel : Vector2, bitmap : BitMap = selection_bitmap, se return true -func invert_bitmap(bitmap : BitMap) -> void: +func invert_bitmap(bitmap: BitMap) -> void: for x in bitmap.get_size().x: for y in bitmap.get_size().y: var pos := Vector2(x, y) bitmap.set_bit(pos, !bitmap.get_bit(pos)) -# Unexposed BitMap class function - https://github.com/godotengine/godot/blob/master/scene/resources/bit_map.cpp#L605 -func resize_bitmap(bitmap : BitMap, new_size : Vector2) -> BitMap: +# Unexposed BitMap class function +# https://github.com/godotengine/godot/blob/master/scene/resources/bit_map.cpp#L605 +func resize_bitmap(bitmap: BitMap, new_size: Vector2) -> BitMap: if new_size == bitmap.get_size(): return bitmap var new_bitmap := BitMap.new() @@ -672,8 +727,9 @@ func resize_bitmap(bitmap : BitMap, new_size : Vector2) -> BitMap: return new_bitmap -# Unexposed BitMap class function - https://github.com/godotengine/godot/blob/master/scene/resources/bit_map.cpp#L622 -func bitmap_to_image(bitmap : BitMap, square := true) -> Image: +# Unexposed BitMap class function +# https://github.com/godotengine/godot/blob/master/scene/resources/bit_map.cpp#L622 +func bitmap_to_image(bitmap: BitMap, square := true) -> Image: var image := Image.new() var width := bitmap.get_size().x var height := bitmap.get_size().y @@ -692,8 +748,9 @@ func bitmap_to_image(bitmap : BitMap, square := true) -> Image: return image -# Algorithm taken from Image.get_used_rect() - https://github.com/godotengine/godot/blob/master/core/io/image.cpp -func get_selection_rectangle(bitmap : BitMap = selection_bitmap) -> Rect2: +# Algorithm taken from Image.get_used_rect() +# https://github.com/godotengine/godot/blob/master/core/io/image.cpp +func get_selection_rectangle(bitmap: BitMap = selection_bitmap) -> Rect2: if bitmap.get_true_bit_count() == 0: return Rect2() @@ -720,12 +777,12 @@ func get_selection_rectangle(bitmap : BitMap = selection_bitmap) -> Rect2: return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1) -func move_bitmap_values(bitmap : BitMap, move_offset := true) -> void: +func move_bitmap_values(bitmap: BitMap, move_offset := true) -> void: var selection_node = Global.canvas.selection - var selection_position : Vector2 = selection_node.big_bounding_rectangle.position - var selection_end : Vector2 = selection_node.big_bounding_rectangle.end + var selection_position: Vector2 = selection_node.big_bounding_rectangle.position + var selection_end: Vector2 = selection_node.big_bounding_rectangle.end - var image : Image = bitmap_to_image(bitmap) + var image: Image = bitmap_to_image(bitmap) var selection_rect := image.get_used_rect() var smaller_image := image.get_rect(selection_rect) image.fill(Color(0)) @@ -762,15 +819,15 @@ func move_bitmap_values(bitmap : BitMap, move_offset := true) -> void: bitmap.create_from_image_alpha(image) -func resize_bitmap_values(bitmap : BitMap, new_size : Vector2, flip_x : bool, flip_y : bool) -> BitMap: +func resize_bitmap_values(bitmap: BitMap, new_size: Vector2, flip_x: bool, flip_y: bool) -> BitMap: var selection_node = Global.canvas.selection - var selection_position : Vector2 = selection_node.big_bounding_rectangle.position + var selection_position: Vector2 = selection_node.big_bounding_rectangle.position var dst := selection_position var new_bitmap_size := size new_bitmap_size.x = max(size.x, abs(selection_position.x) + new_size.x) new_bitmap_size.y = max(size.y, abs(selection_position.y) + new_size.y) var new_bitmap := BitMap.new() - var image : Image = bitmap_to_image(bitmap) + var image: Image = bitmap_to_image(bitmap) var selection_rect := image.get_used_rect() var smaller_image := image.get_rect(selection_rect) if selection_position.x <= 0: diff --git a/src/Classes/ShaderImageEffect.gd b/src/Classes/ShaderImageEffect.gd index 6c02b4442..8ed8630a0 100644 --- a/src/Classes/ShaderImageEffect.gd +++ b/src/Classes/ShaderImageEffect.gd @@ -1,8 +1,15 @@ -class_name ShaderImageEffect extends Reference +class_name ShaderImageEffect +extends Reference # Helper class to generate image effects using shaders signal done -func generate_image(_img : Image,_shaderpath: String, _params : Dictionary , size : Vector2 = Global.current_project.size): + +func generate_image( + _img: Image, + _shaderpath: String, + _params: Dictionary, + size: Vector2 = Global.current_project.size +): var shader = load(_shaderpath) _img.unlock() var viewport_texture := Image.new() diff --git a/src/Main.gd b/src/Main.gd index 3ab8ad0cb..f2f569108 100644 --- a/src/Main.gd +++ b/src/Main.gd @@ -1,6 +1,5 @@ extends Control - var opensprite_file_selected := false var redone := false var is_quitting_on_save := false @@ -9,22 +8,30 @@ var alternate_transparent_background := ColorRect.new() var cursor_image = preload("res://assets/graphics/cursor.png") onready var ui := $MenuAndUI/UI -onready var tools_and_canvas : HSplitContainer = $MenuAndUI/UI/ToolsAndCanvas -onready var tallscreen_hsplit_container : HSplitContainer = $MenuAndUI/UI/ToolsAndCanvas/CanvasAndTimeline/TallscreenHSplitContainer -onready var bottom_panel : VSplitContainer = tallscreen_hsplit_container.get_node("BottomPanel") +onready var tools_and_canvas: HSplitContainer = $MenuAndUI/UI/ToolsAndCanvas +onready var tallscreen_hsplit: HSplitContainer = tools_and_canvas.get_node( + "CanvasAndTimeline/TallscreenHSplitContainer" +) +onready var bottom_panel: VSplitContainer = tallscreen_hsplit.get_node("BottomPanel") onready var right_panel := $MenuAndUI/UI/RightPanel -onready var tool_and_palette_vsplit := $MenuAndUI/UI/RightPanel/MarginContainer/PreviewAndPalettes/ToolAndPaletteVSplit -onready var color_and_tool_options := $MenuAndUI/UI/RightPanel/MarginContainer/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions -onready var canvas_preview_container := $MenuAndUI/UI/RightPanel/MarginContainer/PreviewAndPalettes/CanvasPreviewContainer +onready var canvas_preview_container := right_panel.get_node( + "MarginContainer/PreviewAndPalettes/CanvasPreviewContainer" +) +onready var tool_and_palette_vsplit := right_panel.get_node( + "MarginContainer/PreviewAndPalettes/ToolAndPaletteVSplit" +) +onready var color_and_tool_options := tool_and_palette_vsplit.get_node("ColorAndToolOptions") +onready var scroll_container := tool_and_palette_vsplit.get_node( + "ColorAndToolOptions/ScrollContainer" +) onready var tool_panel := $MenuAndUI/UI/ToolsAndCanvas/ToolPanel -onready var scroll_container := $MenuAndUI/UI/RightPanel/MarginContainer/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer -onready var quit_dialog : ConfirmationDialog = find_node("QuitDialog") +onready var quit_dialog: ConfirmationDialog = find_node("QuitDialog") func _ready() -> void: randomize() add_child(alternate_transparent_background) - move_child(alternate_transparent_background,0) + move_child(alternate_transparent_background, 0) alternate_transparent_background.visible = false alternate_transparent_background.anchor_left = ANCHOR_BEGIN alternate_transparent_background.anchor_top = ANCHOR_BEGIN @@ -50,8 +57,12 @@ func _ready() -> void: Global.quit_and_save_dialog.add_button("Save & Exit", false, "Save") Global.quit_and_save_dialog.get_ok().text = "Exit without saving" - Global.open_sprites_dialog.current_dir = Global.config_cache.get_value("data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)) - Global.save_sprites_dialog.current_dir = Global.config_cache.get_value("data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)) + Global.open_sprites_dialog.current_dir = Global.config_cache.get_value( + "data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP) + ) + Global.save_sprites_dialog.current_dir = Global.config_cache.get_value( + "data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP) + ) # FIXME: OS.get_system_dir does not grab the correct directory for Ubuntu Touch. # Additionally, AppArmor policies prevent the app from writing to the /home @@ -90,33 +101,44 @@ func _ready() -> void: func handle_resize() -> void: - var aspect_ratio = get_viewport_rect().size.x/(0.00001 if get_viewport_rect().size.y == 0 else get_viewport_rect().size.y) - if ( (aspect_ratio <= 3.0/4.0 and Global.panel_layout != Global.PanelLayout.WIDESCREEN) - or Global.panel_layout == Global.PanelLayout.TALLSCREEN): + var aspect_ratio = ( + get_viewport_rect().size.x + / (0.00001 if get_viewport_rect().size.y == 0 else get_viewport_rect().size.y) + ) + if ( + (aspect_ratio <= 3.0 / 4.0 and Global.panel_layout != Global.PanelLayout.WIDESCREEN) + or Global.panel_layout == Global.PanelLayout.TALLSCREEN + ): change_ui_layout("tallscreen") else: change_ui_layout("widescreen") -func change_ui_layout(mode : String) -> void: - var colorpicker_is_switched = true if tool_and_palette_vsplit.has_node("ScrollContainer") else false +func change_ui_layout(mode: String) -> void: + var colorpicker_is_switched = ( + true + if tool_and_palette_vsplit.has_node("ScrollContainer") + else false + ) if mode == "tallscreen" and not tallscreen_is_active: tallscreen_is_active = true # changing visibility and re-parenting of nodes for tall screen if !Global.top_menu_container.zen_mode: - tallscreen_hsplit_container.visible = true - tallscreen_hsplit_container.split_offset = tools_and_canvas.split_offset - reparent_node_to(Global.animation_timeline, tallscreen_hsplit_container.get_node("BottomPanel"), 0) + tallscreen_hsplit.visible = true + tallscreen_hsplit.split_offset = tools_and_canvas.split_offset + reparent_node_to(Global.animation_timeline, tallscreen_hsplit.get_node("BottomPanel"), 0) reparent_node_to(right_panel, bottom_panel, 0) right_panel.rect_min_size.y = 322 reparent_node_to(canvas_preview_container, tool_and_palette_vsplit, 1) tool_and_palette_vsplit = replace_node_with(tool_and_palette_vsplit, HBoxContainer.new()) tool_and_palette_vsplit.set("custom_constants/separation", 8) color_and_tool_options.rect_min_size.x = 280 - reparent_node_to(tool_panel, tallscreen_hsplit_container, 0) + reparent_node_to(tool_panel, tallscreen_hsplit, 0) - var right_panel_margin : MarginContainer = right_panel.find_node("MarginContainer", true, false) + var right_panel_margin: MarginContainer = right_panel.find_node( + "MarginContainer", true, false + ) right_panel_margin.set("custom_constants/margin_top", 8) right_panel_margin.set("custom_constants/margin_left", 0) right_panel_margin.set("custom_constants/margin_right", 0) @@ -125,9 +147,11 @@ func change_ui_layout(mode : String) -> void: elif mode == "widescreen" and tallscreen_is_active: tallscreen_is_active = false # Reparenting and hiding nodes to adjust wide-screen - reparent_node_to(Global.animation_timeline, ui.get_node("ToolsAndCanvas/CanvasAndTimeline"), 1) - tallscreen_hsplit_container.visible = false - tools_and_canvas.split_offset = tallscreen_hsplit_container.split_offset + reparent_node_to( + Global.animation_timeline, ui.get_node("ToolsAndCanvas/CanvasAndTimeline"), 1 + ) + tallscreen_hsplit.visible = false + tools_and_canvas.split_offset = tallscreen_hsplit.split_offset reparent_node_to(right_panel, ui, -1) right_panel.rect_min_size.y = 0 reparent_node_to(canvas_preview_container, right_panel.find_node("PreviewAndPalettes"), 0) @@ -136,7 +160,9 @@ func change_ui_layout(mode : String) -> void: canvas_preview_container.visible = true reparent_node_to(tool_panel, ui.find_node("ToolsAndCanvas"), 0) - var right_panel_margin : MarginContainer = right_panel.find_node("MarginContainer", true, false) + var right_panel_margin: MarginContainer = right_panel.find_node( + "MarginContainer", true, false + ) right_panel_margin.set("custom_constants/margin_top", 0) right_panel_margin.set("custom_constants/margin_left", 8) right_panel_margin.set("custom_constants/margin_right", 8) @@ -157,14 +183,19 @@ func change_ui_layout(mode : String) -> void: scroll_container.rect_min_size = Vector2(0, 0) color_and_tool_options.set("custom_constants/separation", 8) if mode == "widescreen": - reparent_node_to(canvas_preview_container, right_panel.find_node("PreviewAndPalettes", true, false), 0) + reparent_node_to( + canvas_preview_container, + right_panel.find_node("PreviewAndPalettes", true, false), + 0 + ) else: reparent_node_to(canvas_preview_container, tool_and_palette_vsplit, 1) # helper function (change_ui_layout) -# warning: this doesn't really copy any sort of attributes, except a few that were needed in my particular case -func replace_node_with(old : Node, new : Node) -> Node: +# warning: this doesn't really copy any sort of attributes, except a few that +# were needed in my particular case +func replace_node_with(old: Node, new: Node) -> Node: var tempname = old.name old.name = "old" new.name = tempname @@ -183,7 +214,7 @@ func replace_node_with(old : Node, new : Node) -> Node: # helper function (change_ui_layout) -func reparent_node_to(node : Node, dest : Node, pos : int) -> bool: +func reparent_node_to(node: Node, dest: Node, pos: int) -> bool: if dest is Node and node is Node: node.get_parent().remove_child(node) dest.add_child(node) @@ -195,7 +226,7 @@ func reparent_node_to(node : Node, dest : Node, pos : int) -> bool: return false -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: Global.left_cursor.position = get_global_mouse_position() + Vector2(-32, 32) Global.right_cursor.position = get_global_mouse_position() + Vector2(32, 32) @@ -203,23 +234,25 @@ func _input(event : InputEvent) -> void: if get_focus_owner() is LineEdit: get_focus_owner().release_focus() - # The section of code below is reserved for Undo and Redo! Do not place code for Input below, but above. - if !event.is_echo(): # Checks if the action is pressed down + # The section of code below is reserved for Undo and Redo! + # Do not place code for Input below, but above. + if !event.is_echo(): # Checks if the action is pressed down if event.is_action_pressed("redo_secondary"): # Done, so that "redo_secondary" hasn't a slight delay before it starts. # The "redo" and "undo" action don't have a slight delay, - # because they get called as an accelerator once pressed (TopMenuContainer.gd / Line 152). + # because they get called as an accelerator once pressed (TopMenuContainer.gd, Line 152) Global.current_project.commit_redo() return - if event.is_action("redo"): # Ctrl + Y + if event.is_action("redo"): # Ctrl + Y Global.current_project.commit_redo() - if event.is_action("redo_secondary"): # Shift + Ctrl + Z + if event.is_action("redo_secondary"): # Shift + Ctrl + Z Global.current_project.commit_redo() - if event.is_action("undo") and !event.shift: # Ctrl + Z and check if shift isn't pressed - Global.current_project.commit_undo() # so "undo" isn't accidentaly triggered while using "redo_secondary" + if event.is_action("undo") and !event.shift: # Ctrl + Z and check if shift isn't pressed + # so "undo" isn't accidentaly triggered while using "redo_secondary" + Global.current_project.commit_undo() func setup_application_window_size() -> void: @@ -228,8 +261,12 @@ func setup_application_window_size() -> void: # Set a minimum window size to prevent UI elements from collapsing on each other. OS.min_window_size = Vector2(1024, 576) - get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_DISABLED, - SceneTree.STRETCH_ASPECT_IGNORE, Vector2(1024,576), Global.shrink) + get_tree().set_screen_stretch( + SceneTree.STRETCH_MODE_DISABLED, + SceneTree.STRETCH_ASPECT_IGNORE, + Vector2(1024, 576), + Global.shrink + ) # Restore the window position/size if values are present in the configuration cache if Global.config_cache.has_section_key("window", "screen"): @@ -253,7 +290,7 @@ func show_splash_screen() -> void: # Wait for the window to adjust itself, so the popup is correctly centered yield(get_tree(), "screen_resized") - $Dialogs/SplashDialog.popup_centered() # Splash screen + $Dialogs/SplashDialog.popup_centered() # Splash screen modulate = Color(0.5, 0.5, 0.5) else: Global.can_draw = true @@ -261,7 +298,7 @@ func show_splash_screen() -> void: func handle_backup() -> void: # If backup file exists then Pixelorama was not closed properly (probably crashed) - reopen backup - var backup_confirmation : ConfirmationDialog = $Dialogs/BackupConfirmation + var backup_confirmation: ConfirmationDialog = $Dialogs/BackupConfirmation backup_confirmation.get_cancel().text = tr("Delete") if Global.config_cache.has_section("backups"): var project_paths = Global.config_cache.get_section_keys("backups") @@ -272,8 +309,12 @@ func handle_backup() -> void: backup_paths.append(Global.config_cache.get_value("backups", p_path)) # Temporatily stop autosave until user confirms backup OpenSave.autosave_timer.stop() - backup_confirmation.connect("confirmed", self, "_on_BackupConfirmation_confirmed", [project_paths, backup_paths]) - backup_confirmation.get_cancel().connect("pressed", self, "_on_BackupConfirmation_delete", [project_paths, backup_paths]) + backup_confirmation.connect( + "confirmed", self, "_on_BackupConfirmation_confirmed", [project_paths, backup_paths] + ) + backup_confirmation.get_cancel().connect( + "pressed", self, "_on_BackupConfirmation_delete", [project_paths, backup_paths] + ) backup_confirmation.popup_centered() Global.can_draw = false modulate = Color(0.5, 0.5, 0.5) @@ -285,28 +326,33 @@ func handle_backup() -> void: load_last_project() -func _notification(what : int) -> void: +func _notification(what: int) -> void: match what: - MainLoop.NOTIFICATION_WM_QUIT_REQUEST: # Handle exit + MainLoop.NOTIFICATION_WM_QUIT_REQUEST: # Handle exit show_quit_dialog() - MainLoop.NOTIFICATION_WM_FOCUS_OUT: # Called when another program is currently focused + MainLoop.NOTIFICATION_WM_FOCUS_OUT: # Called when another program is currently focused Global.has_focus = false if Global.fps_limit_focus: - Engine.set_target_fps(Global.idle_fps) # then set the fps to the idle fps (by default 1) to facilitate the cpu - MainLoop.NOTIFICATION_WM_MOUSE_ENTER: # Opposite of the above + # then set the fps to the idle fps (by default 1) to facilitate the CPU + Engine.set_target_fps(Global.idle_fps) + MainLoop.NOTIFICATION_WM_MOUSE_ENTER: # Opposite of the above if Global.fps_limit_focus: - Engine.set_target_fps(Global.fps_limit) # 0 stands for maximum fps - MainLoop.NOTIFICATION_WM_MOUSE_EXIT: # if the mouse exits the window and another application has the focus set the fps to the idle fps + Engine.set_target_fps(Global.fps_limit) # 0 stands for maximum fps + # If the mouse exits the window and another application has the focus, + # set the fps to the idle fps + MainLoop.NOTIFICATION_WM_MOUSE_EXIT: if !OS.is_window_focused() and Global.fps_limit_focus: Engine.set_target_fps(Global.idle_fps) MainLoop.NOTIFICATION_WM_FOCUS_IN: var mouse_pos := get_global_mouse_position() - var viewport_rect := Rect2(Global.main_viewport.rect_global_position, Global.main_viewport.rect_size) + var viewport_rect := Rect2( + Global.main_viewport.rect_global_position, Global.main_viewport.rect_size + ) if viewport_rect.has_point(mouse_pos): Global.has_focus = true -func _on_files_dropped(_files : PoolStringArray, _screen : int) -> void: +func _on_files_dropped(_files: PoolStringArray, _screen: int) -> void: OpenSave.handle_loading_files(_files) var splash_dialog = Global.control.get_node("Dialogs/SplashDialog") if splash_dialog.visible: @@ -321,7 +367,7 @@ func load_last_project() -> void: # Check if file still exists on disk var file_path = Global.config_cache.get_value("preferences", "last_project_path") var file_check := File.new() - if file_check.file_exists(file_path): # If yes then load the file + if file_check.file_exists(file_path): # If yes then load the file OpenSave.open_pxo_file(file_path) # Sync file dialogs Global.save_sprites_dialog.current_dir = file_path.get_base_dir() @@ -334,13 +380,13 @@ func load_last_project() -> void: Global.dialog_open(true) -func load_recent_project_file(path : String) -> void: +func load_recent_project_file(path: String) -> void: if OS.get_name() == "HTML5": return # Check if file still exists on disk var file_check := File.new() - if file_check.file_exists(path): # If yes then load the file + if file_check.file_exists(path): # If yes then load the file OpenSave.handle_loading_files([path]) # Sync file dialogs Global.save_sprites_dialog.current_dir = path.get_base_dir() @@ -353,14 +399,18 @@ func load_recent_project_file(path : String) -> void: Global.dialog_open(true) -func _on_OpenSprite_file_selected(path : String) -> void: +func _on_OpenSprite_file_selected(path: String) -> void: OpenSave.handle_loading_files([path]) Global.save_sprites_dialog.current_dir = path.get_base_dir() Global.config_cache.set_value("data", "current_dir", path.get_base_dir()) -func _on_SaveSprite_file_selected(path : String) -> void: - var zstd = Global.save_sprites_dialog.get_vbox().get_node("ZSTDCompression").pressed +func _on_SaveSprite_file_selected(path: String) -> void: + save_project(path) + + +func save_project(path: String) -> void: + var zstd: bool = Global.save_sprites_dialog.get_vbox().get_node("ZSTDCompression").pressed OpenSave.save_pxo_file(path, false, zstd) Global.open_sprites_dialog.current_dir = path.get_base_dir() Global.config_cache.set_value("data", "current_dir", path.get_base_dir()) @@ -370,7 +420,9 @@ func _on_SaveSprite_file_selected(path : String) -> void: func _on_SaveSpriteHTML5_confirmed() -> void: - var file_name = Global.save_sprites_html5_dialog.get_node("FileNameContainer/FileNameLineEdit").text + var file_name = Global.save_sprites_html5_dialog.get_node( + "FileNameContainer/FileNameLineEdit" + ).text file_name += ".pxo" var path = "user://".plus_file(file_name) OpenSave.save_pxo_file(path, false, false) @@ -395,7 +447,7 @@ func show_quit_dialog() -> void: Global.dialog_open(true) -func _on_QuitAndSaveDialog_custom_action(action : String) -> void: +func _on_QuitAndSaveDialog_custom_action(action: String) -> void: if action == "Save": is_quitting_on_save = true Global.save_sprites_dialog.popup_centered() @@ -410,17 +462,19 @@ func _on_QuitDialog_confirmed() -> void: get_tree().quit() -func _on_BackupConfirmation_confirmed(project_paths : Array, backup_paths : Array) -> void: +func _on_BackupConfirmation_confirmed(project_paths: Array, backup_paths: Array) -> void: OpenSave.reload_backup_file(project_paths, backup_paths) OpenSave.autosave_timer.start() Export.file_name = OpenSave.current_save_paths[0].get_file().trim_suffix(".pxo") Export.directory_path = OpenSave.current_save_paths[0].get_base_dir() Export.was_exported = false - Global.top_menu_container.file_menu.set_item_text(4, tr("Save") + " %s" % OpenSave.current_save_paths[0].get_file()) + Global.top_menu_container.file_menu.set_item_text( + 4, tr("Save") + " %s" % OpenSave.current_save_paths[0].get_file() + ) Global.top_menu_container.file_menu.set_item_text(6, tr("Export")) -func _on_BackupConfirmation_delete(project_paths : Array, backup_paths : Array) -> void: +func _on_BackupConfirmation_delete(project_paths: Array, backup_paths: Array) -> void: for i in range(project_paths.size()): OpenSave.remove_backup_by_path(project_paths[i], backup_paths[i]) OpenSave.autosave_timer.start() @@ -437,7 +491,7 @@ func use_osx_shortcuts() -> void: var inputmap := InputMap for action in inputmap.get_actions(): - var event : InputEvent = inputmap.get_action_list(action)[0] + var event: InputEvent = inputmap.get_action_list(action)[0] if event.is_action("show_pixel_grid"): event.shift = true @@ -450,7 +504,9 @@ func use_osx_shortcuts() -> void: func _exit_tree() -> void: Global.config_cache.set_value("window", "panel_layout", Global.panel_layout) Global.config_cache.set_value("window", "screen", OS.current_screen) - Global.config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen) + Global.config_cache.set_value( + "window", "maximized", OS.window_maximized || OS.window_fullscreen + ) Global.config_cache.set_value("window", "position", OS.window_position) Global.config_cache.set_value("window", "size", OS.window_size) Global.config_cache.save("user://cache.ini") diff --git a/src/Palette/CreatePaletteDialog.gd b/src/Palette/CreatePaletteDialog.gd index 427b5df75..cdec31764 100644 --- a/src/Palette/CreatePaletteDialog.gd +++ b/src/Palette/CreatePaletteDialog.gd @@ -18,14 +18,15 @@ onready var colors_settings := $VBoxContainer/ColorsSettings onready var already_exists_warning := $VBoxContainer/AlreadyExistsWarning onready var enter_name_warning := $VBoxContainer/EnterNameWarning + # Opens dialog func open(opened_current_palette: Palette) -> void: - # Only to fill dialog when preset is FromCurrentPalette + # Only to fill dialog when preset is FROM_CURRENT_PALETTE current_palette = opened_current_palette set_default_values() - preset_input.selected = Palettes.NewPalettePresetType.Empty - # Colors settings are only available for FromCurrentSprite and FromCurrentSelection presets + preset_input.selected = Palettes.NewPalettePresetType.EMPTY + # Colors settings are only available for FROM_CURRENT_SPRITE and FROM_CURRENT_SELECTION presets colors_settings.hide() # Hide warning @@ -48,7 +49,7 @@ func set_default_values() -> void: width_input.value = Palette.DEFAULT_WIDTH height_input.value = Palette.DEFAULT_HEIGHT alpha_colors_input.pressed = true - get_colors_from_input.selected = Palettes.GetColorsFrom.CurrentFrame + get_colors_from_input.selected = Palettes.GetColorsFrom.CURRENT_FRAME # Shows/hides a warning when palette already exists @@ -69,7 +70,16 @@ func _on_CreatePaletteDialog_popup_hide() -> void: func _on_CreatePaletteDialog_confirmed() -> void: - emit_signal("saved", preset_input.selected, name_input.text, comment_input.text, width_input.value, height_input.value, alpha_colors_input.pressed, get_colors_from_input.selected) + emit_signal( + "saved", + preset_input.selected, + name_input.text, + comment_input.text, + width_input.value, + height_input.value, + alpha_colors_input.pressed, + get_colors_from_input.selected + ) func _on_Preset_item_selected(index: int) -> void: @@ -80,10 +90,10 @@ func _on_Preset_item_selected(index: int) -> void: toggle_ok_button_disability(true) match index: - Palettes.NewPalettePresetType.Empty: + Palettes.NewPalettePresetType.EMPTY: colors_settings.hide() set_default_values() - Palettes.NewPalettePresetType.FromCurrentPalette: + Palettes.NewPalettePresetType.FROM_CURRENT_PALETTE: colors_settings.hide() # If any palette was selected copy it's settings to dialog if current_palette: @@ -95,7 +105,10 @@ func _on_Preset_item_selected(index: int) -> void: # Copying palette presets grid size width_input.editable = false height_input.editable = false - Palettes.NewPalettePresetType.FromCurrentSprite, Palettes.NewPalettePresetType.FromCurrentSelection: + Palettes.NewPalettePresetType.FROM_CURRENT_SPRITE: + colors_settings.show() + set_default_values() + Palettes.NewPalettePresetType.FROM_CURRENT_SELECTION: colors_settings.show() set_default_values() diff --git a/src/Palette/EditPaletteDialog.gd b/src/Palette/EditPaletteDialog.gd index 5f1ce3bf5..7043f0dbc 100644 --- a/src/Palette/EditPaletteDialog.gd +++ b/src/Palette/EditPaletteDialog.gd @@ -2,7 +2,7 @@ extends ConfirmationDialog # Emitted when user confirms his changes signal saved(name, comment, width, height) -signal deleted() +signal deleted const DELETE_ACTION := "delete" @@ -21,6 +21,7 @@ onready var path_input := $VBoxContainer/PaletteMetadata/Path onready var size_reduced_warning := $VBoxContainer/SizeReducedWarning onready var already_exists_warning := $VBoxContainer/AlreadyExistsWarning + func _ready() -> void: # Add delete button to edit palette dialog add_button(tr("Delete"), false, DELETE_ACTION) @@ -83,7 +84,10 @@ func _on_EditPaletteDialog_custom_action(action: String) -> void: func _on_size_value_changed(_value): # Toggle resize warning label if palette size was reduced - var size_decreased: bool = height_input.value < origin_height or width_input.value < origin_width + var size_decreased: bool = ( + height_input.value < origin_height + or width_input.value < origin_width + ) toggle_size_reduced_warning(size_decreased) diff --git a/src/Palette/Palette.gd b/src/Palette/Palette.gd index b5794c5a0..2e98beda8 100644 --- a/src/Palette/Palette.gd +++ b/src/Palette/Palette.gd @@ -19,7 +19,12 @@ export var colors: Dictionary = {} export var colors_max := 0 -func _init(init_name: String = "Custom Palette", init_width: int = DEFAULT_WIDTH, init_height: int = DEFAULT_HEIGHT, init_comment: String = "") -> void: +func _init( + init_name: String = "Custom Palette", + init_width: int = DEFAULT_WIDTH, + init_height: int = DEFAULT_HEIGHT, + init_comment: String = "" +) -> void: name = init_name comment = init_comment width = init_width @@ -35,7 +40,6 @@ func edit(new_name: String, new_width: int, new_height: int, new_comment: String name = new_name comment = new_comment - var old_colors_max = colors_max colors_max = width * height @@ -45,7 +49,8 @@ func edit(new_name: String, new_width: int, new_height: int, new_comment: String if old_width < new_width and colors_max > old_colors_max: # If width increases colors have to be reindexed so they keep same grid positions - # unless the height has become smaller and we have to re-position the colors so that they won't get erased + # unless the height has become smaller and we have to re-position the colors + # so that they won't get erased reindex_colors_on_width_increase(old_width) @@ -79,7 +84,7 @@ func reindex_colors_on_width_increase(old_width: int) -> void: var new_colors = {} for old_index in sorted_colors_indexes: var new_index: int = old_index + (width - old_width) * (old_index / old_width) - new_colors[new_index ] = colors[old_index] + new_colors[new_index] = colors[old_index] colors = new_colors @@ -132,7 +137,8 @@ func insert_color(index: int, new_color: Color) -> void: # Recursive function that moves every color to right until one of them is moved to empty swatch func move_right(index: int) -> void: - # Moving colors to right would overflow the size of the palette so increase it's height automatically + # Moving colors to right would overflow the size of the palette + # so increase its height automatically if index + 1 == colors_max: height += 1 colors_max = width * height diff --git a/src/Palette/PaletteColor.gd b/src/Palette/PaletteColor.gd index 597b98ca8..19c5134c9 100644 --- a/src/Palette/PaletteColor.gd +++ b/src/Palette/PaletteColor.gd @@ -3,7 +3,7 @@ extends Resource const UNSET_INDEX := -1 -export var color : Color = Color.transparent +export var color: Color = Color.transparent export var index := UNSET_INDEX diff --git a/src/Palette/PaletteGrid.gd b/src/Palette/PaletteGrid.gd index 8f32823e0..70338d0b2 100644 --- a/src/Palette/PaletteGrid.gd +++ b/src/Palette/PaletteGrid.gd @@ -1,5 +1,5 @@ -extends GridContainer class_name PaletteGrid +extends GridContainer signal swatch_pressed(mouse_button, index) signal swatch_double_clicked(mouse_button, index, position) @@ -10,7 +10,7 @@ const PaletteSwatchScene := preload("res://src/Palette/PaletteSwatch.tscn") # Must be integer values const MAX_GRID_SIZE = Vector2(8, 8) -var swatches := [] # PaletteSwatch +var swatches := [] # PaletteSwatch var displayed_palette = null var grid_window_origin := Vector2.ZERO @@ -54,10 +54,16 @@ func display_palette(palette: Palette) -> void: init_swatches() if palette.width < MAX_GRID_SIZE.x or palette.height < MAX_GRID_SIZE.y: - grid_size = Vector2(min(palette.width, MAX_GRID_SIZE.x), min(palette.height, MAX_GRID_SIZE.y)) + grid_size = Vector2( + min(palette.width, MAX_GRID_SIZE.x), min(palette.height, MAX_GRID_SIZE.y) + ) clear_swatches() init_swatches() - elif palette.width >= MAX_GRID_SIZE.x and palette.height >= MAX_GRID_SIZE.y and grid_size != MAX_GRID_SIZE: + elif ( + palette.width >= MAX_GRID_SIZE.x + and palette.height >= MAX_GRID_SIZE.y + and grid_size != MAX_GRID_SIZE + ): grid_size = MAX_GRID_SIZE clear_swatches() init_swatches() @@ -147,7 +153,10 @@ func _on_PaletteSwatch_dropped(source_index: int, target_index: int) -> void: # Grid index adds grid window origin func convert_grid_index_to_palette_index(index: int) -> int: - return int(index / grid_size.x + grid_window_origin.y) * displayed_palette.width + (index % int(grid_size.x) + grid_window_origin.x) + return ( + int(index / grid_size.x + grid_window_origin.y) * displayed_palette.width + + (index % int(grid_size.x) + grid_window_origin.x) + ) func convert_palette_index_to_grid_index(palette_index: int) -> int: diff --git a/src/Palette/PalettePanel.gd b/src/Palette/PalettePanel.gd index 0e9ccf2f1..caeacacde 100644 --- a/src/Palette/PalettePanel.gd +++ b/src/Palette/PalettePanel.gd @@ -1,5 +1,5 @@ -extends PanelContainer class_name PalettePanel +extends PanelContainer var palettes_path_id := {} var palettes_id_path := {} @@ -20,6 +20,7 @@ onready var create_palette_dialog := $CreatePaletteDialog # Color picker button itself is hidden but it's popup is used to edit color swatches onready var hidden_color_picker := $HiddenColorPickerButton + func _ready() -> void: Tools.connect("color_changed", self, "_color_changed") @@ -109,9 +110,14 @@ func _on_PaletteSelect_item_selected(index: int) -> void: func _on_AddColor_gui_input(event: InputEvent) -> void: if Palettes.is_any_palette_selected(): - if event is InputEventMouseButton and event.pressed and (event.button_index == BUTTON_LEFT or event.button_index == BUTTON_RIGHT): + if ( + event is InputEventMouseButton + and event.pressed + and (event.button_index == BUTTON_LEFT or event.button_index == BUTTON_RIGHT) + ): # Gets the grid index that corresponds to the top left of current grid window - # Color will be added at the start of the currently scrolled part of palette - not the absolute beginning of palette + # Color will be added at the start of the currently scrolled part of palette + # - not the absolute beginning of palette var start_index = palette_grid.convert_grid_index_to_palette_index(0) Palettes.current_palette_add_color(event.button_index, start_index) redraw_current_palette() @@ -121,7 +127,9 @@ func _on_AddColor_gui_input(event: InputEvent) -> void: func _on_DeleteColor_gui_input(event: InputEvent) -> void: if Palettes.is_any_palette_selected(): if event is InputEventMouseButton and event.pressed: - var selected_color_index = Palettes.current_palette_get_selected_color_index(event.button_index) + var selected_color_index = Palettes.current_palette_get_selected_color_index( + event.button_index + ) if selected_color_index != -1: Palettes.current_palette_delete_color(selected_color_index) @@ -129,7 +137,15 @@ func _on_DeleteColor_gui_input(event: InputEvent) -> void: toggle_add_delete_buttons() -func _on_CreatePaletteDialog_saved(preset: int, name: String, comment: String, width: int, height: int, add_alpha_colors: bool, colors_from: int) -> void: +func _on_CreatePaletteDialog_saved( + preset: int, + name: String, + comment: String, + width: int, + height: int, + add_alpha_colors: bool, + colors_from: int +) -> void: Palettes.create_new_palette(preset, name, comment, width, height, add_alpha_colors, colors_from) setup_palettes_selector() redraw_current_palette() @@ -141,7 +157,7 @@ func _on_EditPaletteDialog_saved(name: String, comment: String, width: int, heig redraw_current_palette() -func _on_PaletteGrid_swatch_double_clicked(_mouse_button: int, index: int, click_position: Vector2) -> void: +func _on_PaletteGrid_swatch_double_clicked(_mb: int, index: int, click_position: Vector2) -> void: var color = Palettes.current_palette_get_color(index) edited_swatch_index = index hidden_color_picker.color = color diff --git a/src/Palette/PaletteScroll.gd b/src/Palette/PaletteScroll.gd index c58f4c9ab..a41ceeda3 100644 --- a/src/Palette/PaletteScroll.gd +++ b/src/Palette/PaletteScroll.gd @@ -50,7 +50,10 @@ func _on_PaletteGrid_gui_input(event) -> void: if event.button_index == BUTTON_MIDDLE and event.pressed: drag_started = true # Keeps position where the dragging started - drag_start_position = event.position + Vector2(h_slider.value, v_slider.value) * PaletteSwatch.SWATCH_SIZE + drag_start_position = ( + event.position + + Vector2(h_slider.value, v_slider.value) * PaletteSwatch.SWATCH_SIZE + ) if event is InputEventMouseMotion and drag_started: h_slider.value = (drag_start_position.x - event.position.x) / PaletteSwatch.SWATCH_SIZE.x diff --git a/src/Palette/PaletteSwatch.gd b/src/Palette/PaletteSwatch.gd index b6a77a37d..1b2969015 100644 --- a/src/Palette/PaletteSwatch.gd +++ b/src/Palette/PaletteSwatch.gd @@ -1,13 +1,11 @@ -extends ColorRect class_name PaletteSwatch - -# Required by grid sliders -const SWATCH_SIZE := Vector2(26, 26) +extends ColorRect signal pressed(mouse_button) signal double_clicked(mouse_button, position) signal dropped(source_index, new_index) +const SWATCH_SIZE := Vector2(26, 26) # Required by grid sliders const DEFAULT_COLOR := Color(0.0, 0.0, 0.0, 0.0) var index := -1 @@ -16,7 +14,7 @@ var show_right_highlight := false var empty := true setget set_empty -func _ready(): +func _ready() -> void: rect_min_size = SWATCH_SIZE rect_size = SWATCH_SIZE @@ -35,7 +33,12 @@ func _draw() -> void: # Display inner border highlight var margin := SWATCH_SIZE / 4 draw_rect(Rect2(margin, SWATCH_SIZE - margin * 2), Color.black, false, 1) - draw_rect(Rect2(margin - Vector2.ONE, SWATCH_SIZE - margin * 2 + Vector2(2, 2)), Color.white, false, 1) + draw_rect( + Rect2(margin - Vector2.ONE, SWATCH_SIZE - margin * 2 + Vector2(2, 2)), + Color.white, + false, + 1 + ) # Enables drawing of highlights which indicate selected swatches diff --git a/src/Preferences/HandleLanguages.gd b/src/Preferences/HandleLanguages.gd index b3d5c8122..f61f82a69 100644 --- a/src/Preferences/HandleLanguages.gd +++ b/src/Preferences/HandleLanguages.gd @@ -1,32 +1,31 @@ extends Node - -const languages_dict := { - "en_US" : ["English", "English"], - "cs_CZ" : ["Czech", "Czech"], - "de_DE" : ["Deutsch", "German"], - "el_GR" : ["Ελληνικά", "Greek"], - "eo" : ["Esperanto", "Esperanto"], - "es_ES" : ["Español", "Spanish"], - "fr_FR" : ["Français", "French"], - "id_ID" : ["Indonesian", "Indonesian"], - "it_IT" : ["Italiano", "Italian"], - "lv_LV" : ["Latvian", "Latvian"], - "pl_PL" : ["Polski", "Polish"], - "pt_BR" : ["Português Brasileiro", "Brazilian Portuguese"], - "ru_RU" : ["Русский", "Russian"], - "zh_CN" : ["简体中文", "Chinese Simplified"], - "zh_TW" : ["繁體中文", "Chinese Traditional"], - "nb_NO" : ["Norsk Bokmål", "Norwegian Bokmål"], - "hu_HU" : ["Magyar", "Hungarian"], - "ro_RO" : ["Română", "Romanian"], - "ko_KR" : ["한국어", "Korean"], - "tr_TR" : ["Türkçe", "Turkish"], - "ja_JP" : ["日本語", "Japanese"], - "uk_UA" : ["Українська", "Ukrainian"], +const LANGUAGES_DICT := { + "en_US": ["English", "English"], + "cs_CZ": ["Czech", "Czech"], + "de_DE": ["Deutsch", "German"], + "el_GR": ["Ελληνικά", "Greek"], + "eo": ["Esperanto", "Esperanto"], + "es_ES": ["Español", "Spanish"], + "fr_FR": ["Français", "French"], + "id_ID": ["Indonesian", "Indonesian"], + "it_IT": ["Italiano", "Italian"], + "lv_LV": ["Latvian", "Latvian"], + "pl_PL": ["Polski", "Polish"], + "pt_BR": ["Português Brasileiro", "Brazilian Portuguese"], + "ru_RU": ["Русский", "Russian"], + "zh_CN": ["简体中文", "Chinese Simplified"], + "zh_TW": ["繁體中文", "Chinese Traditional"], + "nb_NO": ["Norsk Bokmål", "Norwegian Bokmål"], + "hu_HU": ["Magyar", "Hungarian"], + "ro_RO": ["Română", "Romanian"], + "ko_KR": ["한국어", "Korean"], + "tr_TR": ["Türkçe", "Turkish"], + "ja_JP": ["日本語", "Japanese"], + "uk_UA": ["Українська", "Ukrainian"], } -var loaded_locales : Array +var loaded_locales: Array onready var latin_font = preload("res://assets/fonts/Roboto-Regular.tres") onready var cjk_font = preload("res://assets/fonts/CJK/DroidSansFallback-Regular.tres") @@ -40,12 +39,12 @@ func _ready() -> void: # Create radiobuttons for each language for locale in loaded_locales: - if !locale in languages_dict: + if !locale in LANGUAGES_DICT: continue var button = CheckBox.new() - button.text = languages_dict[locale][0] + " [%s]" % [locale] - button.name = languages_dict[locale][1] - button.hint_tooltip = languages_dict[locale][1] + button.text = LANGUAGES_DICT[locale][0] + " [%s]" % [locale] + button.name = LANGUAGES_DICT[locale][1] + button.hint_tooltip = LANGUAGES_DICT[locale][1] button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND button.group = button_group if Global.is_cjk(locale): @@ -56,14 +55,14 @@ func _ready() -> void: # Load language if Global.config_cache.has_section_key("preferences", "locale"): - var saved_locale : String = Global.config_cache.get_value("preferences", "locale") + var saved_locale: String = Global.config_cache.get_value("preferences", "locale") TranslationServer.set_locale(saved_locale) # Set the language option menu's default selected option to the loaded locale var locale_index: int = loaded_locales.find(saved_locale) - get_child(0).pressed = false # Unset System Language option in preferences + get_child(0).pressed = false # Unset System Language option in preferences get_child(locale_index + 1).pressed = true - else: # If the user doesn't have a language preference, set it to their OS' locale + else: # If the user doesn't have a language preference, set it to their OS' locale TranslationServer.set_locale(OS.get_locale()) if Global.is_cjk(TranslationServer.get_locale()): @@ -77,7 +76,7 @@ func _ready() -> void: child.hint_tooltip = child.name -func _on_Language_pressed(index : int) -> void: +func _on_Language_pressed(index: int) -> void: get_child(index).pressed = true if index == 0: TranslationServer.set_locale(OS.get_locale()) @@ -94,5 +93,5 @@ func _on_Language_pressed(index : int) -> void: # Update Translations Global.update_hint_tooltips() - Global.preferences_dialog._on_PreferencesDialog_popup_hide() - Global.preferences_dialog._on_PreferencesDialog_about_to_show(true) + Global.preferences_dialog.list.clear() + Global.preferences_dialog.add_tabs(true) diff --git a/src/Preferences/HandleShortcuts.gd b/src/Preferences/HandleShortcuts.gd index b42ccf0f6..5d8a92065 100644 --- a/src/Preferences/HandleShortcuts.gd +++ b/src/Preferences/HandleShortcuts.gd @@ -4,11 +4,13 @@ var default_shortcuts_preset := {} var custom_shortcuts_preset := {} var action_being_edited := "" var shortcut_already_assigned = false -var old_input_event : InputEventKey -var new_input_event : InputEventKey +var old_input_event: InputEventKey +var new_input_event: InputEventKey onready var shortcut_selector_popup = Global.preferences_dialog.get_node("Popups/ShortcutSelector") -onready var theme_font_color : Color = Global.preferences_dialog.get_node("Popups/ShortcutSelector/EnteredShortcut").get_color("font_color") +onready var theme_font_color: Color = shortcut_selector_popup.get_node("EnteredShortcut").get_color( + "font_color" +) func _ready() -> void: @@ -21,9 +23,13 @@ func _ready() -> void: if shortcut_grid_item is Button: var input_events = InputMap.get_action_list(shortcut_grid_item.name) if input_events.size() > 1: - printerr("Every shortcut action should have just one input event assigned in input map") + printerr( + "Every shortcut action should have just one input event assigned in input map" + ) shortcut_grid_item.text = (input_events[0] as InputEventKey).as_text() - shortcut_grid_item.connect("pressed", self, "_on_Shortcut_button_pressed", [shortcut_grid_item]) + shortcut_grid_item.connect( + "pressed", self, "_on_Shortcut_button_pressed", [shortcut_grid_item] + ) default_shortcuts_preset[shortcut_grid_item.name] = input_events[0] # Load custom shortcuts from the config file @@ -38,7 +44,7 @@ func _ready() -> void: _on_PresetOptionButton_item_selected(shortcuts_preset) -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if event is InputEventKey: if event.pressed: if event.scancode == KEY_ESCAPE: @@ -48,9 +54,16 @@ func _input(event : InputEvent) -> void: for action in InputMap.get_actions(): for input_event in InputMap.get_action_list(action): if input_event is InputEventKey: - if OS.get_scancode_string(input_event.get_scancode_with_modifiers()) == OS.get_scancode_string(event.get_scancode_with_modifiers()): - shortcut_selector_popup.get_node("EnteredShortcut").text = tr("Already assigned") - shortcut_selector_popup.get_node("EnteredShortcut").add_color_override("font_color", Color.crimson) + if ( + OS.get_scancode_string(input_event.get_scancode_with_modifiers()) + == OS.get_scancode_string(event.get_scancode_with_modifiers()) + ): + shortcut_selector_popup.get_node("EnteredShortcut").text = tr( + "Already assigned" + ) + shortcut_selector_popup.get_node("EnteredShortcut").add_color_override( + "font_color", Color.crimson + ) get_tree().set_input_as_handled() shortcut_already_assigned = true return @@ -59,12 +72,16 @@ func _input(event : InputEvent) -> void: shortcut_already_assigned = false old_input_event = InputMap.get_action_list(action_being_edited)[0] new_input_event = event - shortcut_selector_popup.get_node("EnteredShortcut").text = OS.get_scancode_string(event.get_scancode_with_modifiers()) - shortcut_selector_popup.get_node("EnteredShortcut").add_color_override("font_color", theme_font_color) + shortcut_selector_popup.get_node("EnteredShortcut").text = OS.get_scancode_string( + event.get_scancode_with_modifiers() + ) + shortcut_selector_popup.get_node("EnteredShortcut").add_color_override( + "font_color", theme_font_color + ) get_tree().set_input_as_handled() -func _on_PresetOptionButton_item_selected(id : int) -> void: +func _on_PresetOptionButton_item_selected(id: int) -> void: # Only custom preset which is modifiable toggle_shortcut_buttons(true if id == 1 else false) match id: @@ -78,12 +95,14 @@ func _on_PresetOptionButton_item_selected(id : int) -> void: func apply_shortcuts_preset(preset) -> void: for action in preset: - var _old_input_event : InputEventKey = InputMap.get_action_list(action)[0] - set_action_shortcut(action, _old_input_event, preset[action]) - get_node("Shortcuts/" + action).text = OS.get_scancode_string(preset[action].get_scancode_with_modifiers()) + var preset_old_input_event: InputEventKey = InputMap.get_action_list(action)[0] + set_action_shortcut(action, preset_old_input_event, preset[action]) + get_node("Shortcuts/" + action).text = OS.get_scancode_string( + preset[action].get_scancode_with_modifiers() + ) -func toggle_shortcut_buttons(enabled : bool) -> void: +func toggle_shortcut_buttons(enabled: bool) -> void: for shortcut_grid_item in get_node("Shortcuts").get_children(): if shortcut_grid_item is Button: shortcut_grid_item.disabled = not enabled @@ -93,16 +112,17 @@ func toggle_shortcut_buttons(enabled : bool) -> void: shortcut_grid_item.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND -func set_action_shortcut(action : String, old_input : InputEventKey, new_input : InputEventKey) -> void: - InputMap.action_erase_event(action, old_input) - InputMap.action_add_event(action, new_input) - Global.update_hint_tooltips() +func set_action_shortcut(action: String, oldinput: InputEventKey, newinput: InputEventKey) -> void: + InputMap.action_erase_event(action, oldinput) + InputMap.action_add_event(action, newinput) + var color_switch: BaseButton = Global.control.find_node("ColorSwitch") # Set shortcut to switch colors button if action == "switch_colors": - Global.control.find_node("ColorSwitch").shortcut.shortcut = InputMap.get_action_list("switch_colors")[0] + color_switch.shortcut.shortcut = InputMap.get_action_list("switch_colors")[0] + Global.update_hint_tooltips() -func _on_Shortcut_button_pressed(button : Button) -> void: +func _on_Shortcut_button_pressed(button: Button) -> void: set_process_input(true) action_being_edited = button.name new_input_event = InputMap.get_action_list(button.name)[0] @@ -121,5 +141,7 @@ func _on_ShortcutSelector_confirmed() -> void: custom_shortcuts_preset[action_being_edited] = new_input_event Global.config_cache.set_value("shortcuts", action_being_edited, new_input_event) Global.config_cache.save("user://cache.ini") - get_node("Shortcuts/" + action_being_edited).text = OS.get_scancode_string(new_input_event.get_scancode_with_modifiers()) + get_node("Shortcuts/" + action_being_edited).text = OS.get_scancode_string( + new_input_event.get_scancode_with_modifiers() + ) shortcut_selector_popup.hide() diff --git a/src/Preferences/HandleThemes.gd b/src/Preferences/HandleThemes.gd index a1e6a2f10..5fd00721e 100644 --- a/src/Preferences/HandleThemes.gd +++ b/src/Preferences/HandleThemes.gd @@ -1,6 +1,5 @@ extends Node - var theme_index := 0 onready var themes := [ @@ -12,8 +11,8 @@ onready var themes := [ [preload("res://assets/themes/purple/theme.tres"), "Purple", Color.gray], ] -onready var buttons_container : BoxContainer = $ThemeButtons -onready var colors_container : BoxContainer = $ThemeColorsSpacer/ThemeColors +onready var buttons_container: BoxContainer = $ThemeButtons +onready var colors_container: BoxContainer = $ThemeColorsSpacer/ThemeColors onready var theme_color_preview_scene = preload("res://src/Preferences/ThemeColorPreview.tscn") @@ -28,7 +27,7 @@ func _ready() -> void: buttons_container.add_child(button) button.connect("pressed", self, "_on_Theme_pressed", [button.get_index()]) - var theme_color_preview : ColorRect = theme_color_preview_scene.instance() + var theme_color_preview: ColorRect = theme_color_preview_scene.instance() var color1 = theme[0].get_stylebox("panel", "Panel").bg_color var color2 = theme[0].get_stylebox("panel", "PanelContainer").bg_color theme_color_preview.get_child(0).color = color1 @@ -46,7 +45,7 @@ func _ready() -> void: buttons_container.get_child(0).pressed = true -func _on_Theme_pressed(index : int) -> void: +func _on_Theme_pressed(index: int) -> void: buttons_container.get_child(index).pressed = true change_theme(index) @@ -57,43 +56,53 @@ func _on_Theme_pressed(index : int) -> void: Global.config_cache.save("user://cache.ini") -func change_theme(ID : int) -> void: +func change_theme(id: int) -> void: var font = Global.control.theme.default_font - theme_index = ID - var main_theme : Theme = themes[ID][0] + theme_index = id + var main_theme: Theme = themes[id][0] - if ID == 0 or ID == 1 or ID == 5: # Dark, Gray or Purple Theme + if id == 0 or id == 1 or id == 5: # Dark, Gray or Purple Theme Global.theme_type = Global.ThemeTypes.DARK - elif ID == 2: # Godot's Theme + elif id == 2: # Godot's Theme Global.theme_type = Global.ThemeTypes.BLUE - elif ID == 3: # Caramel Theme + elif id == 3: # Caramel Theme Global.theme_type = Global.ThemeTypes.CARAMEL - elif ID == 4: # Light Theme + elif id == 4: # Light Theme Global.theme_type = Global.ThemeTypes.LIGHT if Global.icon_color_from == Global.IconColorFrom.THEME: - Global.modulate_icon_color = themes[ID][2] + Global.modulate_icon_color = themes[id][2] Global.control.theme = main_theme Global.control.theme.default_font = font Global.default_clear_color = main_theme.get_stylebox("panel", "PanelContainer").bg_color VisualServer.set_default_clear_color(Color(Global.default_clear_color)) - if Global.control.alternate_transparent_background: # Also change color of alternate_transparent_background + if Global.control.alternate_transparent_background: + # Also change color of alternate_transparent_background var new_color = Global.default_clear_color new_color.a = Global.control.alternate_transparent_background.color.a Global.control.alternate_transparent_background.color = new_color - (Global.animation_timeline.get_stylebox("panel", "Panel") as StyleBoxFlat).bg_color = main_theme.get_stylebox("panel", "Panel").bg_color - var fake_vsplit_grabber : TextureRect = Global.animation_timeline.find_node("FakeVSplitContainerGrabber") + Global.animation_timeline.get_stylebox("panel", "Panel").bg_color = main_theme.get_stylebox( + "panel", "Panel" + ).bg_color + var fake_vsplit_grabber: TextureRect = Global.animation_timeline.find_node( + "FakeVSplitContainerGrabber" + ) fake_vsplit_grabber.texture = main_theme.get_icon("grabber", "VSplitContainer") # Theming for left tools panel - var fake_hsplit_grabber : TextureRect = Global.tool_panel.get_node("FakeHSplitGrabber") + var fake_hsplit_grabber: TextureRect = Global.tool_panel.get_node("FakeHSplitGrabber") fake_hsplit_grabber.texture = main_theme.get_icon("grabber", "HSplitContainer") - (Global.tool_panel.get_stylebox("panel", "Panel") as StyleBoxFlat).bg_color = main_theme.get_stylebox("panel", "Panel").bg_color + Global.tool_panel.get_stylebox("panel", "Panel").bg_color = main_theme.get_stylebox( + "panel", "Panel" + ).bg_color - var layer_button_panel_container : PanelContainer = Global.animation_timeline.find_node("LayerButtonPanelContainer") - (layer_button_panel_container.get_stylebox("panel", "PanelContainer") as StyleBoxFlat).bg_color = Global.default_clear_color + var layer_button_pcont: PanelContainer = Global.animation_timeline.find_node( + "LayerButtonPanelContainer" + ) + var lbpc_stylebox: StyleBoxFlat = layer_button_pcont.get_stylebox("panel", "PanelContainer") + lbpc_stylebox.bg_color = Global.default_clear_color var top_menu_style = main_theme.get_stylebox("TopMenu", "Panel") var ruler_style = main_theme.get_stylebox("Ruler", "Button") @@ -122,7 +131,7 @@ func change_icon_colors() -> void: if node.disabled and not ("RestoreDefaultButton" in node.name): node.modulate.a = 0.5 elif node is Button: - var texture : TextureRect + var texture: TextureRect for child in node.get_children(): if child is TextureRect and child.name != "Background": texture = child diff --git a/src/Preferences/PreferencesDialog.gd b/src/Preferences/PreferencesDialog.gd index 920569487..bd639447d 100644 --- a/src/Preferences/PreferencesDialog.gd +++ b/src/Preferences/PreferencesDialog.gd @@ -2,68 +2,186 @@ extends AcceptDialog # Preferences table: [Prop name in Global, relative node path, value type, default value] var preferences = [ - ["open_last_project", "Startup/StartupContainer/OpenLastProject", "pressed", Global.open_last_project], - + [ + "open_last_project", + "Startup/StartupContainer/OpenLastProject", + "pressed", + Global.open_last_project + ], ["shrink", "Interface/ShrinkContainer/ShrinkHSlider", "value", Global.shrink], ["dim_on_popup", "Interface/DimPopup/CheckBox", "pressed", Global.dim_on_popup], - ["icon_color_from", "Interface/IconColorFrom/IconColorOptionButton", "selected", Global.icon_color_from], - ["custom_icon_color", "Interface/IconColorFrom/IconColorButton", "color", Global.custom_icon_color], - ["tool_button_size", "Interface/ToolButtonSize/ToolButtonSizeOptionButton", "selected", Global.tool_button_size], - - ["pressure_sensitivity_mode", "Startup/PressureSentivity/PressureSensitivityOptionButton", "selected", Global.pressure_sensitivity_mode], - ["show_left_tool_icon", "Indicators/IndicatorsContainer/LeftToolIconCheckbox", "pressed", Global.show_left_tool_icon], - ["show_right_tool_icon", "Indicators/IndicatorsContainer/RightToolIconCheckbox", "pressed", Global.show_right_tool_icon], - ["left_square_indicator_visible", "Indicators/IndicatorsContainer/LeftIndicatorCheckbox", "pressed", Global.left_square_indicator_visible], - ["right_square_indicator_visible", "Indicators/IndicatorsContainer/RightIndicatorCheckbox", "pressed", Global.right_square_indicator_visible], - ["autosave_interval", "Backup/AutosaveContainer/AutosaveInterval", "value", Global.autosave_interval], - ["enable_autosave", "Backup/AutosaveContainer/EnableAutosave", "pressed", Global.enable_autosave], - - ["default_image_width", "Image/ImageOptions/ImageDefaultWidth", "value", Global.default_image_width], - ["default_image_height", "Image/ImageOptions/ImageDefaultHeight", "value", Global.default_image_height], - ["default_fill_color", "Image/ImageOptions/DefaultFillColor", "color", Global.default_fill_color], - + [ + "icon_color_from", + "Interface/IconColorFrom/IconColorOptionButton", + "selected", + Global.icon_color_from + ], + [ + "custom_icon_color", + "Interface/IconColorFrom/IconColorButton", + "color", + Global.custom_icon_color + ], + [ + "tool_button_size", + "Interface/ToolButtonSize/ToolButtonSizeOptionButton", + "selected", + Global.tool_button_size + ], + [ + "pressure_sensitivity_mode", + "Startup/PressureSentivity/PressureSensitivityOptionButton", + "selected", + Global.pressure_sensitivity_mode + ], + [ + "show_left_tool_icon", + "Indicators/IndicatorsContainer/LeftToolIconCheckbox", + "pressed", + Global.show_left_tool_icon + ], + [ + "show_right_tool_icon", + "Indicators/IndicatorsContainer/RightToolIconCheckbox", + "pressed", + Global.show_right_tool_icon + ], + [ + "left_square_indicator_visible", + "Indicators/IndicatorsContainer/LeftIndicatorCheckbox", + "pressed", + Global.left_square_indicator_visible + ], + [ + "right_square_indicator_visible", + "Indicators/IndicatorsContainer/RightIndicatorCheckbox", + "pressed", + Global.right_square_indicator_visible + ], + [ + "autosave_interval", + "Backup/AutosaveContainer/AutosaveInterval", + "value", + Global.autosave_interval + ], + [ + "enable_autosave", + "Backup/AutosaveContainer/EnableAutosave", + "pressed", + Global.enable_autosave + ], + [ + "default_image_width", + "Image/ImageOptions/ImageDefaultWidth", + "value", + Global.default_image_width + ], + [ + "default_image_height", + "Image/ImageOptions/ImageDefaultHeight", + "value", + Global.default_image_height + ], + [ + "default_fill_color", + "Image/ImageOptions/DefaultFillColor", + "color", + Global.default_fill_color + ], ["smooth_zoom", "Canvas/ZoomOptions/SmoothZoom", "pressed", Global.smooth_zoom], ["grid_type", "Canvas/GridOptions/GridType", "selected", Global.grid_type], ["grid_width", "Canvas/GridOptions/GridWidthValue", "value", Global.grid_width], ["grid_height", "Canvas/GridOptions/GridHeightValue", "value", Global.grid_height], - ["grid_isometric_cell_bounds_width", "Canvas/GridOptions/IsometricCellBoundsWidthValue", "value", Global.grid_isometric_cell_bounds_width], - ["grid_isometric_cell_bounds_height", "Canvas/GridOptions/IsometricCellBoundsHeightValue", "value", Global.grid_isometric_cell_bounds_height], + [ + "grid_isometric_cell_bounds_width", + "Canvas/GridOptions/IsometricCellBoundsWidthValue", + "value", + Global.grid_isometric_cell_bounds_width + ], + [ + "grid_isometric_cell_bounds_height", + "Canvas/GridOptions/IsometricCellBoundsHeightValue", + "value", + Global.grid_isometric_cell_bounds_height + ], ["grid_offset_x", "Canvas/GridOptions/GridOffsetXValue", "value", Global.grid_offset_x], ["grid_offset_y", "Canvas/GridOptions/GridOffsetYValue", "value", Global.grid_offset_y], - ["grid_draw_over_tile_mode", "Canvas/GridOptions/GridDrawOverTileMode", "pressed", Global.grid_draw_over_tile_mode], + [ + "grid_draw_over_tile_mode", + "Canvas/GridOptions/GridDrawOverTileMode", + "pressed", + Global.grid_draw_over_tile_mode + ], ["grid_color", "Canvas/GridOptions/GridColor", "color", Global.grid_color], - ["pixel_grid_show_at_zoom", "Canvas/PixelGridOptions/ShowAtZoom", "value", Global.pixel_grid_show_at_zoom], + [ + "pixel_grid_show_at_zoom", + "Canvas/PixelGridOptions/ShowAtZoom", + "value", + Global.pixel_grid_show_at_zoom + ], ["pixel_grid_color", "Canvas/PixelGridOptions/GridColor", "color", Global.pixel_grid_color], ["guide_color", "Canvas/GuideOptions/GuideColor", "color", Global.guide_color], ["checker_size", "Canvas/CheckerOptions/CheckerSizeValue", "value", Global.checker_size], ["checker_color_1", "Canvas/CheckerOptions/CheckerColor1", "color", Global.checker_color_1], ["checker_color_2", "Canvas/CheckerOptions/CheckerColor2", "color", Global.checker_color_2], - ["checker_follow_movement", "Canvas/CheckerOptions/CheckerFollowMovement", "pressed", Global.checker_follow_movement], - ["checker_follow_scale", "Canvas/CheckerOptions/CheckerFollowScale", "pressed", Global.checker_follow_scale], + [ + "checker_follow_movement", + "Canvas/CheckerOptions/CheckerFollowMovement", + "pressed", + Global.checker_follow_movement + ], + [ + "checker_follow_scale", + "Canvas/CheckerOptions/CheckerFollowScale", + "pressed", + Global.checker_follow_scale + ], ["tilemode_opacity", "Canvas/CheckerOptions/TileModeOpacity", "value", Global.tilemode_opacity], - - ["selection_animated_borders", "Selection/SelectionOptions/Animate", "pressed", Global.selection_animated_borders], - ["selection_border_color_1", "Selection/SelectionOptions/BorderColor1", "color", Global.selection_border_color_1], - ["selection_border_color_2", "Selection/SelectionOptions/BorderColor2", "color", Global.selection_border_color_2], - + [ + "selection_animated_borders", + "Selection/SelectionOptions/Animate", + "pressed", + Global.selection_animated_borders + ], + [ + "selection_border_color_1", + "Selection/SelectionOptions/BorderColor1", + "color", + Global.selection_border_color_1 + ], + [ + "selection_border_color_2", + "Selection/SelectionOptions/BorderColor2", + "color", + Global.selection_border_color_2 + ], ["fps_limit", "Performance/PerformanceContainer/SetFPSLimit", "value", Global.fps_limit], - ["fps_limit_focus", "Performance/PerformanceContainer/EnableLimitFPSFocus", "pressed", Global.fps_limit_focus], + [ + "fps_limit_focus", + "Performance/PerformanceContainer/EnableLimitFPSFocus", + "pressed", + Global.fps_limit_focus + ], ["idle_fps", "Performance/PerformanceContainer/IdleFPS", "value", Global.idle_fps] ] var selected_item := 0 +var restore_default_button_tcsn = preload("res://src/Preferences/RestoreDefaultButton.tscn") -onready var list : ItemList = $HSplitContainer/List -onready var right_side : VBoxContainer = $HSplitContainer/ScrollContainer/VBoxContainer -onready var autosave_interval : SpinBox = $HSplitContainer/ScrollContainer/VBoxContainer/Backup/AutosaveContainer/AutosaveInterval -onready var restore_default_button_scene = preload("res://src/Preferences/RestoreDefaultButton.tscn") -onready var shrink_label : Label = $HSplitContainer/ScrollContainer/VBoxContainer/Interface/ShrinkContainer/ShrinkLabel -onready var themes : BoxContainer = $"HSplitContainer/ScrollContainer/VBoxContainer/Interface/Themes" -onready var idle_fps_spinbox : SpinBox = $HSplitContainer/ScrollContainer/VBoxContainer/Performance/PerformanceContainer/IdleFPS +onready var list: ItemList = $HSplitContainer/List +onready var right_side: VBoxContainer = $HSplitContainer/ScrollContainer/VBoxContainer +onready var autosave_interval: SpinBox = right_side.get_node( + "Backup/AutosaveContainer/AutosaveInterval" +) +onready var shrink_label: Label = right_side.get_node("Interface/ShrinkContainer/ShrinkLabel") +onready var themes: BoxContainer = right_side.get_node("Interface/Themes") +onready var idle_fps_spinbox: SpinBox = right_side.get_node( + "Performance/PerformanceContainer/IdleFPS" +) func _ready() -> void: - # Replace OK with Close since preference changes are being applied immediately, not after OK confirmation + # Replace OK since preference changes are being applied immediately, not after OK confirmation get_ok().text = tr("Close") if OS.get_name() == "HTML5": @@ -75,7 +193,7 @@ func _ready() -> void: var node = right_side.get_node(pref[1]) var node_position = node.get_index() - var restore_default_button : BaseButton = restore_default_button_scene.instance() + var restore_default_button: BaseButton = restore_default_button_tcsn.instance() restore_default_button.setting_name = pref[0] restore_default_button.value_type = pref[2] restore_default_button.default_value = pref[3] @@ -85,14 +203,34 @@ func _ready() -> void: match pref[2]: "pressed": - node.connect("toggled", self, "_on_Preference_toggled", [pref[0], pref[3], restore_default_button]) + node.connect( + "toggled", + self, + "_on_Preference_toggled", + [pref[0], pref[3], restore_default_button] + ) "value": - node.connect("value_changed", self, "_on_Preference_value_changed", [pref[0], pref[3], restore_default_button]) + node.connect( + "value_changed", + self, + "_on_Preference_value_changed", + [pref[0], pref[3], restore_default_button] + ) "color": node.get_picker().presets_visible = false - node.connect("color_changed", self, "_on_Preference_color_changed", [pref[0], pref[3], restore_default_button]) + node.connect( + "color_changed", + self, + "_on_Preference_color_changed", + [pref[0], pref[3], restore_default_button] + ) "selected": - node.connect("item_selected", self, "_on_Preference_item_selected", [pref[0], pref[3], restore_default_button]) + node.connect( + "item_selected", + self, + "_on_Preference_item_selected", + [pref[0], pref[3], restore_default_button] + ) if Global.config_cache.has_section_key("preferences", pref[0]): var value = Global.config_cache.get_value("preferences", pref[0]) @@ -102,41 +240,55 @@ func _ready() -> void: # This is needed because color_changed doesn't fire if the color changes in code if pref[2] == "color": preference_update(pref[0]) - disable_restore_default_button(restore_default_button, Global.get(pref[0]).is_equal_approx(pref[3])) + disable_restore_default_button( + restore_default_button, Global.get(pref[0]).is_equal_approx(pref[3]) + ) elif pref[2] == "selected": preference_update(pref[0]) - disable_restore_default_button(restore_default_button, Global.get(pref[0]) == pref[3]) + disable_restore_default_button( + restore_default_button, Global.get(pref[0]) == pref[3] + ) -func _on_Preference_toggled(button_pressed : bool, prop : String, default_value, restore_default_button : BaseButton) -> void: +func _on_Preference_toggled( + button_pressed: bool, prop: String, default_value, restore_default_button: BaseButton +) -> void: Global.set(prop, button_pressed) Global.config_cache.set_value("preferences", prop, button_pressed) preference_update(prop) disable_restore_default_button(restore_default_button, Global.get(prop) == default_value) -func _on_Preference_value_changed(value : float, prop : String, default_value, restore_default_button : BaseButton) -> void: +func _on_Preference_value_changed( + value: float, prop: String, default_value, restore_default_button: BaseButton +) -> void: Global.set(prop, value) Global.config_cache.set_value("preferences", prop, value) preference_update(prop) disable_restore_default_button(restore_default_button, Global.get(prop) == default_value) -func _on_Preference_color_changed(color : Color, prop : String, default_value, restore_default_button : BaseButton) -> void: +func _on_Preference_color_changed( + color: Color, prop: String, default_value, restore_default_button: BaseButton +) -> void: Global.set(prop, color) Global.config_cache.set_value("preferences", prop, color) preference_update(prop) - disable_restore_default_button(restore_default_button, Global.get(prop).is_equal_approx(default_value)) + disable_restore_default_button( + restore_default_button, Global.get(prop).is_equal_approx(default_value) + ) -func _on_Preference_item_selected(id : int, prop : String, default_value, restore_default_button : BaseButton) -> void: +func _on_Preference_item_selected( + id: int, prop: String, default_value, restore_default_button: BaseButton +) -> void: Global.set(prop, id) Global.config_cache.set_value("preferences", prop, id) preference_update(prop) disable_restore_default_button(restore_default_button, Global.get(prop) == default_value) -func preference_update(prop : String) -> void: +func preference_update(prop: String) -> void: if prop in ["autosave_interval", "enable_autosave"]: OpenSave.update_autosave() autosave_interval.editable = Global.enable_autosave @@ -145,20 +297,44 @@ func preference_update(prop : String) -> void: else: autosave_interval.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN - if prop in ["grid_type", "grid_width", "grid_height", "grid_isometric_cell_bounds_width", "grid_isometric_cell_bounds_height", "grid_offset_x", "grid_offset_y", "grid_draw_over_tile_mode", "grid_color"]: + if ( + prop + in [ + "grid_type", + "grid_width", + "grid_height", + "grid_isometric_cell_bounds_width", + "grid_isometric_cell_bounds_height", + "grid_offset_x", + "grid_offset_y", + "grid_draw_over_tile_mode", + "grid_color" + ] + ): Global.canvas.grid.update() if prop in ["pixel_grid_show_at_zoom", "pixel_grid_color"]: Global.canvas.pixel_grid.update() - if prop in ["checker_size", "checker_color_1", "checker_color_2", "checker_follow_movement", "checker_follow_scale"]: - Global.transparent_checker._ready() + if ( + prop + in [ + "checker_size", + "checker_color_1", + "checker_color_2", + "checker_follow_movement", + "checker_follow_scale" + ] + ): + Global.transparent_checker.update_rect() if prop in ["guide_color"]: for guide in Global.canvas.get_children(): if guide is SymmetryGuide: # Add a subtle difference to the normal guide color by mixing in some blue - guide.default_color = Global.guide_color.linear_interpolate(Color(0.2 , 0.2, .65), .6) + guide.default_color = Global.guide_color.linear_interpolate( + Color(0.2, 0.2, .65), .6 + ) elif guide is Guide: guide.default_color = Global.guide_color @@ -168,10 +344,19 @@ func preference_update(prop : String) -> void: if prop in ["fps_limit_focus"]: idle_fps_spinbox.editable = !idle_fps_spinbox.editable - if prop in ["selection_animated_borders", "selection_border_color_1", "selection_border_color_2"]: - Global.canvas.selection.marching_ants_outline.material.set_shader_param("animated", Global.selection_animated_borders) - Global.canvas.selection.marching_ants_outline.material.set_shader_param("first_color", Global.selection_border_color_1) - Global.canvas.selection.marching_ants_outline.material.set_shader_param("second_color", Global.selection_border_color_2) + if ( + prop + in ["selection_animated_borders", "selection_border_color_1", "selection_border_color_2"] + ): + Global.canvas.selection.marching_ants_outline.material.set_shader_param( + "animated", Global.selection_animated_borders + ) + Global.canvas.selection.marching_ants_outline.material.set_shader_param( + "first_color", Global.selection_border_color_1 + ) + Global.canvas.selection.marching_ants_outline.material.set_shader_param( + "second_color", Global.selection_border_color_2 + ) Global.canvas.selection.update() if prop in ["icon_color_from", "custom_icon_color"]: @@ -181,14 +366,13 @@ func preference_update(prop : String) -> void: Global.modulate_icon_color = Global.custom_icon_color themes.change_icon_colors() - if prop == "tool_button_size": Tools.set_button_size(Global.tool_button_size) Global.config_cache.save("user://cache.ini") -func disable_restore_default_button(button : BaseButton, disable : bool) -> void: +func disable_restore_default_button(button: BaseButton, disable: bool) -> void: button.disabled = disable if disable: button.mouse_default_cursor_shape = Control.CURSOR_ARROW @@ -198,7 +382,11 @@ func disable_restore_default_button(button : BaseButton, disable : bool) -> void button.hint_tooltip = "Restore default value" -func _on_PreferencesDialog_about_to_show(changed_language := false) -> void: +func _on_PreferencesDialog_about_to_show() -> void: + add_tabs(false) + + +func add_tabs(changed_language := false) -> void: if OS.get_name() != "HTML5": list.add_item(" " + tr("Startup")) list.add_item(" " + tr("Language")) @@ -219,22 +407,37 @@ func _on_PreferencesDialog_popup_hide() -> void: list.clear() -func _on_List_item_selected(index : int) -> void: +func _on_List_item_selected(index: int) -> void: selected_item = index for child in right_side.get_children(): - var content_list = ["Startup", "Languages", "Interface", "Canvas", "Selection", "Image", "Shortcuts", "Backup", "Performance", "Indicators"] + var content_list = [ + "Startup", + "Languages", + "Interface", + "Canvas", + "Selection", + "Image", + "Shortcuts", + "Backup", + "Performance", + "Indicators" + ] if OS.get_name() == "HTML5": content_list.erase("Startup") child.visible = child.name == content_list[index] -func _on_ShrinkHSlider_value_changed(value : float) -> void: +func _on_ShrinkHSlider_value_changed(value: float) -> void: shrink_label.text = str(value) func _on_ShrinkApplyButton_pressed() -> void: - get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_DISABLED, - SceneTree.STRETCH_ASPECT_IGNORE, Vector2(1024,576), Global.shrink) + get_tree().set_screen_stretch( + SceneTree.STRETCH_MODE_DISABLED, + SceneTree.STRETCH_ASPECT_IGNORE, + Vector2(1024, 576), + Global.shrink + ) hide() popup_centered(Vector2(400, 280)) Global.dialog_open(true) diff --git a/src/Preferences/RestoreDefaultButton.gd b/src/Preferences/RestoreDefaultButton.gd index e3d192c03..83c4e427a 100644 --- a/src/Preferences/RestoreDefaultButton.gd +++ b/src/Preferences/RestoreDefaultButton.gd @@ -1,10 +1,9 @@ extends TextureButton - -var setting_name : String -var value_type : String +var setting_name: String +var value_type: String var default_value -var node : Node +var node: Node func _ready() -> void: diff --git a/src/Tools/BaseTool.gd b/src/Tools/BaseTool.gd index beabf03f6..c15d7533f 100644 --- a/src/Tools/BaseTool.gd +++ b/src/Tools/BaseTool.gd @@ -1,8 +1,8 @@ -class_name BaseTool extends VBoxContainer +class_name BaseTool +extends VBoxContainer - -var kname : String -var tool_slot : Tools.Slot = null +var kname: String +var tool_slot: Tools.Slot = null var cursor_text := "" var _cursor := Vector2.INF @@ -20,29 +20,47 @@ func _ready() -> void: $Mirror/Vertical.modulate = Global.modulate_icon_color -func _on_PixelPerfect_toggled(button_pressed : bool) -> void: +func _on_PixelPerfect_toggled(button_pressed: bool) -> void: tool_slot.pixel_perfect = button_pressed tool_slot.save_config() -func _on_Horizontal_toggled(button_pressed : bool) -> void: +func _on_Horizontal_toggled(button_pressed: bool) -> void: tool_slot.horizontal_mirror = button_pressed tool_slot.save_config() Global.show_y_symmetry_axis = button_pressed # If the button is not pressed but another button is, keep the symmetry guide visible - if !button_pressed and (Tools._slots[BUTTON_LEFT].horizontal_mirror or Tools._slots[BUTTON_RIGHT].horizontal_mirror): + if ( + !button_pressed + and ( + Tools._slots[BUTTON_LEFT].horizontal_mirror + or Tools._slots[BUTTON_RIGHT].horizontal_mirror + ) + ): Global.show_y_symmetry_axis = true - Global.current_project.y_symmetry_axis.visible = Global.show_y_symmetry_axis and Global.show_guides + Global.current_project.y_symmetry_axis.visible = ( + Global.show_y_symmetry_axis + and Global.show_guides + ) -func _on_Vertical_toggled(button_pressed : bool) -> void: +func _on_Vertical_toggled(button_pressed: bool) -> void: tool_slot.vertical_mirror = button_pressed tool_slot.save_config() Global.show_x_symmetry_axis = button_pressed # If the button is not pressed but another button is, keep the symmetry guide visible - if !button_pressed and (Tools._slots[BUTTON_LEFT].vertical_mirror or Tools._slots[BUTTON_RIGHT].vertical_mirror): + if ( + !button_pressed + and ( + Tools._slots[BUTTON_LEFT].vertical_mirror + or Tools._slots[BUTTON_RIGHT].vertical_mirror + ) + ): Global.show_x_symmetry_axis = true - Global.current_project.x_symmetry_axis.visible = Global.show_x_symmetry_axis and Global.show_guides + Global.current_project.x_symmetry_axis.visible = ( + Global.show_x_symmetry_axis + and Global.show_guides + ) func save_config() -> void: @@ -60,7 +78,7 @@ func get_config() -> Dictionary: return {} -func set_config(_config : Dictionary) -> void: +func set_config(_config: Dictionary) -> void: pass @@ -68,7 +86,7 @@ func update_config() -> void: pass -func cursor_move(position : Vector2) -> void: +func cursor_move(position: Vector2) -> void: _cursor = position @@ -89,20 +107,20 @@ func _get_draw_rect() -> Rect2: func _get_draw_image() -> Image: - var project : Project = Global.current_project + var project: Project = Global.current_project return project.frames[project.current_frame].cels[project.current_layer].image -func _get_selected_draw_images() -> Array: # Array of Images +func _get_selected_draw_images() -> Array: # Array of Images var images := [] - var project : Project = Global.current_project + var project: Project = Global.current_project for cel_index in project.selected_cels: - var cel : Cel = project.frames[cel_index[0]].cels[cel_index[1]] + var cel: Cel = project.frames[cel_index[0]].cels[cel_index[1]] images.append(cel.image) return images -func _flip_rect(rect : Rect2, size : Vector2, horizontal : bool, vertical : bool) -> Rect2: +func _flip_rect(rect: Rect2, size: Vector2, horizontal: bool, vertical: bool) -> Rect2: var result := rect if horizontal: result.position.x = size.x - rect.end.x @@ -113,7 +131,7 @@ func _flip_rect(rect : Rect2, size : Vector2, horizontal : bool, vertical : bool return result.abs() -func _create_polylines(bitmap : BitMap) -> Array: +func _create_polylines(bitmap: BitMap) -> Array: var lines := [] var size := bitmap.get_size() for y in size.y: @@ -132,7 +150,7 @@ func _create_polylines(bitmap : BitMap) -> Array: return lines -func _add_polylines_segment(lines : Array, start : Vector2, end : Vector2) -> void: +func _add_polylines_segment(lines: Array, start: Vector2, end: Vector2) -> void: for line in lines: if line[0] == start: line.insert(0, end) diff --git a/src/Tools/Bucket.gd b/src/Tools/Bucket.gd index d03b8269a..a3617663e 100644 --- a/src/Tools/Bucket.gd +++ b/src/Tools/Bucket.gd @@ -1,8 +1,7 @@ extends BaseTool - var _prev_mode := 0 -var _pattern : Patterns.Pattern +var _pattern: Patterns.Pattern var _fill_area := 0 var _fill_with := 0 var _offset_x := 0 @@ -14,7 +13,7 @@ func _ready() -> void: func _input(event: InputEvent) -> void: - var options : OptionButton = $FillAreaOptions + var options: OptionButton = $FillAreaOptions if event.is_action_pressed("ctrl"): _prev_mode = options.selected @@ -26,36 +25,38 @@ func _input(event: InputEvent) -> void: _fill_area = options.selected -func _on_FillAreaOptions_item_selected(index : int) -> void: +func _on_FillAreaOptions_item_selected(index: int) -> void: _fill_area = index update_config() save_config() -func _on_FillWithOptions_item_selected(index : int) -> void: +func _on_FillWithOptions_item_selected(index: int) -> void: _fill_with = index update_config() save_config() func _on_PatternType_pressed(): - Global.patterns_popup.connect("pattern_selected", self, "_on_Pattern_selected", [], CONNECT_ONESHOT) + Global.patterns_popup.connect( + "pattern_selected", self, "_on_Pattern_selected", [], CONNECT_ONESHOT + ) Global.patterns_popup.popup(Rect2($FillPattern/Type.rect_global_position, Vector2(226, 72))) -func _on_Pattern_selected(pattern : Patterns.Pattern) -> void: +func _on_Pattern_selected(pattern: Patterns.Pattern) -> void: _pattern = pattern update_pattern() save_config() -func _on_PatternOffsetX_value_changed(value : float) -> void: +func _on_PatternOffsetX_value_changed(value: float) -> void: _offset_x = int(value) update_config() save_config() -func _on_PatternOffsetY_value_changed(value : float) -> void: +func _on_PatternOffsetY_value_changed(value: float) -> void: _offset_y = int(value) update_config() save_config() @@ -65,15 +66,15 @@ func get_config() -> Dictionary: if !_pattern: return {} return { - "pattern_index" : _pattern.index, - "fill_area" : _fill_area, - "fill_with" : _fill_with, - "offset_x" : _offset_x, - "offset_y" : _offset_y, + "pattern_index": _pattern.index, + "fill_area": _fill_area, + "fill_with": _fill_with, + "offset_x": _offset_x, + "offset_y": _offset_y, } -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: if _pattern: var index = config.get("pattern_index", _pattern.index) _pattern = Global.patterns_popup.get_pattern(index) @@ -107,15 +108,21 @@ func update_pattern() -> void: $FillPattern/YOffset/OffsetY.max_value = size.y - 1 -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if Input.is_action_pressed("alt"): _pick_color(position) return Global.canvas.selection.transform_content_confirm() - if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn() or !Global.current_project.tile_mode_rects[Global.TileMode.NONE].has_point(position): + if ( + !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn() + or !Global.current_project.tile_mode_rects[Global.TileMode.NONE].has_point(position) + ): return - if Global.current_project.has_selection and not Global.current_project.can_pixel_get_drawn(position): + if ( + Global.current_project.has_selection + and not Global.current_project.can_pixel_get_drawn(position) + ): return var undo_data = _get_undo_data() if _fill_area == 0: @@ -125,17 +132,17 @@ func draw_start(position : Vector2) -> void: commit_undo("Draw", undo_data) -func draw_move(_position : Vector2) -> void: +func draw_move(_position: Vector2) -> void: pass -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: pass -func fill_in_color(position : Vector2) -> void: - var project : Project = Global.current_project - var color : Color = _get_draw_image().get_pixelv(position) +func fill_in_color(position: Vector2) -> void: + var project: Project = Global.current_project + var color: Color = _get_draw_image().get_pixelv(position) var images := _get_selected_draw_images() for image in images: if _fill_with == 0 or _pattern == null: @@ -151,15 +158,15 @@ func fill_in_color(position : Vector2) -> void: _set_pixel(image, x, y, tool_slot.color) -func fill_in_area(position : Vector2) -> void: - var project : Project = Global.current_project +func fill_in_area(position: Vector2) -> void: + var project: Project = Global.current_project _flood_fill(position) # Handle Mirroring var mirror_x = project.x_symmetry_point - position.x var mirror_y = project.y_symmetry_point - position.y - var mirror_x_inside : bool - var mirror_y_inside : bool + var mirror_x_inside: bool + var mirror_y_inside: bool mirror_x_inside = project.can_pixel_get_drawn(Vector2(mirror_x, position.y)) mirror_y_inside = project.can_pixel_get_drawn(Vector2(position.x, mirror_y)) @@ -172,11 +179,11 @@ func fill_in_area(position : Vector2) -> void: _flood_fill(Vector2(position.x, mirror_y)) -func _flood_fill(position : Vector2) -> void: - var project : Project = Global.current_project +func _flood_fill(position: Vector2) -> void: + var project: Project = Global.current_project var images := _get_selected_draw_images() for image in images: - var color : Color = image.get_pixelv(position) + var color: Color = image.get_pixelv(position) if _fill_with == 0 or _pattern == null: if tool_slot.color.is_equal_approx(color): return @@ -187,11 +194,17 @@ func _flood_fill(position : Vector2) -> void: for n in q: if processed.get_bit(n): continue - var west : Vector2 = n - var east : Vector2 = n - while project.can_pixel_get_drawn(west) && image.get_pixelv(west).is_equal_approx(color): + var west: Vector2 = n + var east: Vector2 = n + while ( + project.can_pixel_get_drawn(west) + && image.get_pixelv(west).is_equal_approx(color) + ): west += Vector2.LEFT - while project.can_pixel_get_drawn(east) && image.get_pixelv(east).is_equal_approx(color): + while ( + project.can_pixel_get_drawn(east) + && image.get_pixelv(east).is_equal_approx(color) + ): east += Vector2.RIGHT for px in range(west.x + 1, east.x): var p := Vector2(px, n.y) @@ -199,14 +212,20 @@ func _flood_fill(position : Vector2) -> void: processed.set_bit(p, true) var north := p + Vector2.UP var south := p + Vector2.DOWN - if project.can_pixel_get_drawn(north) && image.get_pixelv(north).is_equal_approx(color): + if ( + project.can_pixel_get_drawn(north) + && image.get_pixelv(north).is_equal_approx(color) + ): q.append(north) - if project.can_pixel_get_drawn(south) && image.get_pixelv(south).is_equal_approx(color): + if ( + project.can_pixel_get_drawn(south) + && image.get_pixelv(south).is_equal_approx(color) + ): q.append(south) -func _set_pixel(image : Image, x : int, y : int, color : Color) -> void: - var project : Project = Global.current_project +func _set_pixel(image: Image, x: int, y: int, color: Color) -> void: + var project: Project = Global.current_project if !project.can_pixel_get_drawn(Vector2(x, y)): return @@ -222,9 +241,9 @@ func _set_pixel(image : Image, x : int, y : int, color : Color) -> void: image.set_pixel(x, y, pc) -func commit_undo(action : String, undo_data : Dictionary) -> void: +func commit_undo(action: String, undo_data: Dictionary) -> void: var redo_data := _get_undo_data() - var project : Project = Global.current_project + var project: Project = Global.current_project var frame := -1 var layer := -1 if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1: @@ -253,8 +272,8 @@ func _get_undo_data() -> Dictionary: return data -func _pick_color(position : Vector2) -> void: - var project : Project = Global.current_project +func _pick_color(position: Vector2) -> void: + var project: Project = Global.current_project if project.tile_mode and project.get_tile_mode_rect().has_point(position): position = position.posmodv(project.size) diff --git a/src/Tools/ColorPicker.gd b/src/Tools/ColorPicker.gd index cf1e20a74..0e434f1d3 100644 --- a/src/Tools/ColorPicker.gd +++ b/src/Tools/ColorPicker.gd @@ -1,12 +1,11 @@ extends BaseTool - var _prev_mode := 0 var _color_slot := 0 func _input(event: InputEvent) -> void: - var options : OptionButton = $ColorPicker/Options + var options: OptionButton = $ColorPicker/Options if event.is_action_pressed("ctrl"): _prev_mode = options.selected @@ -18,7 +17,7 @@ func _input(event: InputEvent) -> void: _color_slot = options.selected -func _on_Options_item_selected(id : int) -> void: +func _on_Options_item_selected(id: int) -> void: _color_slot = id update_config() save_config() @@ -26,11 +25,11 @@ func _on_Options_item_selected(id : int) -> void: func get_config() -> Dictionary: return { - "color_slot" : _color_slot, + "color_slot": _color_slot, } -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: _color_slot = config.get("color_slot", _color_slot) @@ -38,20 +37,20 @@ func update_config() -> void: $ColorPicker/Options.selected = _color_slot -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: _pick_color(position) -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: _pick_color(position) -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: pass -func _pick_color(position : Vector2) -> void: - var project : Project = Global.current_project +func _pick_color(position: Vector2) -> void: + var project: Project = Global.current_project if project.tile_mode and project.get_tile_mode_rect().has_point(position): position = position.posmodv(project.size) diff --git a/src/Tools/Draw.gd b/src/Tools/Draw.gd index d1785810c..b6b495339 100644 --- a/src/Tools/Draw.gd +++ b/src/Tools/Draw.gd @@ -1,6 +1,5 @@ extends BaseTool - var _brush := Brushes.get_default_brush() var _brush_size := 1 var _brush_interpolate := 0 @@ -22,6 +21,7 @@ var _indicator := BitMap.new() var _polylines := [] var _line_polylines := [] + func _ready() -> void: Tools.connect("color_changed", self, "_on_Color_changed") Global.brushes_popup.connect("brush_removed", self, "_on_Brush_removed") @@ -29,33 +29,35 @@ func _ready() -> void: func _on_BrushType_pressed() -> void: if not Global.brushes_popup.is_connected("brush_selected", self, "_on_Brush_selected"): - Global.brushes_popup.connect("brush_selected", self, "_on_Brush_selected", [], CONNECT_ONESHOT) + Global.brushes_popup.connect( + "brush_selected", self, "_on_Brush_selected", [], CONNECT_ONESHOT + ) Global.brushes_popup.popup(Rect2($Brush/Type.rect_global_position, Vector2(226, 72))) -func _on_Brush_selected(brush : Brushes.Brush) -> void: +func _on_Brush_selected(brush: Brushes.Brush) -> void: _brush = brush update_brush() save_config() -func _on_BrushSize_value_changed(value : float) -> void: +func _on_BrushSize_value_changed(value: float) -> void: _brush_size = int(value) update_config() save_config() -func _on_InterpolateFactor_value_changed(value : float) -> void: +func _on_InterpolateFactor_value_changed(value: float) -> void: _brush_interpolate = int(value) update_config() save_config() -func _on_Color_changed(_color : Color, _button : int) -> void: +func _on_Color_changed(_color: Color, _button: int) -> void: update_brush() -func _on_Brush_removed(brush : Brushes.Brush) -> void: +func _on_Brush_removed(brush: Brushes.Brush) -> void: if brush == _brush: _brush = Brushes.get_default_brush() update_brush() @@ -64,14 +66,14 @@ func _on_Brush_removed(brush : Brushes.Brush) -> void: func get_config() -> Dictionary: return { - "brush_type" : _brush.type, - "brush_index" : _brush.index, - "brush_size" : _brush_size, - "brush_interpolate" : _brush_interpolate, + "brush_type": _brush.type, + "brush_index": _brush.index, + "brush_size": _brush_size, + "brush_interpolate": _brush_interpolate, } -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: var type = config.get("brush_type", _brush.type) var index = config.get("brush_index", _brush.index) _brush = Global.brushes_popup.get_brush(type, index) @@ -131,14 +133,15 @@ func update_mirror_brush() -> void: func update_mask(can_skip := true) -> void: if can_skip and Global.pressure_sensitivity_mode == Global.PressureSensitivity.NONE: return - var size : Vector2 = Global.current_project.size - # Faster than zeroing PoolByteArray directly. See: https://github.com/Orama-Interactive/Pixelorama/pull/439 + var size: Vector2 = Global.current_project.size + # Faster than zeroing PoolByteArray directly. + # See: https://github.com/Orama-Interactive/Pixelorama/pull/439 var nulled_array := [] nulled_array.resize(size.x * size.y) _mask = PoolByteArray(nulled_array) -func update_line_polylines(start : Vector2, end : Vector2) -> void: +func update_line_polylines(start: Vector2, end: Vector2) -> void: var indicator := _create_line_indicator(_indicator, start, end) _line_polylines = _create_polylines(indicator) @@ -147,9 +150,9 @@ func prepare_undo() -> void: _undo_data = _get_undo_data() -func commit_undo(action : String) -> void: +func commit_undo(action: String) -> void: var redo_data := _get_undo_data() - var project : Project = Global.current_project + var project: Project = Global.current_project var frame := -1 var layer := -1 if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1: @@ -170,7 +173,7 @@ func commit_undo(action : String) -> void: _undo_data.clear() -func draw_tool(position : Vector2) -> void: +func draw_tool(position: Vector2) -> void: if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn(): return var strength := _strength @@ -195,7 +198,7 @@ func draw_tool(position : Vector2) -> void: # Bresenham's Algorithm # Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency -func draw_fill_gap(start : Vector2, end : Vector2) -> void: +func draw_fill_gap(start: Vector2, end: Vector2) -> void: var dx := int(abs(end.x - start.x)) var dy := int(-abs(end.y - start.y)) var err := dx + dy @@ -215,7 +218,7 @@ func draw_fill_gap(start : Vector2, end : Vector2) -> void: draw_tool(Vector2(x, y)) -func draw_tool_pixel(position : Vector2) -> void: +func draw_tool_pixel(position: Vector2) -> void: var start := position - Vector2.ONE * (_brush_size >> 1) var end := start + Vector2.ONE * _brush_size for y in range(start.y, end.y): @@ -224,7 +227,7 @@ func draw_tool_pixel(position : Vector2) -> void: # Algorithm based on http://members.chello.at/easyfilter/bresenham.html -func draw_tool_circle(position : Vector2, fill := false) -> void: +func draw_tool_circle(position: Vector2, fill := false) -> void: var r := _brush_size var x := -r var y := 0 @@ -250,8 +253,8 @@ func draw_tool_circle(position : Vector2, fill := false) -> void: err += x * 2 + 1 -func draw_tool_brush(position : Vector2) -> void: - var project : Project = Global.current_project +func draw_tool_brush(position: Vector2) -> void: + var project: Project = Global.current_project if project.tile_mode and project.get_tile_mode_rect().has_point(position): position = position.posmodv(project.size) @@ -265,7 +268,7 @@ func draw_tool_brush(position : Vector2) -> void: return var src_rect := Rect2(dst_rect.position - dst, dst_rect.size) dst = dst_rect.position - var brush_image : Image = remove_unselected_parts_of_brush(_brush_image, dst) + var brush_image: Image = remove_unselected_parts_of_brush(_brush_image, dst) _draw_brush_image(brush_image, src_rect, dst) # Handle Mirroring @@ -274,20 +277,22 @@ func draw_tool_brush(position : Vector2) -> void: if tool_slot.horizontal_mirror: var x_dst := Vector2(mirror_x, dst.y) - var mirror_brush_x : Image = remove_unselected_parts_of_brush(_mirror_brushes.x, x_dst) + var mirror_brush_x: Image = remove_unselected_parts_of_brush(_mirror_brushes.x, x_dst) _draw_brush_image(mirror_brush_x, _flip_rect(src_rect, size, true, false), x_dst) if tool_slot.vertical_mirror: var xy_dst := Vector2(mirror_x, mirror_y) - var mirror_brush_xy : Image = remove_unselected_parts_of_brush(_mirror_brushes.xy, xy_dst) + var mirror_brush_xy: Image = remove_unselected_parts_of_brush( + _mirror_brushes.xy, xy_dst + ) _draw_brush_image(mirror_brush_xy, _flip_rect(src_rect, size, true, true), xy_dst) if tool_slot.vertical_mirror: var y_dst := Vector2(dst.x, mirror_y) - var mirror_brush_y : Image = remove_unselected_parts_of_brush(_mirror_brushes.y, y_dst) + var mirror_brush_y: Image = remove_unselected_parts_of_brush(_mirror_brushes.y, y_dst) _draw_brush_image(mirror_brush_y, _flip_rect(src_rect, size, false, true), y_dst) -func remove_unselected_parts_of_brush(brush : Image, dst : Vector2) -> Image: - var project : Project = Global.current_project +func remove_unselected_parts_of_brush(brush: Image, dst: Vector2) -> Image: + var project: Project = Global.current_project if !project.has_selection: return brush var size := brush.get_size() @@ -306,14 +311,17 @@ func remove_unselected_parts_of_brush(brush : Image, dst : Vector2) -> Image: func draw_indicator() -> void: draw_indicator_at(_cursor, Vector2.ZERO, Color.blue) - if Global.current_project.tile_mode and Global.current_project.get_tile_mode_rect().has_point(_cursor): + if ( + Global.current_project.tile_mode + and Global.current_project.get_tile_mode_rect().has_point(_cursor) + ): var tile := _line_start if _draw_line else _cursor if not Global.current_project.tile_mode_rects[Global.TileMode.NONE].has_point(tile): var offset := tile - tile.posmodv(Global.current_project.size) draw_indicator_at(_cursor, offset, Color.green) -func draw_indicator_at(position : Vector2, offset : Vector2, color : Color) -> void: +func draw_indicator_at(position: Vector2, offset: Vector2, color: Color) -> void: var canvas = Global.canvas.indicators if _brush.type in [Brushes.FILE, Brushes.RANDOM_FILE, Brushes.CUSTOM] and not _draw_line: position -= (_brush_image.get_size() / 2).floor() @@ -333,8 +341,8 @@ func draw_indicator_at(position : Vector2, offset : Vector2, color : Color) -> v canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale) -func _set_pixel(position : Vector2, ignore_mirroring := false) -> void: - var project : Project = Global.current_project +func _set_pixel(position: Vector2, ignore_mirroring := false) -> void: + var project: Project = Global.current_project if project.tile_mode and project.get_tile_mode_rect().has_point(position): position = position.posmodv(project.size) @@ -353,11 +361,11 @@ func _set_pixel(position : Vector2, ignore_mirroring := false) -> void: _drawer.set_pixel(image, position, tool_slot.color, ignore_mirroring) -func _draw_brush_image(_image : Image, _src_rect: Rect2, _dst: Vector2) -> void: +func _draw_brush_image(_image: Image, _src_rect: Rect2, _dst: Vector2) -> void: pass -func _create_blended_brush_image(image : Image) -> Image: +func _create_blended_brush_image(image: Image) -> Image: var size := image.get_size() * _brush_size var brush := Image.new() brush.copy_from(image) @@ -366,7 +374,7 @@ func _create_blended_brush_image(image : Image) -> Image: return brush -func _blend_image(image : Image, color : Color, factor : float) -> Image: +func _blend_image(image: Image, color: Color, factor: float) -> Image: var size := image.get_size() image.lock() for y in size.y: @@ -392,20 +400,20 @@ func _create_brush_indicator() -> BitMap: return _create_image_indicator(_brush_image) -func _create_image_indicator(image : Image) -> BitMap: +func _create_image_indicator(image: Image) -> BitMap: var bitmap := BitMap.new() bitmap.create_from_image_alpha(image, 0.0) return bitmap -func _create_pixel_indicator(size : int) -> BitMap: +func _create_pixel_indicator(size: int) -> BitMap: var bitmap := BitMap.new() bitmap.create(Vector2.ONE * size) bitmap.set_bit_rect(Rect2(Vector2.ZERO, Vector2.ONE * size), true) return bitmap -func _create_circle_indicator(size : int, fill := false) -> BitMap: +func _create_circle_indicator(size: int, fill := false) -> BitMap: var bitmap := BitMap.new() bitmap.create(Vector2.ONE * (size * 2 + 1)) var position := Vector2(size, size) @@ -436,7 +444,7 @@ func _create_circle_indicator(size : int, fill := false) -> BitMap: return bitmap -func _create_line_indicator(indicator : BitMap, start : Vector2, end : Vector2) -> BitMap: +func _create_line_indicator(indicator: BitMap, start: Vector2, end: Vector2) -> BitMap: var bitmap := BitMap.new() var size := (end - start).abs() + indicator.get_size() bitmap.create(size) @@ -471,7 +479,7 @@ func _create_line_indicator(indicator : BitMap, start : Vector2, end : Vector2) return bitmap -func _blit_indicator(dst : BitMap, indicator : BitMap, position : Vector2) -> void: +func _blit_indicator(dst: BitMap, indicator: BitMap, position: Vector2) -> void: var rect := Rect2(Vector2.ZERO, dst.get_size()) var size := indicator.get_size() position -= (size / 2).floor() @@ -484,7 +492,7 @@ func _blit_indicator(dst : BitMap, indicator : BitMap, position : Vector2) -> vo dst.set_bit(pos, bit) -func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary: +func _line_angle_constraint(start: Vector2, end: Vector2) -> Dictionary: var result := {} var angle := rad2deg(end.angle_to_point(start)) var distance := start.distance_to(end) @@ -493,7 +501,7 @@ func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary: angle = stepify(angle, 22.5) if step_decimals(angle) != 0: var diff := end - start - var v := Vector2(2 , 1) if abs(diff.x) > abs(diff.y) else Vector2(1 , 2) + var v := Vector2(2, 1) if abs(diff.x) > abs(diff.y) else Vector2(1, 2) var p := diff.project(diff.sign() * v).abs().round() var f := p.y if abs(diff.x) > abs(diff.y) else p.x end = start + diff.sign() * v * f - diff.sign() @@ -512,25 +520,25 @@ func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary: func _get_undo_data() -> Dictionary: var data := {} - var project : Project = Global.current_project - var cels := [] # Array of Cels + var project: Project = Global.current_project + var cels := [] # Array of Cels if Global.animation_timer.is_stopped(): for cel_index in project.selected_cels: cels.append(project.frames[cel_index[0]].cels[cel_index[1]]) else: for frame in project.frames: - var cel : Cel = frame.cels[project.current_layer] + var cel: Cel = frame.cels[project.current_layer] cels.append(cel) for cel in cels: - var image : Image = cel.image + var image: Image = cel.image image.unlock() data[image] = image.data image.lock() return data -func _pick_color(position : Vector2) -> void: - var project : Project = Global.current_project +func _pick_color(position: Vector2) -> void: + var project: Project = Global.current_project if project.tile_mode and project.get_tile_mode_rect().has_point(position): position = position.posmodv(project.size) diff --git a/src/Tools/EllipseTool.gd b/src/Tools/EllipseTool.gd index f25cff010..2ce3a6a8e 100644 --- a/src/Tools/EllipseTool.gd +++ b/src/Tools/EllipseTool.gd @@ -42,18 +42,22 @@ func _get_shape_points(size: Vector2) -> PoolVector2Array: var new_size := size + size_offset var inner_ellipse_size = new_size - 2 * size_offset - # The inner ellipse is to small to create a gap in the middle of the ellipse, just return a filled ellipse + # The inner ellipse is to small to create a gap in the middle of the ellipse, + # just return a filled ellipse if inner_ellipse_size.x <= 2 and inner_ellipse_size.y <= 2: return _get_shape_points_filled(size) # Adapted scanline algorithm to fill between 2 ellipses, to create a thicker ellipse var res_array := [] - var border_ellipses := _get_ellipse_points(Vector2.ZERO, new_size) + _get_ellipse_points(size_offset, inner_ellipse_size) # Outer and inner ellipses + var border_ellipses := ( + _get_ellipse_points(Vector2.ZERO, new_size) + + _get_ellipse_points(size_offset, inner_ellipse_size) + ) # Outer and inner ellipses var bitmap := _fill_bitmap_with_points(border_ellipses, new_size) - var smallest_side := min (new_size.x, new_size.y) - var largest_side := max (new_size.x, new_size.y) - var scan_dir := Vector2(0, 1) if smallest_side == new_size.x else Vector2(1,0) - var iscan_dir := Vector2(1, 0) if smallest_side == new_size.x else Vector2(0,1) + var smallest_side := min(new_size.x, new_size.y) + var largest_side := max(new_size.x, new_size.y) + var scan_dir := Vector2(0, 1) if smallest_side == new_size.x else Vector2(1, 0) + var iscan_dir := Vector2(1, 0) if smallest_side == new_size.x else Vector2(0, 1) var ie_relevant_offset_side = size_offset.x if smallest_side == new_size.x else size_offset.y var h_ls_c := ceil(largest_side / 2) @@ -74,7 +78,7 @@ func _get_shape_points(size: Vector2) -> PoolVector2Array: else: # Find outer ellipse var l_o := 0 - for l in range (h_ls_c): + for l in range(h_ls_c): var pos := scan_dir * l + iscan_dir * s if bitmap.get_bit(pos): l_o = l @@ -100,7 +104,7 @@ func _get_shape_points(size: Vector2) -> PoolVector2Array: # Algorithm based on http://members.chello.at/easyfilter/bresenham.html -func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: +func _get_ellipse_points(pos: Vector2, size: Vector2) -> Array: var array := [] var x0 := int(pos.x) var x1 := pos.x + int(size.x - 1) @@ -109,9 +113,9 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: var a := int(abs(x1 - x0)) var b := int(abs(y1 - x0)) var b1 := b & 1 - var dx := 4*(1-a)*b*b - var dy := 4*(b1+1)*a*a - var err := dx+dy+b1*a*a + var dx := 4 * (1 - a) * b * b + var dy := 4 * (b1 + 1) * a * a + var err := dx + dy + b1 * a * a var e2 := 0 if x0 > x1: @@ -122,10 +126,10 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: y0 = y1 # warning-ignore:integer_division - y0 += (b+1) / 2 - y1 = y0-b1 - a *= 8*a - b1 = 8*b*b + y0 += (b + 1) / 2 + y1 = y0 - b1 + a *= 8 * a + b1 = 8 * b * b while x0 <= x1: var v1 := Vector2(x1, y0) @@ -137,7 +141,7 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: array.append(v3) array.append(v4) - e2 = 2*err; + e2 = 2 * err if e2 <= dy: y0 += 1 @@ -145,23 +149,23 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: dy += a err += dy - if e2 >= dx || 2*err > dy: - x0+=1 - x1-=1 + if e2 >= dx || 2 * err > dy: + x0 += 1 + x1 -= 1 dx += b1 err += dx - while y0-y1 < b: - var v1 := Vector2(x0-1, y0) - var v2 := Vector2(x1+1, y0) - var v3 := Vector2(x0-1, y1) - var v4 := Vector2(x1+1, y1) + while y0 - y1 < b: + var v1 := Vector2(x0 - 1, y0) + var v2 := Vector2(x1 + 1, y0) + var v3 := Vector2(x0 - 1, y1) + var v4 := Vector2(x1 + 1, y1) array.append(v1) array.append(v2) array.append(v3) array.append(v4) - y0+=1 - y1-=1 + y0 += 1 + y1 -= 1 return array diff --git a/src/Tools/Eraser.gd b/src/Tools/Eraser.gd index d1d209392..518034edf 100644 --- a/src/Tools/Eraser.gd +++ b/src/Tools/Eraser.gd @@ -1,12 +1,12 @@ extends "res://src/Tools/Draw.gd" - var _last_position := Vector2.INF var _clear_image := Image.new() var _changed := false -class EraseOp extends Drawer.ColorOp: +class EraseOp: + extends Drawer.ColorOp var changed := false func process(_src: Color, dst: Color) -> Color: @@ -29,12 +29,12 @@ func get_config() -> Dictionary: return config -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: .set_config(config) _strength = config.get("strength", _strength) -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if Input.is_action_pressed("alt"): _picking_color = true _pick_color(position) @@ -61,8 +61,8 @@ func draw_start(position : Vector2) -> void: cursor_text = "" -func draw_move(position : Vector2) -> void: - if _picking_color: # Still return even if we released Alt +func draw_move(position: Vector2) -> void: + if _picking_color: # Still return even if we released Alt if Input.is_action_pressed("alt"): _pick_color(position) return @@ -79,7 +79,7 @@ func draw_move(position : Vector2) -> void: Global.canvas.sprite_changed_this_frame = true -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: if _picking_color: return @@ -93,7 +93,7 @@ func draw_end(_position : Vector2) -> void: update_random_image() -func _draw_brush_image(image : Image, src_rect: Rect2, dst: Vector2) -> void: +func _draw_brush_image(image: Image, src_rect: Rect2, dst: Vector2) -> void: _changed = true if _strength == 1: var size := image.get_size() diff --git a/src/Tools/LineTool.gd b/src/Tools/LineTool.gd index caad1e1a1..1e3f07ee7 100644 --- a/src/Tools/LineTool.gd +++ b/src/Tools/LineTool.gd @@ -1,6 +1,5 @@ extends "res://src/Tools/Draw.gd" - var _original_pos := Vector2.ZERO var _start := Vector2.ZERO var _offset := Vector2.ZERO @@ -60,7 +59,7 @@ func _get_shape_points_filled(_size: Vector2) -> PoolVector2Array: return PoolVector2Array() -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if _drawing: if event.is_action_pressed("alt"): _displace_origin = true @@ -68,7 +67,7 @@ func _input(event : InputEvent) -> void: _displace_origin = false -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if Input.is_action_pressed("alt"): _picking_color = true _pick_color(position) @@ -85,8 +84,8 @@ func draw_start(position : Vector2) -> void: _drawing = true -func draw_move(position : Vector2) -> void: - if _picking_color: # Still return even if we released Alt +func draw_move(position: Vector2) -> void: + if _picking_color: # Still return even if we released Alt if Input.is_action_pressed("alt"): _pick_color(position) return @@ -104,7 +103,7 @@ func draw_move(position : Vector2) -> void: _offset = position -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: if _picking_color: return @@ -121,7 +120,7 @@ func draw_end(_position : Vector2) -> void: func draw_preview() -> void: if _drawing: - var canvas : CanvasItem = Global.canvas.previews + var canvas: CanvasItem = Global.canvas.previews var indicator := BitMap.new() var start := _start if _start.x > _dest.x: @@ -135,7 +134,7 @@ func draw_preview() -> void: indicator.create((_dest - _start).abs() + t_offsetv * 2 + Vector2.ONE) for point in points: - var p : Vector2 = point - start + t_offsetv + var p: Vector2 = point - start + t_offsetv indicator.set_bit(p, 1) canvas.draw_set_transform(start - t_offsetv, canvas.rotation, canvas.scale) @@ -195,7 +194,7 @@ func _get_points() -> PoolVector2Array: return PoolVector2Array(array) -func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary: +func _line_angle_constraint(start: Vector2, end: Vector2) -> Dictionary: var result := {} var angle := rad2deg(end.angle_to_point(start)) var distance := start.distance_to(end) @@ -203,7 +202,7 @@ func _line_angle_constraint(start : Vector2, end : Vector2) -> Dictionary: angle = stepify(angle, 22.5) if step_decimals(angle) != 0: var diff := end - start - var v := Vector2(2 , 1) if abs(diff.x) > abs(diff.y) else Vector2(1 , 2) + var v := Vector2(2, 1) if abs(diff.x) > abs(diff.y) else Vector2(1, 2) var p := diff.project(diff.sign() * v).abs().round() var f := p.y if abs(diff.x) > abs(diff.y) else p.x end = start + diff.sign() * v * f - diff.sign() diff --git a/src/Tools/Move.gd b/src/Tools/Move.gd index ea8ec7fbd..4a09bc65d 100644 --- a/src/Tools/Move.gd +++ b/src/Tools/Move.gd @@ -1,19 +1,18 @@ extends BaseTool - var _undo_data := {} -var _start_pos : Vector2 -var _offset : Vector2 +var _start_pos: Vector2 +var _offset: Vector2 # Used to check if the state of content transformation has been changed # while draw_move() is being called. For example, pressing Enter while still moving content var _content_transformation_check := false -var _snap_to_grid := false # Mouse Click + Ctrl +var _snap_to_grid := false # Mouse Click + Ctrl -onready var selection_node : Node2D = Global.canvas.selection +onready var selection_node: Node2D = Global.canvas.selection -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if _start_pos != Vector2.INF: if event.is_action_pressed("ctrl"): _snap_to_grid = true @@ -21,13 +20,16 @@ func _input(event : InputEvent) -> void: _offset = _offset.snapped(grid_size) if Global.current_project.has_selection: var prev_pos = selection_node.big_bounding_rectangle.position - selection_node.big_bounding_rectangle.position = selection_node.big_bounding_rectangle.position.snapped(grid_size) - selection_node.marching_ants_outline.offset += selection_node.big_bounding_rectangle.position - prev_pos + selection_node.big_bounding_rectangle.position = prev_pos.snapped(grid_size) + selection_node.marching_ants_outline.offset += ( + selection_node.big_bounding_rectangle.position + - prev_pos + ) elif event.is_action_released("ctrl"): _snap_to_grid = false -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn(): return _start_pos = position @@ -38,20 +40,20 @@ func draw_start(position : Vector2) -> void: _content_transformation_check = selection_node.is_moving_content -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn(): return # This is true if content transformation has been confirmed (pressed Enter for example) # while the content is being moved if _content_transformation_check != selection_node.is_moving_content: return - if Tools.shift: # Snap to axis + if Tools.shift: # Snap to axis var angle := position.angle_to_point(_start_pos) - if abs(angle) <= PI / 4 or abs(angle) >= 3*PI / 4: + if abs(angle) <= PI / 4 or abs(angle) >= 3 * PI / 4: position.y = _start_pos.y else: position.x = _start_pos.x - if _snap_to_grid: # Snap to grid + if _snap_to_grid: # Snap to grid position = position.snapped(Vector2(Global.grid_width, Global.grid_height)) position += Vector2(Global.grid_offset_x, Global.grid_offset_y) @@ -62,24 +64,26 @@ func draw_move(position : Vector2) -> void: _offset = position -func draw_end(position : Vector2) -> void: +func draw_end(position: Vector2) -> void: if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn(): return - if _start_pos != Vector2.INF and _content_transformation_check == selection_node.is_moving_content: - if Tools.shift: # Snap to axis + if ( + _start_pos != Vector2.INF + and _content_transformation_check == selection_node.is_moving_content + ): + if Tools.shift: # Snap to axis var angle := position.angle_to_point(_start_pos) - if abs(angle) <= PI / 4 or abs(angle) >= 3*PI / 4: + if abs(angle) <= PI / 4 or abs(angle) >= 3 * PI / 4: position.y = _start_pos.y else: position.x = _start_pos.x - if _snap_to_grid: # Snap to grid + if _snap_to_grid: # Snap to grid position = position.snapped(Vector2(Global.grid_width, Global.grid_height)) position += Vector2(Global.grid_offset_x, Global.grid_offset_y) - - var pixel_diff : Vector2 = position - _start_pos - var project : Project = Global.current_project + var pixel_diff: Vector2 = position - _start_pos + var project: Project = Global.current_project if project.has_selection: selection_node.move_borders_end() @@ -98,9 +102,9 @@ func draw_end(position : Vector2) -> void: _snap_to_grid = false -func commit_undo(action : String) -> void: +func commit_undo(action: String) -> void: var redo_data := _get_undo_data() - var project : Project = Global.current_project + var project: Project = Global.current_project var frame := -1 var layer := -1 if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1: @@ -123,17 +127,17 @@ func commit_undo(action : String) -> void: func _get_undo_data() -> Dictionary: var data := {} - var project : Project = Global.current_project - var cels := [] # Array of Cels + var project: Project = Global.current_project + var cels := [] # Array of Cels if Global.animation_timer.is_stopped(): for cel_index in project.selected_cels: cels.append(project.frames[cel_index[0]].cels[cel_index[1]]) else: for frame in project.frames: - var cel : Cel = frame.cels[project.current_layer] + var cel: Cel = frame.cels[project.current_layer] cels.append(cel) for cel in cels: - var image : Image = cel.image + var image: Image = cel.image image.unlock() data[image] = image.data image.lock() diff --git a/src/Tools/Pan.gd b/src/Tools/Pan.gd index 78e4172e5..9bb1909d9 100644 --- a/src/Tools/Pan.gd +++ b/src/Tools/Pan.gd @@ -1,15 +1,15 @@ extends BaseTool -func draw_start(_position : Vector2) -> void: +func draw_start(_position: Vector2) -> void: Global.camera.drag = true Global.camera2.drag = true -func draw_move(_position : Vector2) -> void: +func draw_move(_position: Vector2) -> void: pass -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: Global.camera.drag = false Global.camera2.drag = false diff --git a/src/Tools/Pencil.gd b/src/Tools/Pencil.gd index f9a6cdeaf..b6a4cf937 100644 --- a/src/Tools/Pencil.gd +++ b/src/Tools/Pencil.gd @@ -1,6 +1,5 @@ extends "res://src/Tools/Draw.gd" - var _prev_mode := false var _last_position := Vector2.INF var _changed := false @@ -9,7 +8,8 @@ var _fill_inside := false var _draw_points := Array() -class PencilOp extends Drawer.ColorOp: +class PencilOp: + extends Drawer.ColorOp var changed := false var overwrite := false @@ -25,7 +25,7 @@ func _init() -> void: _drawer.color_op = PencilOp.new() -func _on_Overwrite_toggled(button_pressed : bool): +func _on_Overwrite_toggled(button_pressed: bool): _overwrite = button_pressed update_config() save_config() @@ -38,7 +38,7 @@ func _on_FillInside_toggled(button_pressed): func _input(event: InputEvent) -> void: - var overwrite_button : CheckBox = $Overwrite + var overwrite_button: CheckBox = $Overwrite if event.is_action_pressed("ctrl"): _prev_mode = overwrite_button.pressed @@ -57,7 +57,7 @@ func get_config() -> Dictionary: return config -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: .set_config(config) _overwrite = config.get("overwrite", _overwrite) _fill_inside = config.get("fill_inside", _fill_inside) @@ -69,7 +69,7 @@ func update_config() -> void: $FillInside.pressed = _fill_inside -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if Input.is_action_pressed("alt"): _picking_color = true _pick_color(position) @@ -100,8 +100,8 @@ func draw_start(position : Vector2) -> void: cursor_text = "" -func draw_move(position : Vector2) -> void: - if _picking_color: # Still return even if we released Alt +func draw_move(position: Vector2) -> void: + if _picking_color: # Still return even if we released Alt if Input.is_action_pressed("alt"): _pick_color(position) return @@ -120,7 +120,7 @@ func draw_move(position : Vector2) -> void: _draw_points.append(position) -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: if _picking_color: return @@ -146,7 +146,7 @@ func draw_end(_position : Vector2) -> void: update_random_image() -func _draw_brush_image(image : Image, src_rect: Rect2, dst: Vector2) -> void: +func _draw_brush_image(image: Image, src_rect: Rect2, dst: Vector2) -> void: _changed = true var images := _get_selected_draw_images() if _overwrite: diff --git a/src/Tools/SelectionTools/ColorSelect.gd b/src/Tools/SelectionTools/ColorSelect.gd index 9e69dbd2d..d676c69be 100644 --- a/src/Tools/SelectionTools/ColorSelect.gd +++ b/src/Tools/SelectionTools/ColorSelect.gd @@ -1,8 +1,8 @@ extends SelectionTool -func apply_selection(position : Vector2) -> void: - var project : Project = Global.current_project +func apply_selection(position: Vector2) -> void: + var project: Project = Global.current_project if position.x < 0 or position.y < 0: return if position.x > project.size.x - 1 or position.y > project.size.y - 1: @@ -11,7 +11,7 @@ func apply_selection(position : Vector2) -> void: if !_add and !_subtract and !_intersect: Global.canvas.selection.clear_selection() - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() if _intersect: var full_rect = Rect2(Vector2.ZERO, selection_bitmap_copy.get_size()) selection_bitmap_copy.set_bit_rect(full_rect, false) @@ -31,5 +31,7 @@ func apply_selection(position : Vector2) -> void: cel_image.unlock() project.selection_bitmap = selection_bitmap_copy - Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap) + Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle( + project.selection_bitmap + ) Global.canvas.selection.commit_undo("Rectangle Select", undo_data) diff --git a/src/Tools/SelectionTools/EllipseSelect.gd b/src/Tools/SelectionTools/EllipseSelect.gd index 1924a8bc4..bfeb3f388 100644 --- a/src/Tools/SelectionTools/EllipseSelect.gd +++ b/src/Tools/SelectionTools/EllipseSelect.gd @@ -1,14 +1,13 @@ extends SelectionTool - var _rect := Rect2(0, 0, 0, 0) -var _square := false # Mouse Click + Shift -var _expand_from_center := false # Mouse Click + Ctrl -var _displace_origin = false # Mouse Click + Alt +var _square := false # Mouse Click + Shift +var _expand_from_center := false # Mouse Click + Ctrl +var _displace_origin = false # Mouse Click + Alt -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: ._input(event) if !_move and !_rect.has_no_area(): if event.is_action_pressed("shift"): @@ -25,7 +24,7 @@ func _input(event : InputEvent) -> void: _displace_origin = false -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: if selection_node.arrow_key_move: return .draw_move(position) @@ -37,7 +36,7 @@ func draw_move(position : Vector2) -> void: _offset = position -func draw_end(position : Vector2) -> void: +func draw_end(position: Vector2) -> void: if selection_node.arrow_key_move: return .draw_end(position) @@ -49,64 +48,78 @@ func draw_end(position : Vector2) -> void: func draw_preview() -> void: if !_move && !_rect.has_no_area(): - var canvas : Node2D = Global.canvas.previews - var _position := canvas.position - var _scale := canvas.scale + var canvas: Node2D = Global.canvas.previews + var position := canvas.position + var scale := canvas.scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 + position.x = position.x + Global.current_project.size.x + scale.x = -1 var border := _get_shape_points_filled(_rect.size) var indicator := _fill_bitmap_with_points(border, _rect.size) - canvas.draw_set_transform(_rect.position, canvas.rotation, _scale) + canvas.draw_set_transform(_rect.position, canvas.rotation, scale) for line in _create_polylines(indicator): canvas.draw_polyline(PoolVector2Array(line), Color.black) canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale) -func apply_selection(_position : Vector2) -> void: - var project : Project = Global.current_project +func apply_selection(_position: Vector2) -> void: + var project: Project = Global.current_project if !_add and !_subtract and !_intersect: Global.canvas.selection.clear_selection() if _rect.size == Vector2.ZERO and Global.current_project.has_selection: Global.canvas.selection.commit_undo("Rectangle Select", undo_data) if _rect.size != Vector2.ZERO: - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() set_ellipse(selection_bitmap_copy, _rect.position) # Handle mirroring if tool_slot.horizontal_mirror: var mirror_x_rect := _rect - mirror_x_rect.position.x = Global.current_project.x_symmetry_point - _rect.position.x + 1 + mirror_x_rect.position.x = ( + Global.current_project.x_symmetry_point + - _rect.position.x + + 1 + ) mirror_x_rect.end.x = Global.current_project.x_symmetry_point - _rect.end.x + 1 set_ellipse(selection_bitmap_copy, mirror_x_rect.abs().position) if tool_slot.vertical_mirror: var mirror_xy_rect := mirror_x_rect - mirror_xy_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y + 1 + mirror_xy_rect.position.y = ( + Global.current_project.y_symmetry_point + - _rect.position.y + + 1 + ) mirror_xy_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y + 1 set_ellipse(selection_bitmap_copy, mirror_xy_rect.abs().position) if tool_slot.vertical_mirror: var mirror_y_rect := _rect - mirror_y_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y + 1 + mirror_y_rect.position.y = ( + Global.current_project.y_symmetry_point + - _rect.position.y + + 1 + ) mirror_y_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y + 1 set_ellipse(selection_bitmap_copy, mirror_y_rect.abs().position) project.selection_bitmap = selection_bitmap_copy - Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap) + Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle( + project.selection_bitmap + ) Global.canvas.selection.commit_undo("Rectangle Select", undo_data) -func set_ellipse(bitmap : BitMap, position : Vector2) -> void: - var project : Project = Global.current_project - var bitmap_size : Vector2 = bitmap.get_size() +func set_ellipse(bitmap: BitMap, position: Vector2) -> void: + var project: Project = Global.current_project + var bitmap_size: Vector2 = bitmap.get_size() if _intersect: bitmap.set_bit_rect(Rect2(Vector2.ZERO, bitmap_size), false) var points := _get_shape_points_filled(_rect.size) for p in points: - var pos : Vector2 = position + p + var pos: Vector2 = position + p if pos.x < 0 or pos.y < 0 or pos.x >= bitmap_size.x or pos.y >= bitmap_size.y: continue if _intersect: @@ -116,7 +129,8 @@ func set_ellipse(bitmap : BitMap, position : Vector2) -> void: bitmap.set_bit(pos, !_subtract) -# Given an origin point and destination point, returns a rect representing where the shape will be drawn and what it's size +# Given an origin point and destination point, returns a rect representing +# where the shape will be drawn and what is its size func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: var rect := Rect2(Vector2.ZERO, Vector2.ZERO) @@ -125,8 +139,8 @@ func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: var new_size := (dest - origin).floor() # Make rect 1:1 while centering it on the mouse if _square: - var _square_size := max(abs(new_size.x), abs(new_size.y)) - new_size = Vector2(_square_size, _square_size) + var square_size := max(abs(new_size.x), abs(new_size.y)) + new_size = Vector2(square_size, square_size) origin -= new_size dest = origin + 2 * new_size @@ -179,7 +193,7 @@ func _get_shape_points_filled(size: Vector2) -> PoolVector2Array: # Algorithm based on http://members.chello.at/easyfilter/bresenham.html -func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: +func _get_ellipse_points(pos: Vector2, size: Vector2) -> Array: var array := [] var x0 := int(pos.x) var x1 := pos.x + int(size.x - 1) @@ -188,9 +202,9 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: var a := int(abs(x1 - x0)) var b := int(abs(y1 - x0)) var b1 := b & 1 - var dx := 4*(1-a)*b*b - var dy := 4*(b1+1)*a*a - var err := dx+dy+b1*a*a + var dx := 4 * (1 - a) * b * b + var dy := 4 * (b1 + 1) * a * a + var err := dx + dy + b1 * a * a var e2 := 0 if x0 > x1: @@ -201,10 +215,10 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: y0 = y1 # warning-ignore:integer_division - y0 += (b+1) / 2 - y1 = y0-b1 - a *= 8*a - b1 = 8*b*b + y0 += (b + 1) / 2 + y1 = y0 - b1 + a *= 8 * a + b1 = 8 * b * b while x0 <= x1: var v1 := Vector2(x1, y0) @@ -216,7 +230,7 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: array.append(v3) array.append(v4) - e2 = 2*err; + e2 = 2 * err if e2 <= dy: y0 += 1 @@ -224,23 +238,23 @@ func _get_ellipse_points (pos: Vector2, size: Vector2) -> Array: dy += a err += dy - if e2 >= dx || 2*err > dy: - x0+=1 - x1-=1 + if e2 >= dx || 2 * err > dy: + x0 += 1 + x1 -= 1 dx += b1 err += dx - while y0-y1 < b: - var v1 := Vector2(x0-1, y0) - var v2 := Vector2(x1+1, y0) - var v3 := Vector2(x0-1, y1) - var v4 := Vector2(x1+1, y1) + while y0 - y1 < b: + var v1 := Vector2(x0 - 1, y0) + var v2 := Vector2(x1 + 1, y0) + var v3 := Vector2(x0 - 1, y1) + var v4 := Vector2(x1 + 1, y1) array.append(v1) array.append(v2) array.append(v3) array.append(v4) - y0+=1 - y1-=1 + y0 += 1 + y1 -= 1 return array diff --git a/src/Tools/SelectionTools/Lasso.gd b/src/Tools/SelectionTools/Lasso.gd index a84548be5..d15d44b66 100644 --- a/src/Tools/SelectionTools/Lasso.gd +++ b/src/Tools/SelectionTools/Lasso.gd @@ -1,18 +1,17 @@ extends SelectionTool - var _last_position := Vector2.INF var _draw_points := [] -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: .draw_start(position) if !_move: _draw_points.append(position) _last_position = position -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: if selection_node.arrow_key_move: return .draw_move(position) @@ -23,7 +22,7 @@ func draw_move(position : Vector2) -> void: _offset = position -func draw_end(position : Vector2) -> void: +func draw_end(position: Vector2) -> void: if selection_node.arrow_key_move: return if !_move: @@ -33,13 +32,13 @@ func draw_end(position : Vector2) -> void: func draw_preview() -> void: if _last_position != Vector2.INF and !_move: - var canvas : Node2D = Global.canvas.previews - var _position := canvas.position - var _scale := canvas.scale + var canvas: Node2D = Global.canvas.previews + var position := canvas.position + var scale := canvas.scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 - canvas.draw_set_transform(_position, canvas.rotation, _scale) + position.x = position.x + Global.current_project.size.x + scale.x = -1 + canvas.draw_set_transform(position, canvas.rotation, scale) var indicator := _fill_bitmap_with_points(_draw_points, Global.current_project.size) for line in _create_polylines(indicator): @@ -47,27 +46,39 @@ func draw_preview() -> void: # Handle mirroring if tool_slot.horizontal_mirror: - for line in _create_polylines(_fill_bitmap_with_points(mirror_array(_draw_points, true, false), Global.current_project.size)): + for line in _create_polylines( + _fill_bitmap_with_points( + mirror_array(_draw_points, true, false), Global.current_project.size + ) + ): canvas.draw_polyline(PoolVector2Array(line), Color.black) if tool_slot.vertical_mirror: - for line in _create_polylines(_fill_bitmap_with_points(mirror_array(_draw_points, true, true), Global.current_project.size)): + for line in _create_polylines( + _fill_bitmap_with_points( + mirror_array(_draw_points, true, true), Global.current_project.size + ) + ): canvas.draw_polyline(PoolVector2Array(line), Color.black) if tool_slot.vertical_mirror: - for line in _create_polylines(_fill_bitmap_with_points(mirror_array(_draw_points, false, true), Global.current_project.size)): + for line in _create_polylines( + _fill_bitmap_with_points( + mirror_array(_draw_points, false, true), Global.current_project.size + ) + ): canvas.draw_polyline(PoolVector2Array(line), Color.black) canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale) func apply_selection(_position) -> void: - var project : Project = Global.current_project + var project: Project = Global.current_project var cleared := false if !_add and !_subtract and !_intersect: cleared = true Global.canvas.selection.clear_selection() if _draw_points.size() > 3: - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() - var bitmap_size : Vector2 = selection_bitmap_copy.get_size() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() + var bitmap_size: Vector2 = selection_bitmap_copy.get_size() if _intersect: selection_bitmap_copy.set_bit_rect(Rect2(Vector2.ZERO, bitmap_size), false) lasso_selection(selection_bitmap_copy, _draw_points) @@ -81,7 +92,9 @@ func apply_selection(_position) -> void: lasso_selection(selection_bitmap_copy, mirror_array(_draw_points, false, true)) project.selection_bitmap = selection_bitmap_copy - Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap) + Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle( + project.selection_bitmap + ) else: if !cleared: Global.canvas.selection.clear_selection() @@ -91,8 +104,8 @@ func apply_selection(_position) -> void: _last_position = Vector2.INF -func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: - var project : Project = Global.current_project +func lasso_selection(bitmap: BitMap, points: PoolVector2Array) -> void: + var project: Project = Global.current_project var size := bitmap.get_size() for point in points: if point.x < 0 or point.y < 0 or point.x >= size.x or point.y >= size.y: @@ -104,7 +117,7 @@ func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: bitmap.set_bit(point, !_subtract) var v := Vector2() - var image_size : Vector2 = project.size + var image_size: Vector2 = project.size for x in image_size.x: v.x = x for y in image_size.y: @@ -119,7 +132,7 @@ func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: # Bresenham's Algorithm # Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency -func append_gap(start : Vector2, end : Vector2) -> void: +func append_gap(start: Vector2, end: Vector2) -> void: var dx := int(abs(end.x - start.x)) var dy := int(-abs(end.y - start.y)) var err := dx + dy @@ -151,12 +164,14 @@ func _fill_bitmap_with_points(points: Array, size: Vector2) -> BitMap: return bitmap -func mirror_array(array : Array, h : bool, v : bool) -> Array: +func mirror_array(array: Array, h: bool, v: bool) -> Array: var new_array := [] - var project := Global.current_project + var project: Project = Global.current_project for point in array: if h and v: - new_array.append(Vector2(project.x_symmetry_point - point.x, project.y_symmetry_point - point.y)) + new_array.append( + Vector2(project.x_symmetry_point - point.x, project.y_symmetry_point - point.y) + ) elif h: new_array.append(Vector2(project.x_symmetry_point - point.x, point.y)) elif v: diff --git a/src/Tools/SelectionTools/MagicWand.gd b/src/Tools/SelectionTools/MagicWand.gd index f3cce67de..540683853 100644 --- a/src/Tools/SelectionTools/MagicWand.gd +++ b/src/Tools/SelectionTools/MagicWand.gd @@ -1,12 +1,12 @@ extends SelectionTool -func apply_selection(position : Vector2) -> void: - var project : Project = Global.current_project +func apply_selection(position: Vector2) -> void: + var project: Project = Global.current_project if !_add and !_subtract and !_intersect: Global.canvas.selection.clear_selection() - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() if _intersect: var full_rect = Rect2(Vector2.ZERO, selection_bitmap_copy.get_size()) selection_bitmap_copy.set_bit_rect(full_rect, false) @@ -31,12 +31,14 @@ func apply_selection(position : Vector2) -> void: flood_fill(mirror_y, cel_image, selection_bitmap_copy) cel_image.unlock() project.selection_bitmap = selection_bitmap_copy - Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap) + Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle( + project.selection_bitmap + ) Global.canvas.selection.commit_undo("Rectangle Select", undo_data) -func flood_fill(position : Vector2, image : Image, bitmap : BitMap) -> void: - var project : Project = Global.current_project +func flood_fill(position: Vector2, image: Image, bitmap: BitMap) -> void: + var project: Project = Global.current_project if position.x < 0 or position.y < 0: return if position.x > project.size.x - 1 or position.y > project.size.y - 1: @@ -50,8 +52,8 @@ func flood_fill(position : Vector2, image : Image, bitmap : BitMap) -> void: for n in q: if processed.get_bit(n): continue - var west : Vector2 = n - var east : Vector2 = n + var west: Vector2 = n + var east: Vector2 = n while west.x >= 0 && image.get_pixelv(west).is_equal_approx(color): west += Vector2.LEFT while east.x < project.size.x && image.get_pixelv(east).is_equal_approx(color): diff --git a/src/Tools/SelectionTools/PolygonSelect.gd b/src/Tools/SelectionTools/PolygonSelect.gd index fac55258b..536f0e868 100644 --- a/src/Tools/SelectionTools/PolygonSelect.gd +++ b/src/Tools/SelectionTools/PolygonSelect.gd @@ -1,12 +1,11 @@ extends SelectionTool - var _last_position := Vector2.INF var _draw_points := [] -var ready_to_apply := false +var _ready_to_apply := false -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: ._input(event) if _move: return @@ -16,17 +15,17 @@ func _input(event : InputEvent) -> void: if event.doubleclick and event.button_index == tool_slot.button and _draw_points: $DoubleClickTimer.start() append_gap(_draw_points[-1], _draw_points[0], _draw_points) - ready_to_apply = true - apply_selection(Vector2.ZERO) # Argument doesn't matter + _ready_to_apply = true + apply_selection(Vector2.ZERO) # Argument doesn't matter elif event is InputEventKey: if event.is_action_pressed("escape") and _ongoing_selection: _ongoing_selection = false _draw_points.clear() - ready_to_apply = false + _ready_to_apply = false Global.canvas.previews.update() -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if !$DoubleClickTimer.is_stopped(): return .draw_start(position) @@ -36,73 +35,87 @@ func draw_start(position : Vector2) -> void: _last_position = position -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: if selection_node.arrow_key_move: return .draw_move(position) -func draw_end(position : Vector2) -> void: +func draw_end(position: Vector2) -> void: if selection_node.arrow_key_move: return if !_move and _draw_points: append_gap(_draw_points[-1], position, _draw_points) if position == _draw_points[0] and _draw_points.size() > 1: - ready_to_apply = true + _ready_to_apply = true .draw_end(position) func draw_preview() -> void: if _ongoing_selection and !_move: - var canvas : Node2D = Global.canvas.previews - var _position := canvas.position - var _scale := canvas.scale + var canvas: Node2D = Global.canvas.previews + var position := canvas.position + var scale := canvas.scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 + position.x = position.x + Global.current_project.size.x + scale.x = -1 var preview_draw_points := _draw_points.duplicate() append_gap(_draw_points[-1], _last_position, preview_draw_points) - canvas.draw_set_transform(_position, canvas.rotation, _scale) + canvas.draw_set_transform(position, canvas.rotation, scale) var indicator := _fill_bitmap_with_points(preview_draw_points, Global.current_project.size) for line in _create_polylines(indicator): canvas.draw_polyline(PoolVector2Array(line), Color.black) - var circle_radius := Global.camera.zoom * 10 + var circle_radius: Vector2 = Global.camera.zoom * 10 circle_radius.x = clamp(circle_radius.x, 2, circle_radius.x) circle_radius.y = clamp(circle_radius.y, 2, circle_radius.y) if _last_position == _draw_points[0] and _draw_points.size() > 1: - draw_empty_circle(canvas, _draw_points[0] + Vector2.ONE * 0.5, circle_radius, Color.black) + draw_empty_circle( + canvas, _draw_points[0] + Vector2.ONE * 0.5, circle_radius, Color.black + ) # Handle mirroring if tool_slot.horizontal_mirror: - for line in _create_polylines(_fill_bitmap_with_points(mirror_array(preview_draw_points, true, false), Global.current_project.size)): + for line in _create_polylines( + _fill_bitmap_with_points( + mirror_array(preview_draw_points, true, false), Global.current_project.size + ) + ): canvas.draw_polyline(PoolVector2Array(line), Color.black) if tool_slot.vertical_mirror: - for line in _create_polylines(_fill_bitmap_with_points(mirror_array(preview_draw_points, true, true), Global.current_project.size)): + for line in _create_polylines( + _fill_bitmap_with_points( + mirror_array(preview_draw_points, true, true), Global.current_project.size + ) + ): canvas.draw_polyline(PoolVector2Array(line), Color.black) if tool_slot.vertical_mirror: - for line in _create_polylines(_fill_bitmap_with_points(mirror_array(preview_draw_points, false, true), Global.current_project.size)): + for line in _create_polylines( + _fill_bitmap_with_points( + mirror_array(preview_draw_points, false, true), Global.current_project.size + ) + ): canvas.draw_polyline(PoolVector2Array(line), Color.black) canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale) func apply_selection(_position) -> void: - if !ready_to_apply: + if !_ready_to_apply: return - var project : Project = Global.current_project + var project: Project = Global.current_project var cleared := false if !_add and !_subtract and !_intersect: cleared = true Global.canvas.selection.clear_selection() if _draw_points.size() > 3: - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() - var bitmap_size : Vector2 = selection_bitmap_copy.get_size() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() + var bitmap_size: Vector2 = selection_bitmap_copy.get_size() if _intersect: selection_bitmap_copy.set_bit_rect(Rect2(Vector2.ZERO, bitmap_size), false) lasso_selection(selection_bitmap_copy, _draw_points) @@ -116,7 +129,9 @@ func apply_selection(_position) -> void: lasso_selection(selection_bitmap_copy, mirror_array(_draw_points, false, true)) project.selection_bitmap = selection_bitmap_copy - Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap) + Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle( + project.selection_bitmap + ) else: if !cleared: Global.canvas.selection.clear_selection() @@ -124,12 +139,12 @@ func apply_selection(_position) -> void: Global.canvas.selection.commit_undo("Rectangle Select", undo_data) _ongoing_selection = false _draw_points.clear() - ready_to_apply = false + _ready_to_apply = false Global.canvas.previews.update() -func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: - var project : Project = Global.current_project +func lasso_selection(bitmap: BitMap, points: PoolVector2Array) -> void: + var project: Project = Global.current_project var size := bitmap.get_size() for point in points: if point.x < 0 or point.y < 0 or point.x >= size.x or point.y >= size.y: @@ -141,7 +156,7 @@ func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: bitmap.set_bit(point, !_subtract) var v := Vector2() - var image_size : Vector2 = project.size + var image_size: Vector2 = project.size for x in image_size.x: v.x = x for y in image_size.y: @@ -156,7 +171,7 @@ func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: # Bresenham's Algorithm # Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency -func append_gap(start : Vector2, end : Vector2, array : Array) -> void: +func append_gap(start: Vector2, end: Vector2, array: Array) -> void: var dx := int(abs(end.x - start.x)) var dy := int(-abs(end.y - start.y)) var err := dx + dy @@ -188,12 +203,14 @@ func _fill_bitmap_with_points(points: Array, size: Vector2) -> BitMap: return bitmap -func mirror_array(array : Array, h : bool, v : bool) -> Array: +func mirror_array(array: Array, h: bool, v: bool) -> Array: var new_array := [] - var project := Global.current_project + var project: Project = Global.current_project for point in array: if h and v: - new_array.append(Vector2(project.x_symmetry_point - point.x, project.y_symmetry_point - point.y)) + new_array.append( + Vector2(project.x_symmetry_point - point.x, project.y_symmetry_point - point.y) + ) elif h: new_array.append(Vector2(project.x_symmetry_point - point.x, point.y)) elif v: @@ -202,8 +219,11 @@ func mirror_array(array : Array, h : bool, v : bool) -> Array: return new_array -# Thanks to https://www.reddit.com/r/godot/comments/3ktq39/drawing_empty_circles_and_curves/cv0f4eo/?utm_source=reddit&utm_medium=web2x&context=3 -func draw_empty_circle(canvas : CanvasItem, circle_center : Vector2, circle_radius : Vector2, color : Color) -> void: +# Thanks to +# https://www.reddit.com/r/godot/comments/3ktq39/drawing_empty_circles_and_curves/cv0f4eo/ +func draw_empty_circle( + canvas: CanvasItem, circle_center: Vector2, circle_radius: Vector2, color: Color +) -> void: var draw_counter := 1 var line_origin := Vector2() var line_end := Vector2() diff --git a/src/Tools/SelectionTools/RectSelect.gd b/src/Tools/SelectionTools/RectSelect.gd index 3e147709b..d0cafb2b6 100644 --- a/src/Tools/SelectionTools/RectSelect.gd +++ b/src/Tools/SelectionTools/RectSelect.gd @@ -1,14 +1,13 @@ extends SelectionTool - var _rect := Rect2(0, 0, 0, 0) -var _square := false # Mouse Click + Shift -var _expand_from_center := false # Mouse Click + Ctrl -var _displace_origin = false # Mouse Click + Alt +var _square := false # Mouse Click + Shift +var _expand_from_center := false # Mouse Click + Ctrl +var _displace_origin = false # Mouse Click + Alt -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: ._input(event) if !_move and !_rect.has_no_area(): if event.is_action_pressed("shift"): @@ -25,7 +24,7 @@ func _input(event : InputEvent) -> void: _displace_origin = false -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: if selection_node.arrow_key_move: return .draw_move(position) @@ -37,7 +36,7 @@ func draw_move(position : Vector2) -> void: _offset = position -func draw_end(position : Vector2) -> void: +func draw_end(position: Vector2) -> void: if selection_node.arrow_key_move: return .draw_end(position) @@ -49,29 +48,41 @@ func draw_end(position : Vector2) -> void: func draw_preview() -> void: if !_move: - var canvas : Node2D = Global.canvas.previews - var _position := canvas.position - var _scale := canvas.scale + var canvas: Node2D = Global.canvas.previews + var position := canvas.position + var scale := canvas.scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 - canvas.draw_set_transform(_position, canvas.rotation, _scale) + position.x = position.x + Global.current_project.size.x + scale.x = -1 + canvas.draw_set_transform(position, canvas.rotation, scale) canvas.draw_rect(_rect, Color.black, false) # Handle mirroring if tool_slot.horizontal_mirror: var mirror_x_rect := _rect - mirror_x_rect.position.x = Global.current_project.x_symmetry_point - _rect.position.x + 1 + mirror_x_rect.position.x = ( + Global.current_project.x_symmetry_point + - _rect.position.x + + 1 + ) mirror_x_rect.end.x = Global.current_project.x_symmetry_point - _rect.end.x + 1 canvas.draw_rect(mirror_x_rect, Color.black, false) if tool_slot.vertical_mirror: var mirror_xy_rect := mirror_x_rect - mirror_xy_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y + 1 + mirror_xy_rect.position.y = ( + Global.current_project.y_symmetry_point + - _rect.position.y + + 1 + ) mirror_xy_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y + 1 canvas.draw_rect(mirror_xy_rect, Color.black, false) if tool_slot.vertical_mirror: var mirror_y_rect := _rect - mirror_y_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y + 1 + mirror_y_rect.position.y = ( + Global.current_project.y_symmetry_point + - _rect.position.y + + 1 + ) mirror_y_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y + 1 canvas.draw_rect(mirror_y_rect, Color.black, false) canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale) @@ -93,24 +104,37 @@ func apply_selection(_position) -> void: # Handle mirroring if tool_slot.horizontal_mirror: var mirror_x_rect := _rect - mirror_x_rect.position.x = Global.current_project.x_symmetry_point - _rect.position.x + 1 + mirror_x_rect.position.x = ( + Global.current_project.x_symmetry_point + - _rect.position.x + + 1 + ) mirror_x_rect.end.x = Global.current_project.x_symmetry_point - _rect.end.x + 1 Global.canvas.selection.select_rect(mirror_x_rect.abs(), operation) if tool_slot.vertical_mirror: var mirror_xy_rect := mirror_x_rect - mirror_xy_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y + 1 + mirror_xy_rect.position.y = ( + Global.current_project.y_symmetry_point + - _rect.position.y + + 1 + ) mirror_xy_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y + 1 Global.canvas.selection.select_rect(mirror_xy_rect.abs(), operation) if tool_slot.vertical_mirror: var mirror_y_rect := _rect - mirror_y_rect.position.y = Global.current_project.y_symmetry_point - _rect.position.y + 1 + mirror_y_rect.position.y = ( + Global.current_project.y_symmetry_point + - _rect.position.y + + 1 + ) mirror_y_rect.end.y = Global.current_project.y_symmetry_point - _rect.end.y + 1 Global.canvas.selection.select_rect(mirror_y_rect.abs(), operation) Global.canvas.selection.commit_undo("Rectangle Select", undo_data) -# Given an origin point and destination point, returns a rect representing where the shape will be drawn and what it's size +# Given an origin point and destination point, returns a rect representing +# where the shape will be drawn and what is its size func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: var rect := Rect2(Vector2.ZERO, Vector2.ZERO) @@ -119,8 +143,8 @@ func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: var new_size := (dest - origin).floor() # Make rect 1:1 while centering it on the mouse if _square: - var _square_size := max(abs(new_size.x), abs(new_size.y)) - new_size = Vector2(_square_size, _square_size) + var square_size := max(abs(new_size.x), abs(new_size.y)) + new_size = Vector2(square_size, square_size) origin -= new_size dest = origin + 2 * new_size diff --git a/src/Tools/SelectionTools/SelectionTool.gd b/src/Tools/SelectionTools/SelectionTool.gd index a0f259cbb..152f6d957 100644 --- a/src/Tools/SelectionTools/SelectionTool.gd +++ b/src/Tools/SelectionTools/SelectionTool.gd @@ -1,6 +1,7 @@ -class_name SelectionTool extends BaseTool - +class_name SelectionTool +extends BaseTool +var undo_data: Dictionary var _move := false var _move_content := true var _start_pos := Vector2.ZERO @@ -9,43 +10,45 @@ var _offset := Vector2.ZERO # click multiple times to create a selection var _ongoing_selection := false -var _add := false # Shift + Mouse Click -var _subtract := false # Ctrl + Mouse Click -var _intersect := false # Shift + Ctrl + Mouse Click -var _snap_to_grid := false # Mouse Click + Ctrl +var _add := false # Shift + Mouse Click +var _subtract := false # Ctrl + Mouse Click +var _intersect := false # Shift + Ctrl + Mouse Click +var _snap_to_grid := false # Mouse Click + Ctrl # Used to check if the state of content transformation has been changed # while draw_move() is being called. For example, pressing Enter while still moving content var _content_transformation_check := false -var undo_data : Dictionary -onready var selection_node : Node2D = Global.canvas.selection -onready var xspinbox : SpinBox = find_node("XSpinBox") -onready var yspinbox : SpinBox = find_node("YSpinBox") -onready var wspinbox : SpinBox = find_node("WSpinBox") -onready var hspinbox : SpinBox = find_node("HSpinBox") -onready var timer : Timer = $Timer +onready var selection_node: Node2D = Global.canvas.selection +onready var xspinbox: SpinBox = find_node("XSpinBox") +onready var yspinbox: SpinBox = find_node("YSpinBox") +onready var wspinbox: SpinBox = find_node("WSpinBox") +onready var hspinbox: SpinBox = find_node("HSpinBox") +onready var timer: Timer = $Timer func _ready() -> void: set_spinbox_values() -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if _move: if event.is_action_pressed("ctrl"): _snap_to_grid = true var grid_size := Vector2(Global.grid_width, Global.grid_height) _offset = _offset.snapped(grid_size) var prev_pos = selection_node.big_bounding_rectangle.position - selection_node.big_bounding_rectangle.position = selection_node.big_bounding_rectangle.position.snapped(grid_size) - selection_node.marching_ants_outline.offset += selection_node.big_bounding_rectangle.position - prev_pos + selection_node.big_bounding_rectangle.position = prev_pos.snapped(grid_size) + selection_node.marching_ants_outline.offset += ( + selection_node.big_bounding_rectangle.position + - prev_pos + ) elif event.is_action_released("ctrl"): _snap_to_grid = false func set_spinbox_values() -> void: - var select_rect : Rect2 = selection_node.big_bounding_rectangle + var select_rect: Rect2 = selection_node.big_bounding_rectangle xspinbox.editable = !select_rect.has_no_area() yspinbox.editable = !select_rect.has_no_area() wspinbox.editable = !select_rect.has_no_area() @@ -57,46 +60,65 @@ func set_spinbox_values() -> void: hspinbox.value = select_rect.size.y -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if selection_node.arrow_key_move: return - var project : Project = Global.current_project - undo_data = selection_node._get_undo_data(false) + var project: Project = Global.current_project + undo_data = selection_node.get_undo_data(false) _intersect = Tools.shift && Tools.control _add = Tools.shift && !_intersect _subtract = Tools.control && !_intersect _start_pos = position _offset = position - var selection_position : Vector2 = selection_node.big_bounding_rectangle.position + var selection_position: Vector2 = selection_node.big_bounding_rectangle.position var offsetted_pos := position if selection_position.x < 0: offsetted_pos.x -= selection_position.x if selection_position.y < 0: offsetted_pos.y -= selection_position.y - if offsetted_pos.x >= 0 and offsetted_pos.y >= 0 and project.selection_bitmap.get_bit(offsetted_pos) and (!Tools.control or Tools.alt) and !Tools.shift and !_ongoing_selection: + if ( + offsetted_pos.x >= 0 + and offsetted_pos.y >= 0 + and project.selection_bitmap.get_bit(offsetted_pos) + and (!Tools.control or Tools.alt) + and !Tools.shift + and !_ongoing_selection + ): if !Global.current_project.layers[Global.current_project.current_layer].can_layer_get_drawn(): return # Move current selection _move = true - if Tools.alt: # Move selection without content - if Tools.control: # Move the selection without cutting it from the original position / makes a quick copy of it + if Tools.alt: # Move selection without content + if Tools.control: + # Move the selection without cutting it from the original position + # (makes a quick copy of it) _move_content = true if selection_node.is_moving_content: for image in _get_selected_draw_images(): - image.blit_rect_mask(selection_node.preview_image, selection_node.preview_image, Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), selection_node.big_bounding_rectangle.position) + image.blit_rect_mask( + selection_node.preview_image, + selection_node.preview_image, + Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), + selection_node.big_bounding_rectangle.position + ) var selected_bitmap_copy = project.selection_bitmap.duplicate() project.move_bitmap_values(selected_bitmap_copy) project.selection_bitmap = selected_bitmap_copy selection_node.commit_undo("Move Selection", selection_node.undo_data) - selection_node.undo_data = selection_node._get_undo_data(true) + selection_node.undo_data = selection_node.get_undo_data(true) else: selection_node.transform_content_start() selection_node.clear_in_selected_cels = false for image in _get_selected_draw_images(): - image.blit_rect_mask(selection_node.preview_image, selection_node.preview_image, Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), selection_node.big_bounding_rectangle.position) + image.blit_rect_mask( + selection_node.preview_image, + selection_node.preview_image, + Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), + selection_node.big_bounding_rectangle.position + ) Global.canvas.update_selected_cels_textures() else: @@ -113,7 +135,7 @@ func draw_start(position : Vector2) -> void: _content_transformation_check = selection_node.is_moving_content -func draw_move(position : Vector2) -> void: +func draw_move(position: Vector2) -> void: if selection_node.arrow_key_move: return # This is true if content transformation has been confirmed (pressed Enter for example) @@ -121,9 +143,9 @@ func draw_move(position : Vector2) -> void: if _content_transformation_check != selection_node.is_moving_content: return if _move: - if Tools.shift: # Snap to axis + if Tools.shift: # Snap to axis var angle := position.angle_to_point(_start_pos) - if abs(angle) <= PI / 4 or abs(angle) >= 3*PI / 4: + if abs(angle) <= PI / 4 or abs(angle) >= 3 * PI / 4: position.y = _start_pos.y else: position.x = _start_pos.x @@ -140,7 +162,7 @@ func draw_move(position : Vector2) -> void: _set_cursor_text(selection_node.big_bounding_rectangle) -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: if selection_node.arrow_key_move: return if _content_transformation_check == selection_node.is_moving_content: @@ -154,80 +176,94 @@ func draw_end(_position : Vector2) -> void: cursor_text = "" -func apply_selection(_position : Vector2) -> void: +func apply_selection(_position: Vector2) -> void: pass -func _set_cursor_text(rect : Rect2) -> void: +func _set_cursor_text(rect: Rect2) -> void: cursor_text = "%s, %s" % [rect.position.x, rect.position.y] cursor_text += " -> %s, %s" % [rect.end.x - 1, rect.end.y - 1] cursor_text += " (%s, %s)" % [rect.size.x, rect.size.y] -func _on_XSpinBox_value_changed(value : float) -> void: - var project : Project = Global.current_project +func _on_XSpinBox_value_changed(value: float) -> void: + var project: Project = Global.current_project if !project.has_selection or selection_node.big_bounding_rectangle.position.x == value: return if timer.is_stopped(): - undo_data = selection_node._get_undo_data(false) + undo_data = selection_node.get_undo_data(false) timer.start() selection_node.big_bounding_rectangle.position.x = value - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() project.move_bitmap_values(selection_bitmap_copy) project.selection_bitmap = selection_bitmap_copy project.selection_bitmap_changed() -func _on_YSpinBox_value_changed(value : float) -> void: - var project : Project = Global.current_project +func _on_YSpinBox_value_changed(value: float) -> void: + var project: Project = Global.current_project if !project.has_selection or selection_node.big_bounding_rectangle.position.y == value: return if timer.is_stopped(): - undo_data = selection_node._get_undo_data(false) + undo_data = selection_node.get_undo_data(false) timer.start() selection_node.big_bounding_rectangle.position.y = value - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() project.move_bitmap_values(selection_bitmap_copy) project.selection_bitmap = selection_bitmap_copy project.selection_bitmap_changed() -func _on_WSpinBox_value_changed(value : float) -> void: - var project : Project = Global.current_project - if !project.has_selection or selection_node.big_bounding_rectangle.size.x == value or selection_node.big_bounding_rectangle.size.x <= 0: +func _on_WSpinBox_value_changed(value: float) -> void: + var project: Project = Global.current_project + if ( + !project.has_selection + or selection_node.big_bounding_rectangle.size.x == value + or selection_node.big_bounding_rectangle.size.x <= 0 + ): return if timer.is_stopped(): - undo_data = selection_node._get_undo_data(false) + undo_data = selection_node.get_undo_data(false) timer.start() selection_node.big_bounding_rectangle.size.x = value resize_selection() -func _on_HSpinBox_value_changed(value : float) -> void: - var project : Project = Global.current_project - if !project.has_selection or selection_node.big_bounding_rectangle.size.y == value or selection_node.big_bounding_rectangle.size.y <= 0: +func _on_HSpinBox_value_changed(value: float) -> void: + var project: Project = Global.current_project + if ( + !project.has_selection + or selection_node.big_bounding_rectangle.size.y == value + or selection_node.big_bounding_rectangle.size.y <= 0 + ): return if timer.is_stopped(): - undo_data = selection_node._get_undo_data(false) + undo_data = selection_node.get_undo_data(false) timer.start() selection_node.big_bounding_rectangle.size.y = value resize_selection() func resize_selection() -> void: - var project : Project = Global.current_project - var bitmap : BitMap = project.selection_bitmap + var project: Project = Global.current_project + var bitmap: BitMap = project.selection_bitmap if selection_node.is_moving_content: bitmap = selection_node.original_bitmap - var preview_image : Image = selection_node.preview_image + var preview_image: Image = selection_node.preview_image preview_image.copy_from(selection_node.original_preview_image) - preview_image.resize(selection_node.big_bounding_rectangle.size.x, selection_node.big_bounding_rectangle.size.y, Image.INTERPOLATE_NEAREST) + preview_image.resize( + selection_node.big_bounding_rectangle.size.x, + selection_node.big_bounding_rectangle.size.y, + Image.INTERPOLATE_NEAREST + ) selection_node.preview_image_texture.create_from_image(preview_image, 0) - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() - selection_bitmap_copy = project.resize_bitmap_values(bitmap, selection_node.big_bounding_rectangle.size, false, false) + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() + selection_bitmap_copy = project.resize_bitmap_values( + bitmap, selection_node.big_bounding_rectangle.size, false, false + ) project.selection_bitmap = selection_bitmap_copy project.selection_bitmap_changed() diff --git a/src/Tools/Shading.gd b/src/Tools/Shading.gd index f9e6e8e82..fc73d473c 100644 --- a/src/Tools/Shading.gd +++ b/src/Tools/Shading.gd @@ -1,36 +1,34 @@ extends "res://src/Tools/Draw.gd" - -enum ShadingMode {SIMPLE, HUE_SHIFTING} -enum LightenDarken {LIGHTEN, DARKEN} - +enum ShadingMode { SIMPLE, HUE_SHIFTING } +enum LightenDarken { LIGHTEN, DARKEN } var _prev_mode := 0 var _last_position := Vector2.INF var _changed := false -var _shading_mode : int = ShadingMode.SIMPLE -var _mode : int = LightenDarken.LIGHTEN +var _shading_mode: int = ShadingMode.SIMPLE +var _mode: int = LightenDarken.LIGHTEN var _amount := 10 var _hue_amount := 10 var _sat_amount := 10 var _value_amount := 10 -class LightenDarkenOp extends Drawer.ColorOp: +class LightenDarkenOp: + extends Drawer.ColorOp var changed := false - var shading_mode : int = ShadingMode.SIMPLE - var lighten_or_darken : int = LightenDarken.LIGHTEN + var shading_mode: int = ShadingMode.SIMPLE + var lighten_or_darken: int = LightenDarken.LIGHTEN var hue_amount := 10.0 var sat_amount := 10.0 var value_amount := 10.0 - var hue_lighten_limit := 60.0 / 360.0 # A yellow color - var hue_darken_limit := 240.0 / 360.0 # A blue color + var hue_lighten_limit := 60.0 / 360.0 # A yellow color + var hue_darken_limit := 240.0 / 360.0 # A blue color var sat_lighten_limit := 10.0 / 100.0 var value_darken_limit := 10.0 / 100.0 - func process(_src: Color, dst: Color) -> Color: changed = true if dst.a == 0: @@ -66,14 +64,12 @@ class LightenDarkenOp extends Drawer.ColorOp: return dst - # Returns true if the colors are roughly between yellow, green and blue # False when the colors are roughly between red-orange-yellow, or blue-purple-red - func hue_range(hue : float) -> bool: + func hue_range(hue: float) -> bool: return hue > hue_lighten_limit and hue < hue_darken_limit - - func hue_limit_lighten(hue : float, hue_shift : float) -> float: + func hue_limit_lighten(hue: float, hue_shift: float) -> float: # Colors between red-orange-yellow and blue-purple-red if hue_shift > 0: # Just colors between red-orange-yellow @@ -82,7 +78,7 @@ class LightenDarkenOp extends Drawer.ColorOp: hue_shift = hue_lighten_limit - hue # Just blue-purple-red else: - if hue + hue_shift >= hue_lighten_limit + 1: # +1 looping around the color wheel + if hue + hue_shift >= hue_lighten_limit + 1: # +1 looping around the color wheel hue_shift = hue_lighten_limit - hue # Colors between yellow-green-blue @@ -90,13 +86,12 @@ class LightenDarkenOp extends Drawer.ColorOp: hue_shift = hue_lighten_limit - hue return hue_shift - - func hue_limit_darken(hue : float, hue_shift : float) -> float: + func hue_limit_darken(hue: float, hue_shift: float) -> float: # Colors between red-orange-yellow and blue-purple-red if hue_shift > 0: # Just colors between red-orange-yellow if hue < hue_darken_limit: - if hue - hue_shift <= hue_darken_limit - 1: # -1 looping backwards around the color wheel + if hue - hue_shift <= hue_darken_limit - 1: # -1 looping backwards around the color wheel hue_shift = hue - hue_darken_limit # Just blue-purple-red else: @@ -114,7 +109,7 @@ func _init() -> void: func _input(event: InputEvent) -> void: - var options : OptionButton = $LightenDarken + var options: OptionButton = $LightenDarken if event.is_action_pressed("ctrl"): _prev_mode = options.selected @@ -128,39 +123,39 @@ func _input(event: InputEvent) -> void: _drawer.color_op.lighten_or_darken = _mode -func _on_ShadingMode_item_selected(id : int) -> void: +func _on_ShadingMode_item_selected(id: int) -> void: _shading_mode = id _drawer.color_op.shading_mode = id update_config() save_config() -func _on_LightenDarken_item_selected(id : int) -> void: +func _on_LightenDarken_item_selected(id: int) -> void: _mode = id _drawer.color_op.lighten_or_darken = id update_config() save_config() -func _on_LightenDarken_value_changed(value : float) -> void: +func _on_LightenDarken_value_changed(value: float) -> void: _amount = int(value) update_config() save_config() -func _on_LightenDarken_hue_value_changed(value : float) -> void: +func _on_LightenDarken_hue_value_changed(value: float) -> void: _hue_amount = int(value) update_config() save_config() -func _on_LightenDarken_sat_value_changed(value : float) -> void: +func _on_LightenDarken_sat_value_changed(value: float) -> void: _sat_amount = int(value) update_config() save_config() -func _on_LightenDarken_value_value_changed(value : float) -> void: +func _on_LightenDarken_value_value_changed(value: float) -> void: _value_amount = int(value) update_config() save_config() @@ -177,7 +172,7 @@ func get_config() -> Dictionary: return config -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: .set_config(config) _shading_mode = config.get("shading_mode", _shading_mode) _drawer.color_op.shading_mode = _shading_mode @@ -214,7 +209,7 @@ func update_strength() -> void: _drawer.color_op.value_amount = _value_amount -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if Input.is_action_pressed("alt"): _picking_color = true _pick_color(position) @@ -241,8 +236,8 @@ func draw_start(position : Vector2) -> void: cursor_text = "" -func draw_move(position : Vector2) -> void: - if _picking_color: # Still return even if we released Alt +func draw_move(position: Vector2) -> void: + if _picking_color: # Still return even if we released Alt if Input.is_action_pressed("alt"): _pick_color(position) return @@ -259,7 +254,7 @@ func draw_move(position : Vector2) -> void: Global.canvas.sprite_changed_this_frame = true -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: if _picking_color: return @@ -273,7 +268,7 @@ func draw_end(_position : Vector2) -> void: update_random_image() -func _draw_brush_image(image : Image, src_rect: Rect2, dst: Vector2) -> void: +func _draw_brush_image(image: Image, src_rect: Rect2, dst: Vector2) -> void: _changed = true image.lock() for xx in image.get_size().x: diff --git a/src/Tools/ShapeDrawer.gd b/src/Tools/ShapeDrawer.gd index a7da963a9..4713394b0 100644 --- a/src/Tools/ShapeDrawer.gd +++ b/src/Tools/ShapeDrawer.gd @@ -1,6 +1,5 @@ extends "res://src/Tools/Draw.gd" - var _start := Vector2.ZERO var _offset := Vector2.ZERO var _dest := Vector2.ZERO @@ -75,7 +74,7 @@ func _get_shape_points_filled(_size: Vector2) -> PoolVector2Array: return PoolVector2Array() -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if _drawing: if event.is_action_pressed("alt"): _displace_origin = true @@ -83,7 +82,7 @@ func _input(event : InputEvent) -> void: _displace_origin = false -func draw_start(position : Vector2) -> void: +func draw_start(position: Vector2) -> void: if Input.is_action_pressed("alt"): _picking_color = true _pick_color(position) @@ -99,8 +98,8 @@ func draw_start(position : Vector2) -> void: _drawing = true -func draw_move(position : Vector2) -> void: - if _picking_color: # Still return even if we released Alt +func draw_move(position: Vector2) -> void: + if _picking_color: # Still return even if we released Alt if Input.is_action_pressed("alt"): _pick_color(position) return @@ -113,7 +112,7 @@ func draw_move(position : Vector2) -> void: _set_cursor_text(_get_result_rect(_start, position)) -func draw_end(position : Vector2) -> void: +func draw_end(position: Vector2) -> void: if _picking_color: return @@ -129,7 +128,7 @@ func draw_end(position : Vector2) -> void: func draw_preview() -> void: if _drawing: - var canvas : CanvasItem = Global.canvas.previews + var canvas: CanvasItem = Global.canvas.previews var indicator := BitMap.new() var rect := _get_result_rect(_start, _dest) var points := _get_points(rect.size) @@ -160,9 +159,11 @@ func _draw_shape(origin: Vector2, dest: Vector2) -> void: commit_undo("Draw Shape") -# Given an origin point and destination point, returns a rect representing where the shape will be drawn and what it's size +# Given an origin point and destination point, returns a rect representing +# where the shape will be drawn and what is its size func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: - # WARNING: Don't replace Input.is_action_pressed for Tools.control, it makes the preview jittery on windows + # WARNING: Don't replace Input.is_action_pressed for Tools.control, + # it makes the preview jittery on Windows var rect := Rect2(Vector2.ZERO, Vector2.ZERO) # Center the rect on the mouse @@ -170,8 +171,8 @@ func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: var new_size := (dest - origin).floor() # Make rect 1:1 while centering it on the mouse if Input.is_action_pressed("shift"): - var _square_size := max(abs(new_size.x), abs(new_size.y)) - new_size = Vector2(_square_size, _square_size) + var square_size := max(abs(new_size.x), abs(new_size.y)) + new_size = Vector2(square_size, square_size) origin -= new_size dest = origin + 2 * new_size @@ -197,22 +198,19 @@ func _get_points(size: Vector2) -> PoolVector2Array: func _outline_point(p: Vector2, thickness: int = 1, include_p: bool = true) -> Array: - var array := [] + var array := [] - if thickness != 1: - var t_of = thickness - 1 - for x in range (-t_of, thickness): - for y in range (-t_of, thickness): - if x == 0 and y == 0 and not include_p: - continue - - array.append(p + Vector2(x,y)) - - return array + if thickness != 1: + var t_of = thickness - 1 + for x in range(-t_of, thickness): + for y in range(-t_of, thickness): + if x == 0 and y == 0 and not include_p: + continue + array.append(p + Vector2(x, y)) + return array -func _set_cursor_text(rect : Rect2) -> void: +func _set_cursor_text(rect: Rect2) -> void: cursor_text = "%s, %s" % [rect.position.x, rect.position.y] cursor_text += " -> %s, %s" % [rect.end.x - 1, rect.end.y - 1] cursor_text += " (%s, %s)" % [rect.size.x, rect.size.y] - diff --git a/src/Tools/Zoom.gd b/src/Tools/Zoom.gd index acef296f7..f530ccabb 100644 --- a/src/Tools/Zoom.gd +++ b/src/Tools/Zoom.gd @@ -1,7 +1,6 @@ extends BaseTool - -var _relative : Vector2 +var _relative: Vector2 var _prev_mode := 0 var _zoom_mode := 0 @@ -20,7 +19,7 @@ func _input(event: InputEvent) -> void: _zoom_mode = $ModeOptions.selected -func _on_ModeOptions_item_selected(id : int) -> void: +func _on_ModeOptions_item_selected(id: int) -> void: _zoom_mode = id update_config() save_config() @@ -36,11 +35,11 @@ func _on_100_pressed() -> void: func get_config() -> Dictionary: return { - "zoom_mode" : _zoom_mode, + "zoom_mode": _zoom_mode, } -func set_config(config : Dictionary) -> void: +func set_config(config: Dictionary) -> void: _zoom_mode = config.get("zoom_mode", _zoom_mode) @@ -48,10 +47,14 @@ func update_config() -> void: $ModeOptions.selected = _zoom_mode -func draw_start(_position : Vector2) -> void: +func draw_start(_position: Vector2) -> void: var mouse_pos := get_global_mouse_position() - var viewport_rect := Rect2(Global.main_viewport.rect_global_position, Global.main_viewport.rect_size) - var viewport_rect_2 := Rect2(Global.second_viewport.rect_global_position, Global.second_viewport.rect_size) + var viewport_rect := Rect2( + Global.main_viewport.rect_global_position, Global.main_viewport.rect_size + ) + var viewport_rect_2 := Rect2( + Global.second_viewport.rect_global_position, Global.second_viewport.rect_size + ) if viewport_rect.has_point(mouse_pos): Global.camera.zoom_camera(_zoom_mode * 2 - 1) @@ -59,9 +62,9 @@ func draw_start(_position : Vector2) -> void: Global.camera2.zoom_camera(_zoom_mode * 2 - 1) -func draw_move(_position : Vector2) -> void: +func draw_move(_position: Vector2) -> void: Global.camera.zoom_camera(-_relative.x / 3) -func draw_end(_position : Vector2) -> void: +func draw_end(_position: Vector2) -> void: pass diff --git a/src/UI/BrushButton.gd b/src/UI/BrushButton.gd index 12c7ee7be..951e4d41a 100644 --- a/src/UI/BrushButton.gd +++ b/src/UI/BrushButton.gd @@ -1,6 +1,5 @@ extends BaseButton - var brush = Global.brushes_popup.Brush.new() diff --git a/src/UI/BrushesPopup.gd b/src/UI/BrushesPopup.gd index 96a1b69f2..0018f3549 100644 --- a/src/UI/BrushesPopup.gd +++ b/src/UI/BrushesPopup.gd @@ -1,23 +1,22 @@ -extends Popup class_name Brushes - - -class Brush: - var type : int - var image : Image - var random := [] - var index : int - +extends Popup signal brush_selected(brush) signal brush_removed(brush) -enum {PIXEL, CIRCLE, FILLED_CIRCLE, FILE, RANDOM_FILE, CUSTOM} +enum { PIXEL, CIRCLE, FILLED_CIRCLE, FILE, RANDOM_FILE, CUSTOM } var pixel_image = preload("res://assets/graphics/pixel_image.png") var circle_image = preload("res://assets/graphics/circle_9x9.png") var circle_filled_image = preload("res://assets/graphics/circle_filled_9x9.png") +class Brush: + var type: int + var image: Image + var random := [] + var index: int + + func _ready() -> void: var container = Global.brushes_popup.get_node("TabContainer/File/FileBrushContainer") var button = create_button(pixel_image) @@ -39,7 +38,7 @@ func _ready() -> void: button.brush.index = button.get_index() -func select_brush(brush : Brush) -> void: +func select_brush(brush: Brush) -> void: emit_signal("brush_selected", brush) hide() @@ -51,8 +50,8 @@ static func get_default_brush() -> Brush: return brush -static func create_button(image : Image) -> Node: - var button : BaseButton = preload("res://src/UI/BrushButton.tscn").instance() +static func create_button(image: Image) -> Node: + var button: BaseButton = preload("res://src/UI/BrushButton.tscn").instance() var tex := ImageTexture.new() tex.create_from_image(image, 0) button.get_child(0).texture = tex @@ -60,7 +59,7 @@ static func create_button(image : Image) -> Node: return button -static func add_file_brush(images : Array, hint := "") -> void: +static func add_file_brush(images: Array, hint := "") -> void: var button = create_button(images[0]) button.brush.type = FILE if images.size() == 1 else RANDOM_FILE button.brush.image = images[0] @@ -71,7 +70,7 @@ static func add_file_brush(images : Array, hint := "") -> void: button.brush.index = button.get_index() -static func add_project_brush(image : Image, hint := "") -> void: +static func add_project_brush(image: Image, hint := "") -> void: var button = create_button(image) button.brush.type = CUSTOM button.brush.image = image @@ -88,7 +87,7 @@ static func clear_project_brush() -> void: Global.brushes_popup.emit_signal("brush_removed", child.brush) -func get_brush(type : int, index : int) -> Brush: +func get_brush(type: int, index: int) -> Brush: var container if type == CUSTOM: container = Global.brushes_popup.get_node("TabContainer/Project/ProjectBrushContainer") @@ -100,7 +99,7 @@ func get_brush(type : int, index : int) -> Brush: return brush -func remove_brush(brush_button : Node) -> void: +func remove_brush(brush_button: Node) -> void: emit_signal("brush_removed", brush_button.brush) var project = Global.current_project @@ -117,17 +116,19 @@ func remove_brush(brush_button : Node) -> void: project.undo_redo.commit_action() -func undo_custom_brush(brush_button : BaseButton = null) -> void: +func undo_custom_brush(brush_button: BaseButton = null) -> void: Global.general_undo() - var action_name : String = Global.current_project.undo_redo.get_current_action_name() + var action_name: String = Global.current_project.undo_redo.get_current_action_name() if action_name == "Delete Custom Brush": $TabContainer/Project/ProjectBrushContainer.add_child(brush_button) - $TabContainer/Project/ProjectBrushContainer.move_child(brush_button, brush_button.brush.index) + $TabContainer/Project/ProjectBrushContainer.move_child( + brush_button, brush_button.brush.index + ) brush_button.get_node("DeleteButton").visible = false -func redo_custom_brush(brush_button : BaseButton = null) -> void: +func redo_custom_brush(brush_button: BaseButton = null) -> void: Global.general_redo() - var action_name : String = Global.current_project.undo_redo.get_current_action_name() + var action_name: String = Global.current_project.undo_redo.get_current_action_name() if action_name == "Delete Custom Brush": $TabContainer/Project/ProjectBrushContainer.remove_child(brush_button) diff --git a/src/UI/Canvas/CameraMovement.gd b/src/UI/Canvas/CameraMovement.gd index 900c51f40..4ef3db293 100644 --- a/src/UI/Canvas/CameraMovement.gd +++ b/src/UI/Canvas/CameraMovement.gd @@ -1,21 +1,27 @@ extends Camera2D +enum Cameras { MAIN, SECOND, SMALL } +enum Direction { UP, DOWN, LEFT, RIGHT } -enum Cameras {MAIN, SECOND, SMALL} -enum Direction {UP, DOWN, LEFT, RIGHT} - -const low_speed_move_rate := 150.0 -const medium_speed_move_rate := 750.0 -const high_speed_move_rate := 3750.0 +const LOW_SPEED_MOVE_RATE := 150.0 +const MEDIUM_SPEED_MOVE_RATE := 750.0 +const HIGH_SPEED_MOVE_RATE := 3750.0 +const KEY_MOVE_ACTION_NAMES := ["ui_up", "ui_down", "ui_left", "ui_right"] +# Holds sign multipliers for the given directions nyaa +# (per the indices defined by Direction) +# UP, DOWN, LEFT, RIGHT in that order +const DIRECTIONAL_SIGN_MULTIPLIERS := [ + Vector2(0.0, -1.0), Vector2(0.0, 1.0), Vector2(-1.0, 0.0), Vector2(1.0, 0.0) +] # Indices are as in the Direction enum # This is the total time the key for that direction has been pressed. var key_move_press_time := [0.0, 0.0, 0.0, 0.0] -var tween : Tween +var tween: Tween var zoom_min := Vector2(0.005, 0.005) var zoom_max := Vector2.ONE -var viewport_container : ViewportContainer -var transparent_checker : ColorRect +var viewport_container: ViewportContainer +var transparent_checker: ColorRect var mouse_pos := Vector2.ZERO var drag := false var index := 0 @@ -31,14 +37,16 @@ func _ready() -> void: update_transparent_checker_offset() # signals regarding rotation stats - Global.rotation_level_button.connect("pressed",self,"rotation_button_pressed") + Global.rotation_level_button.connect("pressed", self, "rotation_button_pressed") Global.rotation_level_spinbox.connect("value_changed", self, "rotation_value_changed") - Global.rotation_level_spinbox.get_child(0).connect("focus_exited", self, "rotation_focus_exited") + Global.rotation_level_spinbox.get_child(0).connect( + "focus_exited", self, "rotation_focus_exited" + ) # signals regarding zoom stats - Global.zoom_level_button.connect("pressed",self,"zoom_button_pressed") + Global.zoom_level_button.connect("pressed", self, "zoom_button_pressed") Global.zoom_level_spinbox.connect("value_changed", self, "zoom_value_changed") - Global.zoom_level_spinbox.max_value = 100.0/zoom_min.x + Global.zoom_level_spinbox.max_value = 100.0 / zoom_min.x Global.zoom_level_spinbox.get_child(0).connect("focus_exited", self, "zoom_focus_exited") @@ -46,19 +54,23 @@ func rotation_button_pressed() -> void: Global.rotation_level_button.visible = false Global.rotation_level_spinbox.visible = true Global.rotation_level_spinbox.editable = true - Global.rotation_level_spinbox.value = str2var(Global.rotation_level_button.text.replace("°","")) - Global.rotation_level_spinbox.get_child(0).grab_focus() #since the actual lineedit is the first child of spinbox + Global.rotation_level_spinbox.value = str2var( + Global.rotation_level_button.text.replace("°", "") + ) + # Since the actual LineEdit is the first child of SpinBox + Global.rotation_level_spinbox.get_child(0).grab_focus() func rotation_value_changed(value) -> void: if index == Cameras.MAIN: - set_camera_rotation_degrees(-value) # Negative makes going up rotate clockwise + set_camera_rotation_degrees(-value) # Negative makes going up rotate clockwise func rotation_focus_exited() -> void: - if Global.rotation_level_spinbox.value != rotation: #If user pressed enter while editing + if Global.rotation_level_spinbox.value != rotation: # If user pressed enter while editing if index == Cameras.MAIN: - set_camera_rotation_degrees(-Global.rotation_level_spinbox.value) # Negative makes going up rotate clockwise + # Negative makes going up rotate clockwise + set_camera_rotation_degrees(-Global.rotation_level_spinbox.value) Global.rotation_level_button.visible = true Global.rotation_level_spinbox.visible = false Global.rotation_level_spinbox.editable = false @@ -68,8 +80,9 @@ func zoom_button_pressed() -> void: Global.zoom_level_button.visible = false Global.zoom_level_spinbox.visible = true Global.zoom_level_spinbox.editable = true - Global.zoom_level_spinbox.value = str2var(Global.zoom_level_button.text.replace("%","")) - Global.zoom_level_spinbox.get_child(0).grab_focus() #since the actual lineedit is the first child of spinbox + Global.zoom_level_spinbox.value = str2var(Global.zoom_level_button.text.replace("%", "")) + # Since the actual LineEdit is the first child of SpinBox + Global.zoom_level_spinbox.get_child(0).grab_focus() func zoom_value_changed(value) -> void: @@ -78,7 +91,7 @@ func zoom_value_changed(value) -> void: func zoom_focus_exited() -> void: - if Global.zoom_level_spinbox.value != round(100 / zoom.x): #If user pressed enter while editing + if Global.zoom_level_spinbox.value != round(100 / zoom.x): # If user pressed enter while editing if index == Cameras.MAIN: zoom_camera_percent(Global.zoom_level_spinbox.value) Global.zoom_level_button.visible = true @@ -92,19 +105,20 @@ func update_transparent_checker_offset() -> void: o.y = get_viewport_rect().size.y - o.y transparent_checker.update_offset(o, s) + # Get the speed multiplier for when you've pressed # a movement key for the given amount of time -func dir_move_zoom_multiplier(press_time : float) -> float: +func dir_move_zoom_multiplier(press_time: float) -> float: if press_time < 0: return 0.0 - if Input.is_key_pressed(KEY_SHIFT) and Input.is_key_pressed(KEY_CONTROL) : - return high_speed_move_rate + if Input.is_key_pressed(KEY_SHIFT) and Input.is_key_pressed(KEY_CONTROL): + return HIGH_SPEED_MOVE_RATE elif Input.is_key_pressed(KEY_SHIFT): - return medium_speed_move_rate + return MEDIUM_SPEED_MOVE_RATE elif !Input.is_key_pressed(KEY_CONTROL): # control + right/left is used to move frames so # we do this check to ensure that there is no conflict - return low_speed_move_rate + return LOW_SPEED_MOVE_RATE else: return 0.0 @@ -113,14 +127,12 @@ func reset_dir_move_time(direction) -> void: key_move_press_time[direction] = 0.0 -const key_move_action_names := ["ui_up", "ui_down", "ui_left", "ui_right"] - # Check if an event is a ui_up/down/left/right event-press :) -func is_action_direction_pressed(event : InputEvent, allow_echo: bool = true) -> bool: +func is_action_direction_pressed(event: InputEvent, allow_echo: bool = true) -> bool: for slot in Tools._slots.values(): if slot.tool_node is SelectionTool: return false - for action in key_move_action_names: + for action in KEY_MOVE_ACTION_NAMES: if event.is_action_pressed(action, allow_echo): return true return false @@ -131,7 +143,7 @@ func is_action_direction_released(event: InputEvent) -> bool: for slot in Tools._slots.values(): if slot.tool_node is SelectionTool: return false - for action in key_move_action_names: + for action in KEY_MOVE_ACTION_NAMES: if event.is_action_released(action): return true return false @@ -151,17 +163,6 @@ func get_action_direction(event: InputEvent): # -> Optional[Direction] return null -# Holds sign multipliers for the given directions nyaa -# (per the indices defined by Direction) -# UP, DOWN, LEFT, RIGHT in that order -const directional_sign_multipliers := [ - Vector2(0.0, -1.0), - Vector2(0.0, 1.0), - Vector2(-1.0, 0.0), - Vector2(1.0, 0.0) -] - - # Process an action event for a pressed direction # action func process_direction_action_pressed(event: InputEvent) -> void: @@ -171,9 +172,12 @@ func process_direction_action_pressed(event: InputEvent) -> void: var increment := get_process_delta_time() # Count the total time we've been doing this ^.^ key_move_press_time[dir] += increment - var this_direction_press_time : float = key_move_press_time[dir] + var this_direction_press_time: float = key_move_press_time[dir] var move_speed := dir_move_zoom_multiplier(this_direction_press_time) - offset = offset + move_speed * increment * directional_sign_multipliers[dir].rotated(rotation) * zoom + offset = ( + offset + + move_speed * increment * DIRECTIONAL_SIGN_MULTIPLIERS[dir].rotated(rotation) * zoom + ) update_rulers() update_transparent_checker_offset() @@ -186,7 +190,7 @@ func process_direction_action_released(event: InputEvent) -> void: reset_dir_move_time(dir) -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if !Global.can_draw: drag = false return @@ -200,17 +204,18 @@ func _input(event : InputEvent) -> void: drag = true elif event.is_action_released("middle_mouse") || event.is_action_released("space"): drag = false - elif event.is_action_pressed("zoom_in"): # Wheel Up Event + elif event.is_action_pressed("zoom_in"): # Wheel Up Event zoom_camera(-1) - elif event.is_action_pressed("zoom_out"): # Wheel Down Event + elif event.is_action_pressed("zoom_out"): # Wheel Down Event zoom_camera(1) - elif event is InputEventMagnifyGesture: # Zoom Gesture on a Laptop touchpad + elif event is InputEventMagnifyGesture: # Zoom Gesture on a Laptop touchpad if event.factor < 1: zoom_camera(1) else: zoom_camera(-1) - elif event is InputEventPanGesture and OS.get_name() != "Android": # Pan Gesture on a Latop touchpad - offset = offset + event.delta.rotated(rotation) * zoom * 7 # for moving the canvas + elif event is InputEventPanGesture and OS.get_name() != "Android": + # Pan Gesture on a Latop touchpad + offset = offset + event.delta.rotated(rotation) * zoom * 7 # for moving the canvas elif event is InputEventMouseMotion && drag: offset = offset - event.relative.rotated(rotation) * zoom update_transparent_checker_offset() @@ -232,8 +237,8 @@ func rotate_camera_around_point(degrees: float, point: Vector2) -> void: func set_camera_rotation_degrees(degrees: float) -> void: - var difference := degrees - rotation_degrees - var canvas_center := Global.current_project.size / 2 + var difference := degrees - rotation_degrees + var canvas_center: Vector2 = Global.current_project.size / 2 offset = (offset - canvas_center).rotated(deg2rad(difference)) + canvas_center rotation_degrees = wrapf(degrees, -180, 180) rotation_changed() @@ -247,15 +252,22 @@ func rotation_changed() -> void: # Zoom Camera -func zoom_camera(dir : int) -> void: +func zoom_camera(dir: int) -> void: var viewport_size := viewport_container.rect_size if Global.smooth_zoom: var zoom_margin = zoom * dir / 5 var new_zoom = zoom + zoom_margin if new_zoom > zoom_min && new_zoom < zoom_max: - var new_offset = offset + (-0.5 * viewport_size + mouse_pos).rotated(rotation) * (zoom - new_zoom) - tween.interpolate_property(self, "zoom", zoom, new_zoom, 0.05, Tween.TRANS_LINEAR, Tween.EASE_IN) - tween.interpolate_property(self, "offset", offset, new_offset, 0.05, Tween.TRANS_LINEAR, Tween.EASE_IN) + var new_offset = ( + offset + + (-0.5 * viewport_size + mouse_pos).rotated(rotation) * (zoom - new_zoom) + ) + tween.interpolate_property( + self, "zoom", zoom, new_zoom, 0.05, Tween.TRANS_LINEAR, Tween.EASE_IN + ) + tween.interpolate_property( + self, "offset", offset, new_offset, 0.05, Tween.TRANS_LINEAR, Tween.EASE_IN + ) tween.start() else: @@ -271,11 +283,13 @@ func zoom_camera(dir : int) -> void: zoom_changed() -func zoom_camera_percent(value : float) -> void: - var percent :float = (100.0 / value) +func zoom_camera_percent(value: float) -> void: + var percent: float = 100.0 / value var new_zoom = Vector2(percent, percent) if Global.smooth_zoom: - tween.interpolate_property(self, "zoom", zoom, new_zoom, 0.05, Tween.TRANS_LINEAR, Tween.EASE_IN) + tween.interpolate_property( + self, "zoom", zoom, new_zoom, 0.05, Tween.TRANS_LINEAR, Tween.EASE_IN + ) tween.start() else: zoom = new_zoom @@ -312,16 +326,16 @@ func zoom_100() -> void: zoom_changed() -func fit_to_frame(size : Vector2) -> void: +func fit_to_frame(size: Vector2) -> void: offset = size / 2 # Adjust to the rotated size: if rotation != 0.0: # Calculating the rotated corners of the frame to find its rotated size - var a:= Vector2.ZERO # Top left - var b:= Vector2(size.x, 0).rotated(rotation) # Top right - var c:= Vector2(0, size.y).rotated(rotation) # Bottom left - var d:= Vector2(size.x, size.y).rotated(rotation) # Bottom right + var a := Vector2.ZERO # Top left + var b := Vector2(size.x, 0).rotated(rotation) # Top right + var c := Vector2(0, size.y).rotated(rotation) # Bottom left + var d := Vector2(size.x, size.y).rotated(rotation) # Bottom right # Find how far apart each opposite point is on each axis, and take the longer one size.x = max(abs(a.x - d.x), abs(b.x - c.x)) @@ -332,7 +346,7 @@ func fit_to_frame(size : Vector2) -> void: var v_ratio := viewport_container.rect_size.y / size.y var ratio := min(h_ratio, v_ratio) if ratio == 0: - ratio = 0.1 # Set it to a non-zero value just in case + ratio = 0.1 # Set it to a non-zero value just in case # If the ratio is 0, it means that the viewport container is hidden # in that case, use the other viewport to get the ratio if index == Cameras.MAIN: diff --git a/src/UI/Canvas/Canvas.gd b/src/UI/Canvas/Canvas.gd index 511761030..10e5241f8 100644 --- a/src/UI/Canvas/Canvas.gd +++ b/src/UI/Canvas/Canvas.gd @@ -1,14 +1,13 @@ class_name Canvas extends Node2D - var fill_color := Color(0, 0, 0, 0) var current_pixel := Vector2.ZERO var can_undo := true -var sprite_changed_this_frame := false # for optimization purposes +var sprite_changed_this_frame := false # for optimization purposes var move_preview_location := Vector2.ZERO -onready var currently_visible_frame : Viewport = $CurrentlyVisibleFrame +onready var currently_visible_frame: Viewport = $CurrentlyVisibleFrame onready var current_frame_drawer = $CurrentlyVisibleFrame/CurrentFrameDrawer onready var tile_mode = $TileMode onready var pixel_grid = $PixelGrid @@ -20,7 +19,7 @@ onready var previews = $Previews # Called when the node enters the scene tree for the first time. func _ready() -> void: - var frame : Frame = new_empty_frame(true) + var frame: Frame = new_empty_frame(true) Global.current_project.frames.append(frame) yield(get_tree(), "idle_frame") camera_zoom() @@ -30,18 +29,18 @@ func _draw() -> void: Global.second_viewport.get_child(0).get_node("CanvasPreview").update() Global.small_preview_viewport.get_child(0).get_node("CanvasPreview").update() - var current_cels : Array = Global.current_project.frames[Global.current_project.current_frame].cels - var current_layer : int = Global.current_project.current_layer - var _position := position - var _scale := scale + var current_cels: Array = Global.current_project.frames[Global.current_project.current_frame].cels + var current_layer: int = Global.current_project.current_layer + var position_tmp := position + var scale_tmp := scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 - draw_set_transform(_position, rotation, _scale) + position_tmp.x = position_tmp.x + Global.current_project.size.x + scale_tmp.x = -1 + draw_set_transform(position_tmp, rotation, scale_tmp) # Draw current frame layers for i in range(Global.current_project.layers.size()): var modulate_color := Color(1, 1, 1, current_cels[i].opacity) - if Global.current_project.layers[i].visible: # if it's visible + if Global.current_project.layers[i].visible: # if it's visible if i == current_layer: draw_texture(current_cels[i].image_texture, move_preview_location, modulate_color) else: @@ -56,7 +55,7 @@ func _draw() -> void: draw_set_transform(position, rotation, scale) -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: # Don't process anything below if the input isn't a mouse event, or Shift/Ctrl. # This decreases CPU/GPU usage slightly. if not event is InputEventMouse: @@ -102,19 +101,25 @@ func camera_zoom() -> void: camera.fit_to_frame(Global.current_project.size) camera.save_values_to_project() - Global.transparent_checker._ready() # To update the rect size + Global.transparent_checker.update_rect() -func new_empty_frame(first_time := false, single_layer := false, size := Global.current_project.size) -> Frame: +func new_empty_frame( + first_time := false, single_layer := false, size := Global.current_project.size +) -> Frame: var frame := Frame.new() - for l in Global.current_project.layers: # Create as many cels as there are layers + for l in Global.current_project.layers: # Create as many cels as there are layers # The sprite itself var sprite := Image.new() if first_time: if Global.config_cache.has_section_key("preferences", "default_image_width"): - Global.current_project.size.x = Global.config_cache.get_value("preferences", "default_image_width") + Global.current_project.size.x = Global.config_cache.get_value( + "preferences", "default_image_width" + ) if Global.config_cache.has_section_key("preferences", "default_image_height"): - Global.current_project.size.y = Global.config_cache.get_value("preferences", "default_image_height") + Global.current_project.size.y = Global.config_cache.get_value( + "preferences", "default_image_height" + ) if Global.config_cache.has_section_key("preferences", "default_fill_color"): fill_color = Global.config_cache.get_value("preferences", "default_fill_color") sprite.create(size.x, size.y, false, Image.FORMAT_RGBA8) @@ -127,7 +132,9 @@ func new_empty_frame(first_time := false, single_layer := false, size := Global. return frame -func handle_undo(action : String, project : Project = Global.current_project, layer_index := -2, frame_index := -2) -> void: +func handle_undo( + action: String, project: Project = Global.current_project, layer_index := -2, frame_index := -2 +) -> void: if !can_undo: return @@ -167,7 +174,9 @@ func handle_undo(action : String, project : Project = Global.current_project, la can_undo = false -func handle_redo(_action : String, project : Project = Global.current_project, layer_index := -2, frame_index := -2) -> void: +func handle_redo( + _action: String, project: Project = Global.current_project, layer_index := -2, frame_index := -2 +) -> void: can_undo = true if project.undos < project.undo_redo.get_version(): return @@ -201,38 +210,38 @@ func handle_redo(_action : String, project : Project = Global.current_project, l project.undo_redo.commit_action() -func update_texture(layer_index : int, frame_index := -1, project : Project = Global.current_project) -> void: - if frame_index == -1: - frame_index = project.current_frame +func update_texture(layer_i: int, frame_i := -1, project: Project = Global.current_project) -> void: + if frame_i == -1: + frame_i = project.current_frame - if frame_index < project.frames.size() and layer_index < project.layers.size(): - var current_cel : Cel = project.frames[frame_index].cels[layer_index] + if frame_i < project.frames.size() and layer_i < project.layers.size(): + var current_cel: Cel = project.frames[frame_i].cels[layer_i] current_cel.image_texture.create_from_image(current_cel.image, 0) if project == Global.current_project: - var frame_texture_rect : TextureRect - frame_texture_rect = project.layers[layer_index].frame_container.get_child(frame_index).find_node("CelTexture") + var frame_button = project.layers[layer_i].frame_container.get_child(frame_i) + var frame_texture_rect: TextureRect + frame_texture_rect = frame_button.find_node("CelTexture") frame_texture_rect.texture = current_cel.image_texture -func update_selected_cels_textures(project : Project = Global.current_project) -> void: +func update_selected_cels_textures(project: Project = Global.current_project) -> void: for cel_index in project.selected_cels: - var frame_index : int = cel_index[0] - var layer_index : int = cel_index[1] + var frame_index: int = cel_index[0] + var layer_index: int = cel_index[1] if frame_index < project.frames.size() and layer_index < project.layers.size(): - var current_cel : Cel = project.frames[frame_index].cels[layer_index] + var current_cel: Cel = project.frames[frame_index].cels[layer_index] current_cel.image_texture.create_from_image(current_cel.image, 0) if project == Global.current_project: - var frame_texture_rect : TextureRect - frame_texture_rect = project.layers[layer_index].frame_container.get_child(frame_index).find_node("CelTexture") - frame_texture_rect.texture = current_cel.image_texture + var cel_button = project.layers[layer_index].frame_container.get_child(frame_index) + var cel_texture_rect: TextureRect = cel_button.find_node("CelTexture") + cel_texture_rect.texture = current_cel.image_texture func onion_skinning() -> void: - # Past - if Global.onion_skinning_past_rate > 0: - var color : Color + if Global.onion_skinning_past_rate > 0: # Past + var color: Color if Global.onion_skinning_blue_red: color = Color.blue else: @@ -240,15 +249,17 @@ func onion_skinning() -> void: for i in range(1, Global.onion_skinning_past_rate + 1): if Global.current_project.current_frame >= i: var layer_i := 0 - for layer in Global.current_project.frames[Global.current_project.current_frame - i].cels: + for layer in Global.current_project.frames[( + Global.current_project.current_frame + - i + )].cels: if Global.current_project.layers[layer_i].visible: color.a = 0.6 / i draw_texture(layer.image_texture, Vector2.ZERO, color) layer_i += 1 - # Future - if Global.onion_skinning_future_rate > 0: - var color : Color + if Global.onion_skinning_future_rate > 0: # Future + var color: Color if Global.onion_skinning_blue_red: color = Color.red else: @@ -256,7 +267,10 @@ func onion_skinning() -> void: for i in range(1, Global.onion_skinning_future_rate + 1): if Global.current_project.current_frame < Global.current_project.frames.size() - i: var layer_i := 0 - for layer in Global.current_project.frames[Global.current_project.current_frame + i].cels: + for layer in Global.current_project.frames[( + Global.current_project.current_frame + + i + )].cels: if Global.current_project.layers[layer_i].visible: color.a = 0.6 / i draw_texture(layer.image_texture, Vector2.ZERO, color) diff --git a/src/UI/Canvas/CanvasPreview.gd b/src/UI/Canvas/CanvasPreview.gd index 1c2163234..5a459ca40 100644 --- a/src/UI/Canvas/CanvasPreview.gd +++ b/src/UI/Canvas/CanvasPreview.gd @@ -1,19 +1,22 @@ extends Node2D +var frame: int = 0 +onready var animation_timer: Timer = $AnimationTimer -var frame : int = 0 -onready var animation_timer : Timer = $AnimationTimer func _draw() -> void: - var current_project : Project = Global.current_project + var current_project: Project = Global.current_project if frame >= current_project.frames.size(): frame = current_project.current_frame - $AnimationTimer.wait_time = current_project.frames[frame].duration * (1 / Global.current_project.fps) + $AnimationTimer.wait_time = ( + current_project.frames[frame].duration + * (1 / Global.current_project.fps) + ) if animation_timer.is_stopped(): frame = current_project.current_frame - var current_cels : Array = current_project.frames[frame].cels + var current_cels: Array = current_project.frames[frame].cels # Draw current frame layers for i in range(current_cels.size()): @@ -23,13 +26,16 @@ func _draw() -> void: func _on_AnimationTimer_timeout() -> void: - var current_project : Project = Global.current_project + var current_project: Project = Global.current_project if frame < current_project.frames.size() - 1: frame += 1 else: frame = 0 $AnimationTimer.set_one_shot(true) - $AnimationTimer.wait_time = Global.current_project.frames[frame].duration * (1 / Global.current_project.fps) + $AnimationTimer.wait_time = ( + Global.current_project.frames[frame].duration + * (1 / Global.current_project.fps) + ) $AnimationTimer.start() update() diff --git a/src/UI/Canvas/CurrentFrameDrawer.gd b/src/UI/Canvas/CurrentFrameDrawer.gd index 8773853b9..e102a58ad 100644 --- a/src/UI/Canvas/CurrentFrameDrawer.gd +++ b/src/UI/Canvas/CurrentFrameDrawer.gd @@ -2,7 +2,7 @@ extends Node2D func _draw() -> void: - var current_cels : Array = Global.current_project.frames[Global.current_project.current_frame].cels + var current_cels: Array = Global.current_project.frames[Global.current_project.current_frame].cels for i in range(Global.current_project.layers.size()): if Global.current_project.layers[i].visible and current_cels[i].opacity > 0: var modulate_color := Color(1, 1, 1, current_cels[i].opacity) diff --git a/src/UI/Canvas/Grid.gd b/src/UI/Canvas/Grid.gd index f5b9135db..52162ec96 100644 --- a/src/UI/Canvas/Grid.gd +++ b/src/UI/Canvas/Grid.gd @@ -5,7 +5,7 @@ func _draw() -> void: if not Global.draw_grid: return - var target_rect : Rect2 + var target_rect: Rect2 if Global.grid_draw_over_tile_mode: target_rect = Global.current_project.get_tile_mode_rect() else: @@ -13,7 +13,7 @@ func _draw() -> void: if target_rect.has_no_area(): return - var grid_type : int = Global.grid_type + var grid_type: int = Global.grid_type if grid_type == Global.GridTypes.CARTESIAN || grid_type == Global.GridTypes.ALL: _draw_cartesian_grid(target_rect) @@ -21,20 +21,26 @@ func _draw() -> void: _draw_isometric_grid(target_rect) -func _draw_cartesian_grid(target_rect : Rect2) -> void: +func _draw_cartesian_grid(target_rect: Rect2) -> void: # Using Array instead of PoolVector2Array to avoid kinda # random "resize: Can't resize PoolVector if locked" errors. # See: https://github.com/Orama-Interactive/Pixelorama/issues/331 # It will be converted to PoolVector2Array before being sent to be rendered. var grid_multiline_points := [] - var x : float = target_rect.position.x + fposmod(Global.grid_offset_x - target_rect.position.x, Global.grid_width) + var x: float = ( + target_rect.position.x + + fposmod(Global.grid_offset_x - target_rect.position.x, Global.grid_width) + ) while x <= target_rect.end.x: grid_multiline_points.push_back(Vector2(x, target_rect.position.y)) grid_multiline_points.push_back(Vector2(x, target_rect.end.y)) x += Global.grid_width - var y : float = target_rect.position.y + fposmod(Global.grid_offset_y - target_rect.position.y, Global.grid_height) + var y: float = ( + target_rect.position.y + + fposmod(Global.grid_offset_y - target_rect.position.y, Global.grid_height) + ) while y <= target_rect.end.y: grid_multiline_points.push_back(Vector2(target_rect.position.x, y)) grid_multiline_points.push_back(Vector2(target_rect.end.x, y)) @@ -44,38 +50,42 @@ func _draw_cartesian_grid(target_rect : Rect2) -> void: draw_multiline(grid_multiline_points, Global.grid_color) -func _draw_isometric_grid(target_rect : Rect2) -> void: +func _draw_isometric_grid(target_rect: Rect2) -> void: # Using Array instead of PoolVector2Array to avoid kinda # random "resize: Can't resize PoolVector if locked" errors. # See: https://github.com/Orama-Interactive/Pixelorama/issues/331 # It will be converted to PoolVector2Array before being sent to be rendered. var grid_multiline_points := [] - var cell_size := Vector2(Global.grid_isometric_cell_bounds_width, Global.grid_isometric_cell_bounds_height) - var max_cell_count : Vector2 = target_rect.size / cell_size + var cell_size := Vector2( + Global.grid_isometric_cell_bounds_width, Global.grid_isometric_cell_bounds_height + ) + var max_cell_count: Vector2 = target_rect.size / cell_size var origin := Vector2(Global.grid_offset_x, Global.grid_offset_y) - var origin_offset : Vector2 = (origin - target_rect.position).posmodv(cell_size) + var origin_offset: Vector2 = (origin - target_rect.position).posmodv(cell_size) # lines ↗↗↗ (from bottom-left to top-right) var per_cell_offset := cell_size * Vector2(1, -1) # lines ↗↗↗ starting from the rect's left side (top to bottom): - var y : float = fposmod(origin_offset.y + cell_size.y * (0.5 + origin_offset.x / cell_size.x), cell_size.y) + var y: float = fposmod( + origin_offset.y + cell_size.y * (0.5 + origin_offset.x / cell_size.x), cell_size.y + ) while y < target_rect.size.y: - var start : Vector2 = target_rect.position + Vector2(0, y) - var cells_to_rect_bounds : float = min(max_cell_count.x, y / cell_size.y) - var end : Vector2 = start + cells_to_rect_bounds * per_cell_offset + var start: Vector2 = target_rect.position + Vector2(0, y) + var cells_to_rect_bounds: float = min(max_cell_count.x, y / cell_size.y) + var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset grid_multiline_points.push_back(start) grid_multiline_points.push_back(end) y += cell_size.y # lines ↗↗↗ starting from the rect's bottom side (left to right): - var x : float = (y - target_rect.size.y) / cell_size.y * cell_size.x + var x: float = (y - target_rect.size.y) / cell_size.y * cell_size.x while x < target_rect.size.x: - var start : Vector2 = target_rect.position + Vector2(x, target_rect.size.y) - var cells_to_rect_bounds : float = min(max_cell_count.y, max_cell_count.x - x / cell_size.x) - var end : Vector2 = start + cells_to_rect_bounds * per_cell_offset + var start: Vector2 = target_rect.position + Vector2(x, target_rect.size.y) + var cells_to_rect_bounds: float = min(max_cell_count.y, max_cell_count.x - x / cell_size.x) + var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset grid_multiline_points.push_back(start) grid_multiline_points.push_back(end) x += cell_size.x @@ -86,9 +96,9 @@ func _draw_isometric_grid(target_rect : Rect2) -> void: # lines ↘↘↘ starting from the rect's left side (top to bottom): y = fposmod(origin_offset.y - cell_size.y * (0.5 + origin_offset.x / cell_size.x), cell_size.y) while y < target_rect.size.y: - var start : Vector2 = target_rect.position + Vector2(0, y) - var cells_to_rect_bounds : float = min(max_cell_count.x, max_cell_count.y - y / cell_size.y) - var end : Vector2 = start + cells_to_rect_bounds * per_cell_offset + var start: Vector2 = target_rect.position + Vector2(0, y) + var cells_to_rect_bounds: float = min(max_cell_count.x, max_cell_count.y - y / cell_size.y) + var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset grid_multiline_points.push_back(start) grid_multiline_points.push_back(end) y += cell_size.y @@ -96,9 +106,9 @@ func _draw_isometric_grid(target_rect : Rect2) -> void: # lines ↘↘↘ starting from the rect's top side (left to right): x = fposmod(origin_offset.x - cell_size.x * (0.5 + origin_offset.y / cell_size.y), cell_size.x) while x < target_rect.size.x: - var start : Vector2 = target_rect.position + Vector2(x, 0) - var cells_to_rect_bounds : float = min(max_cell_count.y, max_cell_count.x - x / cell_size.x) - var end : Vector2 = start + cells_to_rect_bounds * per_cell_offset + var start: Vector2 = target_rect.position + Vector2(x, 0) + var cells_to_rect_bounds: float = min(max_cell_count.y, max_cell_count.x - x / cell_size.x) + var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset grid_multiline_points.push_back(start) grid_multiline_points.push_back(end) x += cell_size.x diff --git a/src/UI/Canvas/Indicators.gd b/src/UI/Canvas/Indicators.gd index f979f6439..1f8ff0b86 100644 --- a/src/UI/Canvas/Indicators.gd +++ b/src/UI/Canvas/Indicators.gd @@ -1,7 +1,7 @@ extends Node2D -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if Global.has_focus and event is InputEventMouseMotion: update() diff --git a/src/UI/Canvas/PixelGrid.gd b/src/UI/Canvas/PixelGrid.gd index cbaff2d43..1c929b6c9 100644 --- a/src/UI/Canvas/PixelGrid.gd +++ b/src/UI/Canvas/PixelGrid.gd @@ -9,7 +9,7 @@ func _draw() -> void: if zoom_percentage < Global.pixel_grid_show_at_zoom: return - var target_rect : Rect2 = Global.current_project.get_tile_mode_rect() + var target_rect: Rect2 = Global.current_project.get_tile_mode_rect() if target_rect.has_no_area(): return diff --git a/src/UI/Canvas/Previews.gd b/src/UI/Canvas/Previews.gd index 935aedff8..b93478659 100644 --- a/src/UI/Canvas/Previews.gd +++ b/src/UI/Canvas/Previews.gd @@ -1,6 +1,7 @@ extends Node2D -func _input(event : InputEvent) -> void: + +func _input(event: InputEvent) -> void: if Global.has_focus and event is InputEventMouse: update() diff --git a/src/UI/Canvas/Rulers/Guide.gd b/src/UI/Canvas/Rulers/Guide.gd index 7fbd1b0eb..2c51922ab 100644 --- a/src/UI/Canvas/Rulers/Guide.gd +++ b/src/UI/Canvas/Rulers/Guide.gd @@ -1,6 +1,7 @@ -class_name Guide extends Line2D +class_name Guide +extends Line2D -enum Types {HORIZONTAL, VERTICAL} +enum Types { HORIZONTAL, VERTICAL } var font := preload("res://assets/fonts/Roboto-Regular.tres") var has_focus := true @@ -17,7 +18,7 @@ func _ready() -> void: modulate.a = 0.5 -func _input(_event : InputEvent) -> void: +func _input(_event: InputEvent) -> void: if !visible: return var tmp_transform = get_canvas_transform().affine_inverse() @@ -32,7 +33,12 @@ func _input(_event : InputEvent) -> void: else: point0.x -= width * 3 point1.x += width * 3 - if Global.can_draw and Global.has_focus and point_in_rectangle(mouse_pos, point0, point1) and Input.is_action_just_pressed("left_mouse"): + if ( + Global.can_draw + and Global.has_focus + and point_in_rectangle(mouse_pos, point0, point1) + and Input.is_action_just_pressed("left_mouse") + ): if !point_in_rectangle(Global.canvas.current_pixel, Vector2.ZERO, project.size): has_focus = true Global.has_focus = false @@ -67,42 +73,89 @@ func _draw() -> void: var zoom: Vector2 = Global.camera.zoom # viewport_poly is an array of the points that make up the corners of the viewport - var viewport_poly:= [Vector2.ZERO, Vector2(viewport_size.x, 0), viewport_size, Vector2(0, viewport_size.y)] + var viewport_poly := [ + Vector2.ZERO, Vector2(viewport_size.x, 0), viewport_size, Vector2(0, viewport_size.y) + ] # Adjusting viewport_poly to take into account the camera offset, zoom, and rotation for p in range(viewport_poly.size()): - viewport_poly[p] = viewport_poly[p].rotated(Global.camera.rotation) * zoom + Vector2(Global.camera.offset.x - (viewport_size.rotated(Global.camera.rotation).x / 2) * zoom.x, Global.camera.offset.y - (viewport_size.rotated(Global.camera.rotation).y / 2) * zoom.y) + viewport_poly[p] = ( + viewport_poly[p].rotated(Global.camera.rotation) * zoom + + Vector2( + ( + Global.camera.offset.x + - (viewport_size.rotated(Global.camera.rotation).x / 2) * zoom.x + ), + ( + Global.camera.offset.y + - (viewport_size.rotated(Global.camera.rotation).y / 2) * zoom.y + ) + ) + ) - var string := "%spx" % str(stepify(mouse_pos.y if type == Types.HORIZONTAL else mouse_pos.x, 0.5)) + var string := ( + "%spx" + % str(stepify(mouse_pos.y if type == Types.HORIZONTAL else mouse_pos.x, 0.5)) + ) var color: Color = Global.control.theme.get_color("font_color", "Label") # X and Y offsets for nicer looking spacing var x_offset := 5 - var y_offset := -7 # Only used where the string is above the guide + var y_offset := -7 # Only used where the string is above the guide # Draw the string where the guide intersects with the viewport poly # Priority is top edge, then left, then right - var intersection = Geometry.segment_intersects_segment_2d(points[0], points[1], viewport_poly[0], viewport_poly[1]) + var intersection = Geometry.segment_intersects_segment_2d( + points[0], points[1], viewport_poly[0], viewport_poly[1] + ) if intersection: draw_set_transform(intersection, Global.camera.rotation, zoom * 2) - if intersection.distance_squared_to(viewport_poly[0]) < intersection.distance_squared_to(viewport_poly[1]): + if ( + intersection.distance_squared_to(viewport_poly[0]) + < intersection.distance_squared_to(viewport_poly[1]) + ): draw_string(font, Vector2(x_offset, font.get_height()), string, color) else: - draw_string(font, Vector2(-font.get_string_size(string).x - x_offset, font.get_height()), string, color) + draw_string( + font, + Vector2(-font.get_string_size(string).x - x_offset, font.get_height()), + string, + color + ) return - intersection = Geometry.segment_intersects_segment_2d(points[0], points[1], viewport_poly[3], viewport_poly[0]) + intersection = Geometry.segment_intersects_segment_2d( + points[0], points[1], viewport_poly[3], viewport_poly[0] + ) if intersection: draw_set_transform(intersection, Global.camera.rotation, zoom * 2) - if intersection.distance_squared_to(viewport_poly[3]) < intersection.distance_squared_to(viewport_poly[0]): + if ( + intersection.distance_squared_to(viewport_poly[3]) + < intersection.distance_squared_to(viewport_poly[0]) + ): draw_string(font, Vector2(x_offset, y_offset), string, color) else: draw_string(font, Vector2(x_offset, font.get_height()), string, color) return - intersection = Geometry.segment_intersects_segment_2d(points[0], points[1], viewport_poly[1], viewport_poly[2]) + intersection = Geometry.segment_intersects_segment_2d( + points[0], points[1], viewport_poly[1], viewport_poly[2] + ) if intersection: draw_set_transform(intersection, Global.camera.rotation, zoom * 2) - if intersection.distance_squared_to(viewport_poly[1]) < intersection.distance_squared_to(viewport_poly[2]): - draw_string(font, Vector2(-font.get_string_size(string).x - x_offset, font.get_height()), string, color) + if ( + intersection.distance_squared_to(viewport_poly[1]) + < intersection.distance_squared_to(viewport_poly[2]) + ): + draw_string( + font, + Vector2(-font.get_string_size(string).x - x_offset, font.get_height()), + string, + color + ) else: - draw_string(font, Vector2(-font.get_string_size(string).x - x_offset, y_offset), string, color) + draw_string( + font, + Vector2(-font.get_string_size(string).x - x_offset, y_offset), + string, + color + ) return # If there's no intersection with a viewport edge, show string in top left corner @@ -117,5 +170,5 @@ func outside_canvas() -> bool: return points[0].x < 0 || points[0].x > project.size.x -func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool: +func point_in_rectangle(p: Vector2, coord1: Vector2, coord2: Vector2) -> bool: return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y diff --git a/src/UI/Canvas/Rulers/HorizontalRuler.gd b/src/UI/Canvas/Rulers/HorizontalRuler.gd index 7f06f22cb..9f6480898 100644 --- a/src/UI/Canvas/Rulers/HorizontalRuler.gd +++ b/src/UI/Canvas/Rulers/HorizontalRuler.gd @@ -6,8 +6,8 @@ var font := preload("res://assets/fonts/Roboto-Small.tres") var major_subdivision := 2 var minor_subdivision := 4 -var first : Vector2 -var last : Vector2 +var first: Vector2 +var last: Vector2 func _ready() -> void: @@ -24,54 +24,85 @@ func _draw() -> void: transform.x = Vector2(zoom, zoom) # This tracks the "true" top left corner of the drawing: - transform.origin = Global.main_viewport.rect_size / 2 + Global.camera.offset.rotated(-Global.camera.rotation) * -zoom + transform.origin = ( + Global.main_viewport.rect_size / 2 + + Global.camera.offset.rotated(-Global.camera.rotation) * -zoom + ) var proj_size := Global.current_project.size # Calculating the rotated corners of the image, use min to find the farthest left - var a := Vector2.ZERO # Top left - var b := Vector2(proj_size.x, 0).rotated(-Global.camera.rotation) # Top right - var c := Vector2(0, proj_size.y).rotated(-Global.camera.rotation) # Bottom left - var d := Vector2(proj_size.x, proj_size.y).rotated(-Global.camera.rotation) # Bottom right + var a := Vector2.ZERO # Top left + var b := Vector2(proj_size.x, 0).rotated(-Global.camera.rotation) # Top right + var c := Vector2(0, proj_size.y).rotated(-Global.camera.rotation) # Bottom left + var d := Vector2(proj_size.x, proj_size.y).rotated(-Global.camera.rotation) # Bottom right transform.origin.x += min(min(a.x, b.x), min(c.x, d.x)) * zoom var basic_rule := 100.0 var i := 0 - while(basic_rule * zoom > 100): + while basic_rule * zoom > 100: basic_rule /= 5.0 if i % 2 else 2.0 i += 1 i = 0 - while(basic_rule * zoom < 100): + while basic_rule * zoom < 100: basic_rule *= 2.0 if i % 2 else 5.0 i += 1 ruler_transform = ruler_transform.scaled(Vector2(basic_rule, basic_rule)) - major_subdivide = major_subdivide.scaled(Vector2(1.0 / major_subdivision, 1.0 / major_subdivision)) - minor_subdivide = minor_subdivide.scaled(Vector2(1.0 / minor_subdivision, 1.0 / minor_subdivision)) + major_subdivide = major_subdivide.scaled( + Vector2(1.0 / major_subdivision, 1.0 / major_subdivision) + ) + minor_subdivide = minor_subdivide.scaled( + Vector2(1.0 / minor_subdivision, 1.0 / minor_subdivision) + ) - first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(Vector2.ZERO) - last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(Global.main_viewport.rect_size) + first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform( + Vector2.ZERO + ) + last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform( + Global.main_viewport.rect_size + ) for j in range(ceil(first.x), ceil(last.x)): - var position : Vector2 = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Vector2(j, 0)) + var position: Vector2 = (transform * ruler_transform * major_subdivide * minor_subdivide).xform( + Vector2(j, 0) + ) if j % (major_subdivision * minor_subdivision) == 0: - draw_line(Vector2(position.x + RULER_WIDTH, 0), Vector2(position.x + RULER_WIDTH, RULER_WIDTH), Color.white) + draw_line( + Vector2(position.x + RULER_WIDTH, 0), + Vector2(position.x + RULER_WIDTH, RULER_WIDTH), + Color.white + ) var val = (ruler_transform * major_subdivide * minor_subdivide).xform(Vector2(j, 0)).x - draw_string(font, Vector2(position.x + RULER_WIDTH + 2, font.get_height() - 4), str(int(val))) + draw_string( + font, Vector2(position.x + RULER_WIDTH + 2, font.get_height() - 4), str(int(val)) + ) else: if j % minor_subdivision == 0: - draw_line(Vector2(position.x + RULER_WIDTH, RULER_WIDTH * 0.33), Vector2(position.x + RULER_WIDTH, RULER_WIDTH), Color.white) + draw_line( + Vector2(position.x + RULER_WIDTH, RULER_WIDTH * 0.33), + Vector2(position.x + RULER_WIDTH, RULER_WIDTH), + Color.white + ) else: - draw_line(Vector2(position.x + RULER_WIDTH, RULER_WIDTH * 0.66), Vector2(position.x + RULER_WIDTH, RULER_WIDTH), Color.white) + draw_line( + Vector2(position.x + RULER_WIDTH, RULER_WIDTH * 0.66), + Vector2(position.x + RULER_WIDTH, RULER_WIDTH), + Color.white + ) func _on_HorizontalRuler_pressed() -> void: + create_guide() + + +func create_guide() -> void: if !Global.show_guides: return var mouse_pos := get_local_mouse_position() - if mouse_pos.x < RULER_WIDTH: # For double guides - Global.vertical_ruler._on_VerticalRuler_pressed() + if mouse_pos.x < RULER_WIDTH: # For double guides + Global.vertical_ruler.create_guide() var guide := Guide.new() if abs(Global.camera.rotation_degrees) < 45 or abs(Global.camera.rotation_degrees) > 135: guide.type = guide.Types.HORIZONTAL @@ -88,7 +119,7 @@ func _on_HorizontalRuler_pressed() -> void: func _on_HorizontalRuler_mouse_entered() -> void: var mouse_pos := get_local_mouse_position() - if mouse_pos.x < RULER_WIDTH: # For double guides + if mouse_pos.x < RULER_WIDTH: # For double guides mouse_default_cursor_shape = Control.CURSOR_FDIAGSIZE else: mouse_default_cursor_shape = Control.CURSOR_VSPLIT diff --git a/src/UI/Canvas/Rulers/SymmetryGuide.gd b/src/UI/Canvas/Rulers/SymmetryGuide.gd index 13945bace..0c7c0d9b6 100644 --- a/src/UI/Canvas/Rulers/SymmetryGuide.gd +++ b/src/UI/Canvas/Rulers/SymmetryGuide.gd @@ -1,5 +1,5 @@ -class_name SymmetryGuide extends Guide - +class_name SymmetryGuide +extends Guide var _texture = preload("res://assets/graphics/dotted_line.png") @@ -11,10 +11,10 @@ func _ready() -> void: texture_mode = Line2D.LINE_TEXTURE_TILE width = Global.camera.zoom.x * 4 # Add a subtle difference to the normal guide color by mixing in some blue - default_color = Global.guide_color.linear_interpolate(Color(0.2 , 0.2, .65), .6) + default_color = Global.guide_color.linear_interpolate(Color(0.2, 0.2, .65), .6) -func _input(_event : InputEvent) -> void: +func _input(_event: InputEvent) -> void: if !visible: return ._input(_event) diff --git a/src/UI/Canvas/Rulers/VerticalRuler.gd b/src/UI/Canvas/Rulers/VerticalRuler.gd index c7c25e2fa..9a1a57965 100644 --- a/src/UI/Canvas/Rulers/VerticalRuler.gd +++ b/src/UI/Canvas/Rulers/VerticalRuler.gd @@ -6,8 +6,8 @@ var font := preload("res://assets/fonts/Roboto-Small.tres") var major_subdivision := 2 var minor_subdivision := 4 -var first : Vector2 -var last : Vector2 +var first: Vector2 +var last: Vector2 func _ready() -> void: @@ -24,37 +24,50 @@ func _draw() -> void: transform.y = Vector2(zoom, zoom) # This tracks the "true" top left corner of the drawing: - transform.origin = Global.main_viewport.rect_size / 2 + Global.camera.offset.rotated(-Global.camera.rotation) * -zoom + transform.origin = ( + Global.main_viewport.rect_size / 2 + + Global.camera.offset.rotated(-Global.camera.rotation) * -zoom + ) var proj_size := Global.current_project.size # Calculating the rotated corners of the image, use min to find the top one - var a := Vector2.ZERO # Top left - var b := Vector2(proj_size.x, 0).rotated(-Global.camera.rotation) # Top right - var c := Vector2(0, proj_size.y).rotated(-Global.camera.rotation) # Bottom left - var d := Vector2(proj_size.x, proj_size.y).rotated(-Global.camera.rotation) # Bottom right + var a := Vector2.ZERO # Top left + var b := Vector2(proj_size.x, 0).rotated(-Global.camera.rotation) # Top right + var c := Vector2(0, proj_size.y).rotated(-Global.camera.rotation) # Bottom left + var d := Vector2(proj_size.x, proj_size.y).rotated(-Global.camera.rotation) # Bottom right transform.origin.y += min(min(a.y, b.y), min(c.y, d.y)) * zoom var basic_rule := 100.0 var i := 0 - while(basic_rule * zoom > 100): + while basic_rule * zoom > 100: basic_rule /= 5.0 if i % 2 else 2.0 i += 1 i = 0 - while(basic_rule * zoom < 100): + while basic_rule * zoom < 100: basic_rule *= 2.0 if i % 2 else 5.0 i += 1 ruler_transform = ruler_transform.scaled(Vector2(basic_rule, basic_rule)) - major_subdivide = major_subdivide.scaled(Vector2(1.0 / major_subdivision, 1.0 / major_subdivision)) - minor_subdivide = minor_subdivide.scaled(Vector2(1.0 / minor_subdivision, 1.0 / minor_subdivision)) + major_subdivide = major_subdivide.scaled( + Vector2(1.0 / major_subdivision, 1.0 / major_subdivision) + ) + minor_subdivide = minor_subdivide.scaled( + Vector2(1.0 / minor_subdivision, 1.0 / minor_subdivision) + ) - first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(Vector2.ZERO) - last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(Global.main_viewport.rect_size) + first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform( + Vector2.ZERO + ) + last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform( + Global.main_viewport.rect_size + ) for j in range(ceil(first.y), ceil(last.y)): - var position : Vector2 = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Vector2(0, j)) + var position: Vector2 = (transform * ruler_transform * major_subdivide * minor_subdivide).xform( + Vector2(0, j) + ) if j % (major_subdivision * minor_subdivision) == 0: draw_line(Vector2(0, position.y), Vector2(RULER_WIDTH, position.y), Color.white) var text_xform = Transform2D(-PI / 2, Vector2(font.get_height() - 4, position.y - 2)) @@ -64,12 +77,24 @@ func _draw() -> void: draw_set_transform_matrix(get_transform()) else: if j % minor_subdivision == 0: - draw_line(Vector2(RULER_WIDTH * 0.33, position.y), Vector2(RULER_WIDTH, position.y), Color.white) + draw_line( + Vector2(RULER_WIDTH * 0.33, position.y), + Vector2(RULER_WIDTH, position.y), + Color.white + ) else: - draw_line(Vector2(RULER_WIDTH * 0.66, position.y), Vector2(RULER_WIDTH, position.y), Color.white) + draw_line( + Vector2(RULER_WIDTH * 0.66, position.y), + Vector2(RULER_WIDTH, position.y), + Color.white + ) func _on_VerticalRuler_pressed() -> void: + create_guide() + + +func create_guide() -> void: if !Global.show_guides: return var guide := Guide.new() diff --git a/src/UI/Canvas/Selection.gd b/src/UI/Canvas/Selection.gd index b677cd588..5505c4c32 100644 --- a/src/UI/Canvas/Selection.gd +++ b/src/UI/Canvas/Selection.gd @@ -1,41 +1,6 @@ extends Node2D - -class Clipboard: - var image := Image.new() - var selection_bitmap := BitMap.new() - var big_bounding_rectangle := Rect2() - var selection_offset := Vector2.ZERO - - -class Gizmo: - enum Type {SCALE, ROTATE} - - var rect : Rect2 - var direction := Vector2.ZERO - var type : int - - func _init(_type : int = Type.SCALE, _direction := Vector2.ZERO) -> void: - type = _type - direction = _direction - - - func get_cursor() -> int: - var cursor := Input.CURSOR_MOVE - if direction == Vector2.ZERO: - return Input.CURSOR_POINTING_HAND - elif direction == Vector2(-1, -1) or direction == Vector2(1, 1): # Top left or bottom right - cursor = Input.CURSOR_FDIAGSIZE - elif direction == Vector2(1, -1) or direction == Vector2(-1, 1): # Top right or bottom left - cursor = Input.CURSOR_BDIAGSIZE - elif direction == Vector2(0, -1) or direction == Vector2(0, 1): # Center top or center bottom - cursor = Input.CURSOR_VSIZE - elif direction == Vector2(-1, 0) or direction == Vector2(1, 0): # Center left or center right - cursor = Input.CURSOR_HSIZE - return cursor - - -enum SelectionOperation {ADD, SUBTRACT, INTERSECT} +enum SelectionOperation { ADD, SUBTRACT, INTERSECT } const KEY_MOVE_ACTION_NAMES := ["ui_up", "ui_down", "ui_left", "ui_right"] @@ -58,30 +23,64 @@ var original_offset := Vector2.ZERO var preview_image := Image.new() var preview_image_texture := ImageTexture.new() -var undo_data : Dictionary -var gizmos := [] # Array of Gizmos -var dragged_gizmo : Gizmo = null +var undo_data: Dictionary +var gizmos := [] # Array of Gizmos +var dragged_gizmo: Gizmo = null var prev_angle := 0 var mouse_pos_on_gizmo_drag := Vector2.ZERO var clear_in_selected_cels := true -onready var marching_ants_outline : Sprite = $MarchingAntsOutline +onready var marching_ants_outline: Sprite = $MarchingAntsOutline + + +class Clipboard: + var image := Image.new() + var selection_bitmap := BitMap.new() + var big_bounding_rectangle := Rect2() + var selection_offset := Vector2.ZERO + + +class Gizmo: + enum Type { SCALE, ROTATE } + + var rect: Rect2 + var direction := Vector2.ZERO + var type: int + + func _init(_type: int = Type.SCALE, _direction := Vector2.ZERO) -> void: + type = _type + direction = _direction + + func get_cursor() -> int: + var cursor := Input.CURSOR_MOVE + if direction == Vector2.ZERO: + return Input.CURSOR_POINTING_HAND + elif direction == Vector2(-1, -1) or direction == Vector2(1, 1): # Top left or bottom right + cursor = Input.CURSOR_FDIAGSIZE + elif direction == Vector2(1, -1) or direction == Vector2(-1, 1): # Top right or bottom left + cursor = Input.CURSOR_BDIAGSIZE + elif direction == Vector2(0, -1) or direction == Vector2(0, 1): # Center top or center bottom + cursor = Input.CURSOR_VSIZE + elif direction == Vector2(-1, 0) or direction == Vector2(1, 0): # Center left or center right + cursor = Input.CURSOR_HSIZE + return cursor func _ready() -> void: - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(-1, -1))) # Top left - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(0, -1))) # Center top - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(1, -1))) # Top right - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(1, 0))) # Center right - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(1, 1))) # Bottom right - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(0, 1))) # Center bottom - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(-1, 1))) # Bottom left - gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(-1, 0))) # Center left + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(-1, -1))) # Top left + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(0, -1))) # Center top + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(1, -1))) # Top right + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(1, 0))) # Center right + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(1, 1))) # Bottom right + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(0, 1))) # Center bottom + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(-1, 1))) # Bottom left + gizmos.append(Gizmo.new(Gizmo.Type.SCALE, Vector2(-1, 0))) # Center left + # gizmos.append(Gizmo.new(Gizmo.Type.ROTATE)) # Rotation gizmo (temp) -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: if event is InputEventKey: if is_moving_content: if Input.is_action_just_pressed("enter"): @@ -92,7 +91,7 @@ func _input(event : InputEvent) -> void: move_with_arrow_keys(event) elif event is InputEventMouse: - var gizmo : Gizmo + var gizmo: Gizmo if big_bounding_rectangle.size != Vector2.ZERO: for g in gizmos: if g.rect.has_point(Global.canvas.current_pixel): @@ -116,14 +115,17 @@ func _input(event : InputEvent) -> void: transform_content_confirm() if !is_moving_content: if Input.is_action_pressed("alt"): - undo_data = _get_undo_data(false) + undo_data = get_undo_data(false) temp_rect = big_bounding_rectangle temp_bitmap = Global.current_project.selection_bitmap else: transform_content_start() Global.current_project.selection_offset = Vector2.ZERO if gizmo.type == Gizmo.Type.ROTATE: - var img_size := max(original_preview_image.get_width(), original_preview_image.get_height()) + var img_size := max( + original_preview_image.get_width(), + original_preview_image.get_height() + ) original_preview_image.crop(img_size, img_size) else: var prev_temp_rect := temp_rect @@ -142,7 +144,10 @@ func _input(event : InputEvent) -> void: temp_rect.end.y = pos rect_aspect_ratio = abs(temp_rect.size.y / temp_rect.size.x) temp_rect_size = temp_rect.size - temp_rect_pivot = temp_rect.position + ((temp_rect.end - temp_rect.position) / 2).floor() + temp_rect_pivot = ( + temp_rect.position + + ((temp_rect.end - temp_rect.position) / 2).floor() + ) elif dragged_gizmo: Global.has_focus = true @@ -157,7 +162,7 @@ func _input(event : InputEvent) -> void: gizmo_rotate() -func move_with_arrow_keys(event : InputEvent) -> void: +func move_with_arrow_keys(event: InputEvent) -> void: var selection_tool_selected := false for slot in Tools._slots.values(): if slot.tool_node is SelectionTool: @@ -184,11 +189,14 @@ func move_with_arrow_keys(event : InputEvent) -> void: var step := Vector2.ONE if Input.is_key_pressed(KEY_CONTROL): step = Vector2(Global.grid_width, Global.grid_height) - move_content(Vector2(int(event.is_action("ui_right")) - int(event.is_action("ui_left")), int(event.is_action("ui_down")) - int(event.is_action("ui_up"))).rotated(stepify(Global.camera.rotation, PI / 2)) * step) + var input := Vector2() + input.x = int(event.is_action("ui_right")) - int(event.is_action("ui_left")) + input.y = int(event.is_action("ui_down")) - int(event.is_action("ui_up")) + move_content(input.rotated(stepify(Global.camera.rotation, PI / 2)) * step) # Check if an event is a ui_up/down/left/right event-press -func is_action_direction_pressed(event : InputEvent) -> bool: +func is_action_direction_pressed(event: InputEvent) -> bool: for action in KEY_MOVE_ACTION_NAMES: if event.is_action_pressed(action): return true @@ -212,27 +220,27 @@ func is_action_direction_released(event: InputEvent) -> bool: func _draw() -> void: - var _position := position - var _scale := scale + var position_tmp := position + var scale_tmp := scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 - draw_set_transform(_position, rotation, _scale) + position_tmp.x = position_tmp.x + Global.current_project.size.x + scale_tmp.x = -1 + draw_set_transform(position_tmp, rotation, scale_tmp) if big_bounding_rectangle.size != Vector2.ZERO: - for gizmo in gizmos: # Draw gizmos + for gizmo in gizmos: # Draw gizmos draw_rect(gizmo.rect, Global.selection_border_color_2) - var filled_rect : Rect2 = gizmo.rect - var filled_size : Vector2 = gizmo.rect.size * Vector2(0.2, 0.2) + var filled_rect: Rect2 = gizmo.rect + var filled_size: Vector2 = gizmo.rect.size * Vector2(0.2, 0.2) filled_rect.position += filled_size filled_rect.size -= filled_size * 2 - draw_rect(filled_rect, Global.selection_border_color_1) # Filled white square + draw_rect(filled_rect, Global.selection_border_color_1) # Filled white square if is_moving_content and !preview_image.is_empty(): draw_texture(preview_image_texture, big_bounding_rectangle.position, Color(1, 1, 1, 0.5)) draw_set_transform(position, rotation, scale) -func _big_bounding_rectangle_changed(value : Rect2) -> void: +func _big_bounding_rectangle_changed(value: Rect2) -> void: big_bounding_rectangle = value for slot in Tools._slots.values(): if slot.tool_node is SelectionTool: @@ -241,26 +249,35 @@ func _big_bounding_rectangle_changed(value : Rect2) -> void: func update_gizmos() -> void: - var rect_pos : Vector2 = big_bounding_rectangle.position - var rect_end : Vector2 = big_bounding_rectangle.end - var size := Vector2.ONE * Global.camera.zoom * 10 + var rect_pos: Vector2 = big_bounding_rectangle.position + var rect_end: Vector2 = big_bounding_rectangle.end + var size: Vector2 = Vector2.ONE * Global.camera.zoom * 10 # Clockwise, starting from top-left corner gizmos[0].rect = Rect2(rect_pos - size, size) - gizmos[1].rect = Rect2(Vector2((rect_end.x + rect_pos.x - size.x) / 2, rect_pos.y - size.y), size) + gizmos[1].rect = Rect2( + Vector2((rect_end.x + rect_pos.x - size.x) / 2, rect_pos.y - size.y), size + ) gizmos[2].rect = Rect2(Vector2(rect_end.x, rect_pos.y - size.y), size) gizmos[3].rect = Rect2(Vector2(rect_end.x, (rect_end.y + rect_pos.y - size.y) / 2), size) gizmos[4].rect = Rect2(rect_end, size) gizmos[5].rect = Rect2(Vector2((rect_end.x + rect_pos.x - size.x) / 2, rect_end.y), size) gizmos[6].rect = Rect2(Vector2(rect_pos.x - size.x, rect_end.y), size) - gizmos[7].rect = Rect2(Vector2(rect_pos.x - size.x, (rect_end.y + rect_pos.y - size.y) / 2), size) + gizmos[7].rect = Rect2( + Vector2(rect_pos.x - size.x, (rect_end.y + rect_pos.y - size.y) / 2), size + ) # Rotation gizmo (temp) -# gizmos[8].rect = Rect2(Vector2((rect_end.x + rect_pos.x - size.x) / 2, rect_pos.y - size.y - (size.y * 2)), size) +# gizmos[8].rect = Rect2( +# Vector2((rect_end.x + rect_pos.x - size.x) / 2, rect_pos.y - size.y - (size.y * 2)), size +# ) update() -func update_on_zoom(zoom : float) -> void: - var size := max(Global.current_project.selection_bitmap.get_size().x, Global.current_project.selection_bitmap.get_size().y) +func update_on_zoom(zoom: float) -> void: + var size := max( + Global.current_project.selection_bitmap.get_size().x, + Global.current_project.selection_bitmap.get_size().y + ) marching_ants_outline.material.set_shader_param("width", zoom) marching_ants_outline.material.set_shader_param("frequency", (1.0 / zoom) * 10 * size / 64) for gizmo in gizmos: @@ -274,39 +291,41 @@ func gizmo_resize() -> void: if Input.is_action_pressed("ctrl"): # Code inspired from https://github.com/GDQuest/godot-open-rpg - if dir.x != 0 and dir.y != 0: # Border gizmos + if dir.x != 0 and dir.y != 0: # Border gizmos temp_rect.size = ((Global.canvas.current_pixel - temp_rect_pivot) * 2.0 * dir) - elif dir.y == 0: # Center left and right gizmos + elif dir.y == 0: # Center left and right gizmos temp_rect.size.x = (Global.canvas.current_pixel.x - temp_rect_pivot.x) * 2.0 * dir.x - elif dir.x == 0: # Center top and bottom gizmos + elif dir.x == 0: # Center top and bottom gizmos temp_rect.size.y = (Global.canvas.current_pixel.y - temp_rect_pivot.y) * 2.0 * dir.y temp_rect = Rect2(-1.0 * temp_rect.size / 2 + temp_rect_pivot, temp_rect.size) else: resize_rect(Global.canvas.current_pixel, dir) - if Input.is_action_pressed("shift"): # Maintain aspect ratio + if Input.is_action_pressed("shift"): # Maintain aspect ratio var end_y = temp_rect.end.y - if dir == Vector2(1, -1) or dir.x == 0: # Top right corner, center top and center bottom + if dir == Vector2(1, -1) or dir.x == 0: # Top right corner, center top and center bottom var size := temp_rect.size.y - if sign(size) != sign(temp_rect.size.x): # Needed in order for resizing to work properly in negative sizes + # Needed in order for resizing to work properly in negative sizes + if sign(size) != sign(temp_rect.size.x): if temp_rect.size.x > 0: size = abs(size) else: size = -abs(size) temp_rect.size.x = size / rect_aspect_ratio - else: # The rest of the corners + else: # The rest of the corners var size := temp_rect.size.x - if sign(size) != sign(temp_rect.size.y): # Needed in order for resizing to work properly in negative sizes + # Needed in order for resizing to work properly in negative sizes + if sign(size) != sign(temp_rect.size.y): if temp_rect.size.y > 0: size = abs(size) else: size = -abs(size) temp_rect.size.y = size * rect_aspect_ratio - if dir == Vector2(-1, -1): # Top left corner - # Inspired by the solution answered in https://stackoverflow.com/questions/50230967/drag-resizing-rectangle-with-fixed-aspect-ratio-northwest-corner + # Inspired by the solution answered in https://stackoverflow.com/a/50271547 + if dir == Vector2(-1, -1): # Top left corner temp_rect.position.y = end_y - temp_rect.size.y big_bounding_rectangle = temp_rect.abs() @@ -317,7 +336,7 @@ func gizmo_resize() -> void: if big_bounding_rectangle.size.y == 0: big_bounding_rectangle.size.y = 1 - self.big_bounding_rectangle = big_bounding_rectangle # Call the setter method + self.big_bounding_rectangle = big_bounding_rectangle # Call the setter method var size = big_bounding_rectangle.size.abs() if is_moving_content: @@ -328,12 +347,14 @@ func gizmo_resize() -> void: if temp_rect.size.y < 0: preview_image.flip_y() preview_image_texture.create_from_image(preview_image, 0) - Global.current_project.selection_bitmap = Global.current_project.resize_bitmap_values(temp_bitmap, size, temp_rect.size.x < 0, temp_rect.size.y < 0) + Global.current_project.selection_bitmap = Global.current_project.resize_bitmap_values( + temp_bitmap, size, temp_rect.size.x < 0, temp_rect.size.y < 0 + ) Global.current_project.selection_bitmap_changed() update() -func resize_rect(pos : Vector2, dir : Vector2) -> void: +func resize_rect(pos: Vector2, dir: Vector2) -> void: if dir.x > 0: temp_rect.size.x = pos.x - temp_rect.position.x elif dir.x < 0: @@ -353,8 +374,8 @@ func resize_rect(pos : Vector2, dir : Vector2) -> void: temp_rect.size.y = temp_rect_size.y -func gizmo_rotate() -> void: # Does not work properly yet - var angle := Global.canvas.current_pixel.angle_to_point(mouse_pos_on_gizmo_drag) +func gizmo_rotate() -> void: # Does not work properly yet + var angle: float = Global.canvas.current_pixel.angle_to_point(mouse_pos_on_gizmo_drag) angle = deg2rad(floor(rad2deg(angle))) if angle == prev_angle: return @@ -362,19 +383,24 @@ func gizmo_rotate() -> void: # Does not work properly yet # var img_size := max(original_preview_image.get_width(), original_preview_image.get_height()) # warning-ignore:integer_division # warning-ignore:integer_division -# var pivot = Vector2(original_preview_image.get_width() / 2, original_preview_image.get_height() / 2) +# var pivot = Vector2(original_preview_image.get_width()/2, original_preview_image.get_height()/2) var pivot = Vector2(big_bounding_rectangle.size.x / 2, big_bounding_rectangle.size.y / 2) preview_image.copy_from(original_preview_image) if original_big_bounding_rectangle.position != big_bounding_rectangle.position: preview_image.fill(Color(0, 0, 0, 0)) var pos_diff := (original_big_bounding_rectangle.position - big_bounding_rectangle.position).abs() # pos_diff.y = 0 - preview_image.blit_rect(original_preview_image, Rect2(Vector2.ZERO, preview_image.get_size()), pos_diff) + preview_image.blit_rect( + original_preview_image, Rect2(Vector2.ZERO, preview_image.get_size()), pos_diff + ) DrawingAlgos.nn_rotate(preview_image, angle, pivot) preview_image_texture.create_from_image(preview_image, 0) var bitmap_image = Global.current_project.bitmap_to_image(original_bitmap) - var bitmap_pivot = original_big_bounding_rectangle.position + ((original_big_bounding_rectangle.end - original_big_bounding_rectangle.position) / 2) + var bitmap_pivot = ( + original_big_bounding_rectangle.position + + ((original_big_bounding_rectangle.end - original_big_bounding_rectangle.position) / 2) + ) DrawingAlgos.nn_rotate(bitmap_image, angle, bitmap_pivot) Global.current_project.selection_bitmap.create_from_image_alpha(bitmap_image) Global.current_project.selection_bitmap_changed() @@ -382,10 +408,12 @@ func gizmo_rotate() -> void: # Does not work properly yet update() -func select_rect(rect : Rect2, operation : int = SelectionOperation.ADD) -> void: - var project : Project = Global.current_project - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() - var offset_position := Vector2.ZERO # Used only if the selection is outside of the canvas boundaries, on the left and/or above (negative coords) +func select_rect(rect: Rect2, operation: int = SelectionOperation.ADD) -> void: + var project: Project = Global.current_project + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() + # Used only if the selection is outside of the canvas boundaries, + # on the left and/or above (negative coords) + var offset_position := Vector2.ZERO if big_bounding_rectangle.position.x < 0: rect.position.x -= big_bounding_rectangle.position.x offset_position.x = big_bounding_rectangle.position.x @@ -417,14 +445,14 @@ func select_rect(rect : Rect2, operation : int = SelectionOperation.ADD) -> void project.move_bitmap_values(selection_bitmap_copy) project.selection_bitmap = selection_bitmap_copy - self.big_bounding_rectangle = big_bounding_rectangle # call getter method + self.big_bounding_rectangle = big_bounding_rectangle # call getter method func move_borders_start() -> void: - undo_data = _get_undo_data(false) + undo_data = get_undo_data(false) -func move_borders(move : Vector2) -> void: +func move_borders(move: Vector2) -> void: if move == Vector2.ZERO: return marching_ants_outline.offset += move @@ -433,7 +461,7 @@ func move_borders(move : Vector2) -> void: func move_borders_end() -> void: - var selected_bitmap_copy := Global.current_project.selection_bitmap.duplicate() + var selected_bitmap_copy: BitMap = Global.current_project.selection_bitmap.duplicate() Global.current_project.move_bitmap_values(selected_bitmap_copy) Global.current_project.selection_bitmap = selected_bitmap_copy @@ -446,12 +474,12 @@ func move_borders_end() -> void: func transform_content_start() -> void: if !is_moving_content: - undo_data = _get_undo_data(true) + undo_data = get_undo_data(true) temp_rect = big_bounding_rectangle temp_bitmap = Global.current_project.selection_bitmap get_preview_image() if original_preview_image.is_empty(): - undo_data = _get_undo_data(false) + undo_data = get_undo_data(false) return is_moving_content = true original_bitmap = Global.current_project.selection_bitmap.duplicate() @@ -460,30 +488,42 @@ func transform_content_start() -> void: update() -func move_content(move : Vector2) -> void: +func move_content(move: Vector2) -> void: move_borders(move) func transform_content_confirm() -> void: if !is_moving_content: return - var project : Project = Global.current_project + var project: Project = Global.current_project for cel_index in project.selected_cels: - var frame : int = cel_index[0] - var layer : int = cel_index[1] + var frame: int = cel_index[0] + var layer: int = cel_index[1] if frame < project.frames.size() and layer < project.layers.size(): if Global.current_project.layers[layer].can_layer_get_drawn(): - var cel_image : Image = project.frames[frame].cels[layer].image - var src : Image = preview_image - if not is_pasting and not (frame == project.current_frame and layer == project.current_layer): + var cel_image: Image = project.frames[frame].cels[layer].image + var src: Image = preview_image + if ( + not is_pasting + and not (frame == project.current_frame and layer == project.current_layer) + ): src = get_selected_image(cel_image, clear_in_selected_cels) - src.resize(big_bounding_rectangle.size.x, big_bounding_rectangle.size.y, Image.INTERPOLATE_NEAREST) + src.resize( + big_bounding_rectangle.size.x, + big_bounding_rectangle.size.y, + Image.INTERPOLATE_NEAREST + ) if temp_rect.size.x < 0: src.flip_x() if temp_rect.size.y < 0: src.flip_y() - cel_image.blit_rect_mask(src, src, Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), big_bounding_rectangle.position) + cel_image.blit_rect_mask( + src, + src, + Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), + big_bounding_rectangle.position + ) var selected_bitmap_copy = project.selection_bitmap.duplicate() project.move_bitmap_values(selected_bitmap_copy) project.selection_bitmap = selected_bitmap_copy @@ -501,7 +541,7 @@ func transform_content_confirm() -> void: func transform_content_cancel() -> void: if preview_image.is_empty(): return - var project : Project = Global.current_project + var project: Project = Global.current_project project.selection_offset = original_offset is_moving_content = false @@ -510,8 +550,13 @@ func transform_content_cancel() -> void: project.selection_bitmap_changed() preview_image = original_preview_image if !is_pasting: - var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image - cel_image.blit_rect_mask(preview_image, preview_image, Rect2(Vector2.ZERO, Global.current_project.selection_bitmap.get_size()), big_bounding_rectangle.position) + var cel_image: Image = project.frames[project.current_frame].cels[project.current_layer].image + cel_image.blit_rect_mask( + preview_image, + preview_image, + Rect2(Vector2.ZERO, Global.current_project.selection_bitmap.get_size()), + big_bounding_rectangle.position + ) Global.canvas.update_texture(project.current_layer) original_preview_image = Image.new() preview_image = Image.new() @@ -520,34 +565,41 @@ func transform_content_cancel() -> void: update() -func commit_undo(action : String, _undo_data : Dictionary) -> void: - if !_undo_data: +func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: + if !undo_data_tmp: print("No undo data found!") return - var redo_data = _get_undo_data(_undo_data["undo_image"]) - var project := Global.current_project + var redo_data = get_undo_data(undo_data_tmp["undo_image"]) + var project: Project = Global.current_project project.undos += 1 project.undo_redo.create_action(action) project.undo_redo.add_do_property(project, "selection_bitmap", redo_data["selection_bitmap"]) - project.undo_redo.add_do_property(self, "big_bounding_rectangle", redo_data["big_bounding_rectangle"]) + project.undo_redo.add_do_property( + self, "big_bounding_rectangle", redo_data["big_bounding_rectangle"] + ) project.undo_redo.add_do_property(project, "selection_offset", redo_data["outline_offset"]) - project.undo_redo.add_undo_property(project, "selection_bitmap", _undo_data["selection_bitmap"]) - project.undo_redo.add_undo_property(self, "big_bounding_rectangle", _undo_data["big_bounding_rectangle"]) - project.undo_redo.add_undo_property(project, "selection_offset", _undo_data["outline_offset"]) + project.undo_redo.add_undo_property( + project, "selection_bitmap", undo_data_tmp["selection_bitmap"] + ) + project.undo_redo.add_undo_property( + self, "big_bounding_rectangle", undo_data_tmp["big_bounding_rectangle"] + ) + project.undo_redo.add_undo_property( + project, "selection_offset", undo_data_tmp["outline_offset"] + ) - - if _undo_data["undo_image"]: + if undo_data_tmp["undo_image"]: for image in redo_data: if not image is Image: continue project.undo_redo.add_do_property(image, "data", redo_data[image]) image.unlock() - for image in _undo_data: + for image in undo_data_tmp: if not image is Image: continue - project.undo_redo.add_undo_property(image, "data", _undo_data[image]) + project.undo_redo.add_undo_property(image, "data", undo_data_tmp[image]) project.undo_redo.add_do_method(Global, "redo") project.undo_redo.add_do_method(project, "selection_bitmap_changed") project.undo_redo.add_undo_method(Global, "undo") @@ -557,9 +609,9 @@ func commit_undo(action : String, _undo_data : Dictionary) -> void: undo_data.clear() -func _get_undo_data(undo_image : bool) -> Dictionary: +func get_undo_data(undo_image: bool) -> Dictionary: var data := {} - var project := Global.current_project + var project: Project = Global.current_project data["selection_bitmap"] = project.selection_bitmap data["big_bounding_rectangle"] = big_bounding_rectangle data["outline_offset"] = Global.current_project.selection_offset @@ -575,11 +627,11 @@ func _get_undo_data(undo_image : bool) -> Dictionary: return data -func _get_selected_draw_images() -> Array: # Array of Images +func _get_selected_draw_images() -> Array: # Array of Images var images := [] - var project : Project = Global.current_project + var project: Project = Global.current_project for cel_index in project.selected_cels: - var cel : Cel = project.frames[cel_index[0]].cels[cel_index[1]] + var cel: Cel = project.frames[cel_index[0]].cels[cel_index[1]] images.append(cel.image) return images @@ -590,10 +642,10 @@ func cut() -> void: func copy() -> void: - var project := Global.current_project + var project: Project = Global.current_project if !project.has_selection: return - var image : Image = project.frames[project.current_frame].cels[project.current_layer].image + var image: Image = project.frames[project.current_frame].cels[project.current_layer].image var to_copy := Image.new() if is_moving_content: to_copy.copy_from(preview_image) @@ -625,15 +677,18 @@ func paste() -> void: if clipboard.image.is_empty(): return clear_selection() - undo_data = _get_undo_data(true) - var project := Global.current_project + undo_data = get_undo_data(true) + var project: Project = Global.current_project original_bitmap = project.selection_bitmap.duplicate() original_big_bounding_rectangle = big_bounding_rectangle original_offset = project.selection_offset - var clip_bitmap : BitMap = clipboard.selection_bitmap.duplicate() - var max_size := Vector2(max(clip_bitmap.get_size().x, project.selection_bitmap.get_size().x), max(clip_bitmap.get_size().y, project.selection_bitmap.get_size().y)) + var clip_bitmap: BitMap = clipboard.selection_bitmap.duplicate() + var max_size := Vector2( + max(clip_bitmap.get_size().x, project.selection_bitmap.get_size().x), + max(clip_bitmap.get_size().y, project.selection_bitmap.get_size().y) + ) project.selection_bitmap = Global.current_project.resize_bitmap(clip_bitmap, max_size) self.big_bounding_rectangle = clipboard.big_bounding_rectangle @@ -651,7 +706,7 @@ func paste() -> void: func delete() -> void: - var project := Global.current_project + var project: Project = Global.current_project if !project.has_selection: return if is_moving_content: @@ -664,22 +719,22 @@ func delete() -> void: commit_undo("Draw", undo_data) return - var _undo_data := _get_undo_data(true) - var image : Image = project.frames[project.current_frame].cels[project.current_layer].image + var undo_data_tmp := get_undo_data(true) + var image: Image = project.frames[project.current_frame].cels[project.current_layer].image for x in big_bounding_rectangle.size.x: for y in big_bounding_rectangle.size.y: var pos := Vector2(x, y) + big_bounding_rectangle.position if project.can_pixel_get_drawn(pos): image.set_pixelv(pos, Color(0)) - commit_undo("Draw", _undo_data) + commit_undo("Draw", undo_data_tmp) func new_brush() -> void: - var project := Global.current_project + var project: Project = Global.current_project if !project.has_selection: return - var image : Image = project.frames[project.current_frame].cels[project.current_layer].image + var image: Image = project.frames[project.current_frame].cels[project.current_layer].image var brush := Image.new() if is_moving_content: brush.copy_from(preview_image) @@ -703,41 +758,41 @@ func new_brush() -> void: brush.unlock() if !brush.is_invisible(): - var brush_used : Image = brush.get_rect(brush.get_used_rect()) + var brush_used: Image = brush.get_rect(brush.get_used_rect()) project.brushes.append(brush_used) Brushes.add_project_brush(brush_used) func select_all() -> void: - var project := Global.current_project - var _undo_data = _get_undo_data(false) + var project: Project = Global.current_project + var undo_data_tmp = get_undo_data(false) clear_selection() var full_rect = Rect2(Vector2.ZERO, project.size) select_rect(full_rect) - commit_undo("Rectangle Select", _undo_data) + commit_undo("Rectangle Select", undo_data_tmp) func invert() -> void: transform_content_confirm() - var project := Global.current_project - var _undo_data = _get_undo_data(false) - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var project: Project = Global.current_project + var undo_data_tmp = get_undo_data(false) + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() selection_bitmap_copy = project.resize_bitmap(selection_bitmap_copy, project.size) project.invert_bitmap(selection_bitmap_copy) project.selection_bitmap = selection_bitmap_copy project.selection_bitmap_changed() self.big_bounding_rectangle = project.get_selection_rectangle(selection_bitmap_copy) project.selection_offset = Vector2.ZERO - commit_undo("Rectangle Select", _undo_data) + commit_undo("Rectangle Select", undo_data_tmp) func clear_selection(use_undo := false) -> void: - var project := Global.current_project + var project: Project = Global.current_project if !project.has_selection: return transform_content_confirm() - var _undo_data = _get_undo_data(false) - var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var undo_data_tmp = get_undo_data(false) + var selection_bitmap_copy: BitMap = project.selection_bitmap.duplicate() selection_bitmap_copy = project.resize_bitmap(selection_bitmap_copy, project.size) var full_rect = Rect2(Vector2.ZERO, selection_bitmap_copy.get_size()) selection_bitmap_copy.set_bit_rect(full_rect, false) @@ -747,12 +802,12 @@ func clear_selection(use_undo := false) -> void: project.selection_offset = Vector2.ZERO update() if use_undo: - commit_undo("Clear Selection", _undo_data) + commit_undo("Clear Selection", undo_data_tmp) func get_preview_image() -> void: - var project : Project = Global.current_project - var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image + var project: Project = Global.current_project + var cel_image: Image = project.frames[project.current_frame].cels[project.current_layer].image if original_preview_image.is_empty(): # original_preview_image.copy_from(cel_image) original_preview_image = cel_image.get_rect(big_bounding_rectangle) @@ -772,13 +827,23 @@ func get_preview_image() -> void: preview_image_texture.create_from_image(preview_image, 0) var clear_image := Image.new() - clear_image.create(original_preview_image.get_width(), original_preview_image.get_height(), false, Image.FORMAT_RGBA8) - cel_image.blit_rect_mask(clear_image, original_preview_image, Rect2(Vector2.ZERO, Global.current_project.selection_bitmap.get_size()), big_bounding_rectangle.position) + clear_image.create( + original_preview_image.get_width(), + original_preview_image.get_height(), + false, + Image.FORMAT_RGBA8 + ) + cel_image.blit_rect_mask( + clear_image, + original_preview_image, + Rect2(Vector2.ZERO, Global.current_project.selection_bitmap.get_size()), + big_bounding_rectangle.position + ) Global.canvas.update_texture(project.current_layer) -func get_selected_image(cel_image : Image, clear := true) -> Image: - var project : Project = Global.current_project +func get_selected_image(cel_image: Image, clear := true) -> Image: + var project: Project = Global.current_project var image := Image.new() image = cel_image.get_rect(original_big_bounding_rectangle) image.lock() @@ -786,7 +851,11 @@ func get_selected_image(cel_image : Image, clear := true) -> Image: for x in range(0, original_big_bounding_rectangle.size.x): for y in range(0, original_big_bounding_rectangle.size.y): var pos := Vector2(x, y) - if !project.can_pixel_get_drawn(pos + original_big_bounding_rectangle.position, original_bitmap, original_big_bounding_rectangle.position): + if !project.can_pixel_get_drawn( + pos + original_big_bounding_rectangle.position, + original_bitmap, + original_big_bounding_rectangle.position + ): image.set_pixelv(pos, Color(0, 0, 0, 0)) image.unlock() @@ -796,7 +865,12 @@ func get_selected_image(cel_image : Image, clear := true) -> Image: if clear: var clear_image := Image.new() clear_image.create(image.get_width(), image.get_height(), false, Image.FORMAT_RGBA8) - cel_image.blit_rect_mask(clear_image, image, Rect2(Vector2.ZERO, Global.current_project.selection_bitmap.get_size()), original_big_bounding_rectangle.position) + cel_image.blit_rect_mask( + clear_image, + image, + Rect2(Vector2.ZERO, Global.current_project.selection_bitmap.get_size()), + original_big_bounding_rectangle.position + ) Global.canvas.update_texture(project.current_layer) return image diff --git a/src/UI/Canvas/TileMode.gd b/src/UI/Canvas/TileMode.gd index 61bf9ccf0..d17bb6312 100644 --- a/src/UI/Canvas/TileMode.gd +++ b/src/UI/Canvas/TileMode.gd @@ -2,18 +2,20 @@ extends Node2D func _draw() -> void: - var size : Vector2 = Global.current_project.size - var positions : Array = get_tile_positions(size) + var size: Vector2 = Global.current_project.size + var positions: Array = get_tile_positions(size) var tilemode_opacity := Global.tilemode_opacity - var _position := position - var _scale := scale + var position_tmp := position + var scale_tmp := scale if Global.mirror_view: - _position.x = _position.x + Global.current_project.size.x - _scale.x = -1 - draw_set_transform(_position, rotation, _scale) + position_tmp.x = position_tmp.x + Global.current_project.size.x + scale_tmp.x = -1 + draw_set_transform(position_tmp, rotation, scale_tmp) - var modulate_color := Color(tilemode_opacity, tilemode_opacity, tilemode_opacity, tilemode_opacity) # premultiply alpha blending is applied + var modulate_color := Color( + tilemode_opacity, tilemode_opacity, tilemode_opacity, tilemode_opacity + ) # premultiply alpha blending is applied var current_frame_texture: Texture = Global.canvas.currently_visible_frame.get_texture() for pos in positions: draw_texture(current_frame_texture, pos, modulate_color) @@ -25,24 +27,24 @@ func get_tile_positions(size): match Global.current_project.tile_mode: Global.TileMode.BOTH: return [ - Vector2(0, size.y), # Down - Vector2(-size.x, size.y), # Down left - Vector2(-size.x, 0), # Left - -size, # Up left - Vector2(0, -size.y), # Up - Vector2(size.x, -size.y), # Up right - Vector2(size.x, 0), # Right - size # Down right + Vector2(0, size.y), # Down + Vector2(-size.x, size.y), # Down left + Vector2(-size.x, 0), # Left + -size, # Up left + Vector2(0, -size.y), # Up + Vector2(size.x, -size.y), # Up right + Vector2(size.x, 0), # Right + size # Down right ] Global.TileMode.X_AXIS: return [ - Vector2(size.x, 0), # Right - Vector2(-size.x, 0), # Left + Vector2(size.x, 0), # Right + Vector2(-size.x, 0), # Left ] Global.TileMode.Y_AXIS: return [ - Vector2(0, size.y), # Down - Vector2(0, -size.y), # Up + Vector2(0, size.y), # Down + Vector2(0, -size.y), # Up ] _: return [] diff --git a/src/UI/CanvasPreviewContainer.gd b/src/UI/CanvasPreviewContainer.gd index 947443c5b..90211ab1e 100644 --- a/src/UI/CanvasPreviewContainer.gd +++ b/src/UI/CanvasPreviewContainer.gd @@ -1,18 +1,17 @@ extends PanelContainer - onready var canvas_preview = $HBoxContainer/PreviewViewportContainer/Viewport/CanvasPreview -onready var camera : Camera2D = $HBoxContainer/PreviewViewportContainer/Viewport/CameraPreview -onready var play_button : Button = $HBoxContainer/VBoxContainer/PlayButton +onready var camera: Camera2D = $HBoxContainer/PreviewViewportContainer/Viewport/CameraPreview +onready var play_button: Button = $HBoxContainer/VBoxContainer/PlayButton -func _on_PreviewZoomSlider_value_changed(value : float) -> void: +func _on_PreviewZoomSlider_value_changed(value: float) -> void: camera.zoom = -Vector2(value, value) camera.save_values_to_project() camera.update_transparent_checker_offset() -func _on_PlayButton_toggled(button_pressed : bool) -> void: +func _on_PlayButton_toggled(button_pressed: bool) -> void: if button_pressed: if Global.current_project.frames.size() <= 1: play_button.pressed = false diff --git a/src/UI/ColorAndToolOptions.gd b/src/UI/ColorAndToolOptions.gd index 594671dbb..572fb0eb7 100644 --- a/src/UI/ColorAndToolOptions.gd +++ b/src/UI/ColorAndToolOptions.gd @@ -1,6 +1,5 @@ extends VBoxContainer - onready var left_picker := $ColorPickersHorizontal/LeftColorPickerButton onready var right_picker := $ColorPickersHorizontal/RightColorPickerButton @@ -15,7 +14,7 @@ func _on_ColorSwitch_pressed() -> void: Tools.swap_color() -func _on_ColorPickerButton_color_changed(color : Color, right : bool): +func _on_ColorPickerButton_color_changed(color: Color, right: bool): var button := BUTTON_RIGHT if right else BUTTON_LEFT Tools.assign_color(color, button) @@ -34,7 +33,7 @@ func _on_ColorDefaults_pressed() -> void: Tools.default_color() -func update_color(color : Color, button : int) -> void: +func update_color(color: Color, button: int) -> void: if button == BUTTON_LEFT: left_picker.color = color else: diff --git a/src/UI/ColorAndToolOptions.tscn b/src/UI/ColorAndToolOptions.tscn index c2e9efe0e..ebf9fa8f5 100644 --- a/src/UI/ColorAndToolOptions.tscn +++ b/src/UI/ColorAndToolOptions.tscn @@ -48,6 +48,8 @@ margin_bottom = 13.0 [node name="ColorSwitch" type="TextureButton" parent="ColorPickersHorizontal/ColorButtonsVertical/ColorSwitchCenter" groups=["UIButtons"]] margin_right = 25.0 margin_bottom = 7.0 +hint_tooltip = "Switch left and right colors +(%s)" mouse_default_cursor_shape = 2 shortcut_in_tooltip = false shortcut = SubResource( 1 ) diff --git a/src/UI/Dialogs/AboutDialog.gd b/src/UI/Dialogs/AboutDialog.gd index 19f541ed1..b5656cd95 100644 --- a/src/UI/Dialogs/AboutDialog.gd +++ b/src/UI/Dialogs/AboutDialog.gd @@ -1,61 +1,24 @@ extends WindowDialog - -const LICENSES := [ -"""MIT License - -Copyright (c) 2019-present Orama Interactive and contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""", - -"""This software uses Godot Engine, available under the following license: - -Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. -Copyright (c) 2014-2021 Godot Engine contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""", - -"Portions of this software are copyright © 2021 The FreeType Project (www.freetype.org). All rights reserved.", - -"""MIT License - -Copyright (c) 2020 Igor Santarek - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -] +export(Array, String, MULTILINE) var licenses: Array onready var credits = $AboutUI/Credits -onready var groups : Tree = $AboutUI/Credits/Groups +onready var groups: Tree = $AboutUI/Credits/Groups onready var developer_container = $AboutUI/Credits/Developers onready var contributors_container = $AboutUI/Credits/Contributors onready var donors_container = $AboutUI/Credits/Donors onready var translators_container = $AboutUI/Credits/Translators onready var licenses_container = $AboutUI/Credits/Licenses -onready var developers : Tree = $AboutUI/Credits/Developers/DeveloperTree -onready var contributors : Tree = $AboutUI/Credits/Contributors/ContributorTree -onready var donors : Tree = $AboutUI/Credits/Donors/DonorTree -onready var translators : Tree = $AboutUI/Credits/Translators/TranslatorTree +onready var developers: Tree = $AboutUI/Credits/Developers/DeveloperTree +onready var contributors: Tree = $AboutUI/Credits/Contributors/ContributorTree +onready var donors: Tree = $AboutUI/Credits/Donors/DonorTree +onready var translators: Tree = $AboutUI/Credits/Translators/TranslatorTree -onready var license_text : TextEdit = $AboutUI/Credits/Licenses/LicenseText +onready var license_text: TextEdit = $AboutUI/Credits/Licenses/LicenseText -onready var slogan_label : Label = $AboutUI/IconsButtons/SloganAndLinks/VBoxContainer/PixeloramaSlogan -onready var copyright_label : Label = $AboutUI/Copyright +onready var slogan: Label = $AboutUI/IconsButtons/SloganAndLinks/VBoxContainer/PixeloramaSlogan +onready var copyright_label: Label = $AboutUI/Copyright onready var latin_font_italic = preload("res://assets/fonts/Roboto-Italic.tres") onready var cjk_font = preload("res://assets/fonts/CJK/DroidSansFallback-Regular.tres") @@ -69,16 +32,17 @@ func _ready() -> void: var license_buttons_container = $AboutUI/Credits/Licenses/LicenseButtonsContainer for button in license_buttons_container.get_children(): button.connect("pressed", self, "_on_LicenseButton_pressed", [button.get_index()]) + license_text.text = licenses[0] func _on_AboutDialog_about_to_show() -> void: window_title = tr("About Pixelorama") + " " + Global.current_version if Global.is_cjk(TranslationServer.get_locale()): - slogan_label.add_font_override("font", cjk_font) + slogan.add_font_override("font", cjk_font) copyright_label.add_font_override("font", cjk_font_small) else: - slogan_label.add_font_override("font", latin_font_italic) + slogan.add_font_override("font", latin_font_italic) copyright_label.add_font_override("font", latin_font_small) var groups_root := groups.create_item() @@ -88,17 +52,17 @@ func _on_AboutDialog_about_to_show() -> void: var translators_button := groups.create_item(groups_root) var licenses_button := groups.create_item(groups_root) - developers_button.set_text(0, " " + tr("Developers")) + developers_button.set_text(0, " " + tr("Developers")) # We use metadata to avoid being affected by translations developers_button.set_metadata(0, "Developers") developers_button.select(0) - contributors_button.set_text(0, " " + tr("Contributors")) + contributors_button.set_text(0, " " + tr("Contributors")) contributors_button.set_metadata(0, "Contributors") - donors_button.set_text(0, " " + tr("Donors")) + donors_button.set_text(0, " " + tr("Donors")) donors_button.set_metadata(0, "Donors") - translators_button.set_text(0, " " + tr("Translators")) + translators_button.set_text(0, " " + tr("Translators")) translators_button.set_metadata(0, "Translators") - licenses_button.set_text(0, " " + tr("Licenses")) + licenses_button.set_text(0, " " + tr("Licenses")) licenses_button.set_metadata(0, "Licenses") create_developers() @@ -116,7 +80,7 @@ func _on_Groups_item_selected() -> void: if child != groups: child.visible = false - var selected : String = groups.get_selected().get_metadata(0) + var selected: String = groups.get_selected().get_metadata(0) if "Developers" in selected: developer_container.visible = true elif "Contributors" in selected: @@ -141,13 +105,15 @@ func _on_Donate_pressed() -> void: OS.shell_open("https://www.patreon.com/OramaInteractive") -func _on_LicenseButton_pressed(index : int) -> void: - license_text.text = LICENSES[index] +func _on_LicenseButton_pressed(index: int) -> void: + license_text.text = licenses[index] func create_developers() -> void: var dev_root := developers.create_item() - developers.create_item(dev_root).set_text(0, " Manolis Papadeas (Overloaded) - " + tr("Lead Programmer")) + developers.create_item(dev_root).set_text( + 0, " Manolis Papadeas (Overloaded) - " + tr("Lead Programmer") + ) developers.create_item(dev_root).set_text(0, " John Nikitakis (Erevos) - " + tr("UI Designer")) @@ -208,61 +174,135 @@ func create_contributors() -> void: func create_translators() -> void: var translators_root := translators.create_item() - translators.create_item(translators_root).set_text(0, " Manolis Papadeas (Overloaded) - " + tr("Greek")) - translators.create_item(translators_root).set_text(0, " Xenofon Konitsas (huskee) - " + tr("Greek")) - translators.create_item(translators_root).set_text(0, " Lena Louloudaki (Soliscital) - " + tr("Greek")) - translators.create_item(translators_root).set_text(0, " Hugo Locurcio (Calinou) - " + tr("French")) + translators.create_item(translators_root).set_text( + 0, " Manolis Papadeas (Overloaded) - " + tr("Greek") + ) + translators.create_item(translators_root).set_text( + 0, " Xenofon Konitsas (huskee) - " + tr("Greek") + ) + translators.create_item(translators_root).set_text( + 0, " Lena Louloudaki (Soliscital) - " + tr("Greek") + ) + translators.create_item(translators_root).set_text( + 0, " Hugo Locurcio (Calinou) - " + tr("French") + ) translators.create_item(translators_root).set_text(0, " blackjoker77777 - " + tr("French")) translators.create_item(translators_root).set_text(0, " Yoshiip (myoshipro) - " + tr("French")) translators.create_item(translators_root).set_text(0, " Iorvethe - " + tr("French")) - translators.create_item(translators_root).set_text(0, " Paul Coral (lepaincestbon) - " + tr("French")) + translators.create_item(translators_root).set_text( + 0, " Paul Coral (lepaincestbon) - " + tr("French") + ) translators.create_item(translators_root).set_text(0, " RED (REDOOO) - " + tr("French")) - translators.create_item(translators_root).set_text(0, " Aidan Olsen (PossiblyAShrub) - " + tr("French")) - translators.create_item(translators_root).set_text(0, " Jean-Loup Macarit (leyk973) - " + tr("French")) - translators.create_item(translators_root).set_text(0, " Lulullia (lulullia902) - " + tr("French")) + translators.create_item(translators_root).set_text( + 0, " Aidan Olsen (PossiblyAShrub) - " + tr("French") + ) + translators.create_item(translators_root).set_text( + 0, " Jean-Loup Macarit (leyk973) - " + tr("French") + ) + translators.create_item(translators_root).set_text( + 0, " Lulullia (lulullia902) - " + tr("French") + ) translators.create_item(translators_root).set_text(0, " Nicolas.C (nico57c) - " + tr("French")) translators.create_item(translators_root).set_text(0, " Schweini07 - " + tr("German")) - translators.create_item(translators_root).set_text(0, " Martin Zabinski (Martin1991zab) - " + tr("German")) - translators.create_item(translators_root).set_text(0, " Dawid Niedźwiedzki (tiritto) - " + tr("Polish")) - translators.create_item(translators_root).set_text(0, " Serhiy Dmytryshyn (dies) - " + tr("Polish")) - translators.create_item(translators_root).set_text(0, " Igor Santarek (jegor377) - " + tr("Polish")) + translators.create_item(translators_root).set_text( + 0, " Martin Zabinski (Martin1991zab) - " + tr("German") + ) + translators.create_item(translators_root).set_text( + 0, " Dawid Niedźwiedzki (tiritto) - " + tr("Polish") + ) + translators.create_item(translators_root).set_text( + 0, " Serhiy Dmytryshyn (dies) - " + tr("Polish") + ) + translators.create_item(translators_root).set_text( + 0, " Igor Santarek (jegor377) - " + tr("Polish") + ) translators.create_item(translators_root).set_text(0, " RainbowP - " + tr("Polish")) - translators.create_item(translators_root).set_text(0, " Michael Alexsander (YeldhamDev) - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " Cedulio Cezar (ceduliocezar) - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " Alexandre Oliveira (rockytvbr) - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " IagoAndrade - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " chacal_exodius - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " Lucas Santiago (lu.santi.oli) - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " TheNoobPro44 - " + tr("Brazilian Portuguese")) - translators.create_item(translators_root).set_text(0, " DippoZz - " + tr("Brazilian Portuguese")) + translators.create_item(translators_root).set_text( + 0, " Michael Alexsander (YeldhamDev) - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " Cedulio Cezar (ceduliocezar) - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " Alexandre Oliveira (rockytvbr) - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " IagoAndrade - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " chacal_exodius - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " Lucas Santiago (lu.santi.oli) - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " TheNoobPro44 - " + tr("Brazilian Portuguese") + ) + translators.create_item(translators_root).set_text( + 0, " DippoZz - " + tr("Brazilian Portuguese") + ) translators.create_item(translators_root).set_text(0, " Andreev Andrei - " + tr("Russian")) translators.create_item(translators_root).set_text(0, " ax trifonov (ax34) - " + tr("Russian")) - translators.create_item(translators_root).set_text(0, " Artem (blinovartem) - " + tr("Russian")) - translators.create_item(translators_root).set_text(0, " stomleny_cmok - " + tr("Russian") + " " + tr("and") + " " + tr("Ukrainian")) - translators.create_item(translators_root).set_text(0, " Bohdan Matviiv (BodaMat) - " + tr("Ukrainian")) - translators.create_item(translators_root).set_text(0, " JunYouIntrovert - " + tr("Chinese Traditional")) - translators.create_item(translators_root).set_text(0, " Kinwailo - " + tr("Chinese Traditional")) - translators.create_item(translators_root).set_text(0, " Chenxu Wang - " + tr("Chinese Simplified")) - translators.create_item(translators_root).set_text(0, " Catherine Yang (qzcyyw13) - " + tr("Chinese Simplified")) - translators.create_item(translators_root).set_text(0, " Marco Galli (Gaarco) - " + tr("Italian")) + translators.create_item(translators_root).set_text( + 0, " Artem (blinovartem) - " + tr("Russian") + ) + translators.create_item(translators_root).set_text( + 0, " stomleny_cmok - " + tr("Russian") + " " + tr("and") + " " + tr("Ukrainian") + ) + translators.create_item(translators_root).set_text( + 0, " Bohdan Matviiv (BodaMat) - " + tr("Ukrainian") + ) + translators.create_item(translators_root).set_text( + 0, " JunYouIntrovert - " + tr("Chinese Traditional") + ) + translators.create_item(translators_root).set_text( + 0, " Kinwailo - " + tr("Chinese Traditional") + ) + translators.create_item(translators_root).set_text( + 0, " Chenxu Wang - " + tr("Chinese Simplified") + ) + translators.create_item(translators_root).set_text( + 0, " Catherine Yang (qzcyyw13) - " + tr("Chinese Simplified") + ) + translators.create_item(translators_root).set_text( + 0, " Marco Galli (Gaarco) - " + tr("Italian") + ) translators.create_item(translators_root).set_text(0, " StarFang208 - " + tr("Italian")) - translators.create_item(translators_root).set_text(0, " Azagaya VJ (azagaya.games) - " + tr("Spanish")) - translators.create_item(translators_root).set_text(0, " Lilly And (KatieAnd) - " + tr("Spanish")) + translators.create_item(translators_root).set_text( + 0, " Azagaya VJ (azagaya.games) - " + tr("Spanish") + ) + translators.create_item(translators_root).set_text( + 0, " Lilly And (KatieAnd) - " + tr("Spanish") + ) translators.create_item(translators_root).set_text(0, " UncleFangs - " + tr("Spanish")) - translators.create_item(translators_root).set_text(0, " Jaime Arancibia Soto - " + tr("Spanish") + " " + tr("and") + " " + tr("Catalan")) + translators.create_item(translators_root).set_text( + 0, " Jaime Arancibia Soto - " + tr("Spanish") + " " + tr("and") + " " + tr("Catalan") + ) translators.create_item(translators_root).set_text(0, " foralistico - " + tr("Spanish")) - translators.create_item(translators_root).set_text(0, " Jose Callejas (satorikeiko) - " + tr("Spanish")) - translators.create_item(translators_root).set_text(0, " Agnis Aldiņš (NeZvers) - " + tr("Latvian")) - translators.create_item(translators_root).set_text(0, " Edgars Korns (Eddy11) - " + tr("Latvian")) + translators.create_item(translators_root).set_text( + 0, " Jose Callejas (satorikeiko) - " + tr("Spanish") + ) + translators.create_item(translators_root).set_text( + 0, " Agnis Aldiņš (NeZvers) - " + tr("Latvian") + ) + translators.create_item(translators_root).set_text( + 0, " Edgars Korns (Eddy11) - " + tr("Latvian") + ) translators.create_item(translators_root).set_text(0, " Teashrock - " + tr("Esperanto")) translators.create_item(translators_root).set_text(0, " Blend_Smile - " + tr("Indonesian")) - translators.create_item(translators_root).set_text(0, " Martin Novák (novhack) - " + tr("Czech")) + translators.create_item(translators_root).set_text( + 0, " Martin Novák (novhack) - " + tr("Czech") + ) translators.create_item(translators_root).set_text(0, " Lullius - " + tr("Norwegian Bokmål")) translators.create_item(translators_root).set_text(0, " Aninuscsalas - " + tr("Hungarian")) translators.create_item(translators_root).set_text(0, " jaehyeon1090 - " + tr("Korean")) translators.create_item(translators_root).set_text(0, " sfun_G - " + tr("Korean")) - translators.create_item(translators_root).set_text(0, " KripC2160 - " + tr("Korean") + " " + tr("and") + " " + tr("Japanese")) - translators.create_item(translators_root).set_text(0, " daisuke osada (barlog) - " + tr("Japanese")) + translators.create_item(translators_root).set_text( + 0, " KripC2160 - " + tr("Korean") + " " + tr("and") + " " + tr("Japanese") + ) + translators.create_item(translators_root).set_text( + 0, " daisuke osada (barlog) - " + tr("Japanese") + ) translators.create_item(translators_root).set_text(0, " Motomo.exe - " + tr("Japanese")) translators.create_item(translators_root).set_text(0, " hebekeg - " + tr("Japanese")) translators.create_item(translators_root).set_text(0, " Sorenwds - " + tr("Japanese")) @@ -271,5 +311,7 @@ func create_translators() -> void: translators.create_item(translators_root).set_text(0, " kmsecer - " + tr("Turkish")) translators.create_item(translators_root).set_text(0, " Rıdvan SAYLAR - " + tr("Turkish")) translators.create_item(translators_root).set_text(0, " latbat58 - " + tr("Turkish")) - translators.create_item(translators_root).set_text(0, " M Buhari Horoz (Sorian01) - " + tr("Turkish")) + translators.create_item(translators_root).set_text( + 0, " M Buhari Horoz (Sorian01) - " + tr("Turkish") + ) translators.create_item(translators_root).set_text(0, " br.bahrampour - " + tr("Turkish")) diff --git a/src/UI/Dialogs/AboutDialog.tscn b/src/UI/Dialogs/AboutDialog.tscn index 92782ce7f..686e1574b 100644 --- a/src/UI/Dialogs/AboutDialog.tscn +++ b/src/UI/Dialogs/AboutDialog.tscn @@ -15,6 +15,32 @@ rect_min_size = Vector2( 600, 400 ) window_title = "About Pixelorama" resizable = true script = ExtResource( 1 ) +licenses = [ "MIT License + +Copyright (c) 2019-present Orama Interactive and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", "This software uses Godot Engine, available under the following license: + +Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. +Copyright (c) 2014-2021 Godot Engine contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", "Portions of this software are copyright © 2021 The FreeType Project (www.freetype.org). All rights reserved.", "MIT License + +Copyright (c) 2020 Igor Santarek + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] [node name="AboutUI" type="VBoxContainer" parent="."] anchor_right = 1.0 @@ -196,15 +222,6 @@ size_flags_horizontal = 3 margin_right = 444.0 margin_bottom = 241.0 size_flags_vertical = 3 -text = "MIT License - -Copyright (c) 2019-present Orama Interactive and contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." readonly = true wrap_enabled = true diff --git a/src/UI/Dialogs/CreateNewImage.gd b/src/UI/Dialogs/CreateNewImage.gd index 113011c1f..e825048ec 100644 --- a/src/UI/Dialogs/CreateNewImage.gd +++ b/src/UI/Dialogs/CreateNewImage.gd @@ -1,16 +1,5 @@ extends ConfirmationDialog - -class Template: - var resolution : Vector2 - var name : String - - - func _init(_resolution : Vector2, _name := "") -> void: - resolution = _resolution - name = _name - - var aspect_ratio := 1.0 var templates := [ # Basic @@ -18,7 +7,6 @@ var templates := [ Template.new(Vector2(32, 32)), Template.new(Vector2(64, 64)), Template.new(Vector2(128, 128)), - # Nintendo Template.new(Vector2(160, 144), "GB"), Template.new(Vector2(240, 160), "GBA"), @@ -28,17 +16,14 @@ var templates := [ Template.new(Vector2(512, 480), "SNES (PAL)"), Template.new(Vector2(646, 486), "N64 (NTSC)"), Template.new(Vector2(786, 576), "N64 (PAL)"), - # Sega Template.new(Vector2(256, 192), "SMS (NTSC)"), Template.new(Vector2(256, 224), "SMS (PAL)"), Template.new(Vector2(160, 144), "GG"), Template.new(Vector2(320, 224), "MD (NTSC)"), Template.new(Vector2(320, 240), "MD (PAL)"), - # NEC - Template.new(Vector2(256, 239), "PC Engine"), #256×224 to 512×242 (mostly 256×239) - + Template.new(Vector2(256, 239), "PC Engine"), #256×224 to 512×242 (mostly 256×239) # DOS Template.new(Vector2(320, 200), "DOS EGA"), Template.new(Vector2(320, 200), "DOS VGA"), @@ -47,7 +32,6 @@ var templates := [ Template.new(Vector2(320, 200), "DOS CGA (4-Colour)"), Template.new(Vector2(160, 240), "DOS CGA (Composite)"), Template.new(Vector2(160, 240), "Tandy"), - # Commodore Template.new(Vector2(320, 200), "Amiga OCS LowRes (NTSC)"), Template.new(Vector2(320, 256), "Amiga OCS LowRes (PAL)"), @@ -57,7 +41,6 @@ var templates := [ Template.new(Vector2(1280, 256), "Amiga ECS SuperHiRes (PAL)"), Template.new(Vector2(640, 480), "Amiga ECS Multiscan"), Template.new(Vector2(320, 200), "C64"), - # Sinclair Template.new(Vector2(256, 192), "ZX Spectrum"), ] @@ -71,6 +54,15 @@ onready var landscape_button = find_node("LandscapeButton") onready var fill_color_node = find_node("FillColor") +class Template: + var resolution: Vector2 + var name: String + + func _init(_resolution: Vector2, _name := "") -> void: + resolution = _resolution + name = _name + + func _ready() -> void: width_value.value = Global.default_image_width height_value.value = Global.default_image_height @@ -85,22 +77,36 @@ func _create_option_list() -> void: var i := 1 for template in templates: if template.name != "": - templates_options.add_item("{width}x{height} - {name}".format({"width":template.resolution.x, "height":template.resolution.y, "name":template.name}), i) + templates_options.add_item( + "{width}x{height} - {name}".format( + { + "width": template.resolution.x, + "height": template.resolution.y, + "name": template.name + } + ), + i + ) else: - templates_options.add_item("{width}x{height}".format({"width":template.resolution.x, "height":template.resolution.y}), i) + templates_options.add_item( + "{width}x{height}".format( + {"width": template.resolution.x, "height": template.resolution.y} + ), + i + ) i += 1 func _on_CreateNewImage_confirmed() -> void: - var width : int = width_value.value - var height : int = height_value.value - var fill_color : Color = fill_color_node.color + var width: int = width_value.value + var height: int = height_value.value + var fill_color: Color = fill_color_node.color Global.canvas.fill_color = fill_color - var frame : Frame = Global.canvas.new_empty_frame(false, true, Vector2(width, height)) - var new_project : Project - var proj_name :String = $VBoxContainer/ProjectName/NameInput.text + var frame: Frame = Global.canvas.new_empty_frame(false, true, Vector2(width, height)) + var new_project: Project + var proj_name: String = $VBoxContainer/ProjectName/NameInput.text if proj_name.is_valid_filename(): new_project = Project.new([frame], tr(proj_name), Vector2(width, height).floor()) else: @@ -112,7 +118,7 @@ func _on_CreateNewImage_confirmed() -> void: Global.canvas.camera_zoom() -func _on_AspectRatioButton_toggled(_button_pressed : bool) -> void: +func _on_AspectRatioButton_toggled(_button_pressed: bool) -> void: aspect_ratio = width_value.value / height_value.value @@ -136,7 +142,7 @@ func toggle_size_buttons() -> void: landscape_button.connect("toggled", self, "_on_LandscapeButton_toggled") -func _on_TemplatesOptions_item_selected(id : int) -> void: +func _on_TemplatesOptions_item_selected(id: int) -> void: #if a template is chosen while "ratio button" is pressed then temporarily release it var temporary_release = false if ratio_box.pressed: @@ -154,14 +160,14 @@ func _on_TemplatesOptions_item_selected(id : int) -> void: ratio_box.pressed = true -func _on_PortraitButton_toggled(button_pressed : bool) -> void: +func _on_PortraitButton_toggled(button_pressed: bool) -> void: if !button_pressed or height_value.value > width_value.value: toggle_size_buttons() return switch_width_height() -func _on_LandscapeButton_toggled(button_pressed : bool) -> void: +func _on_LandscapeButton_toggled(button_pressed: bool) -> void: if !button_pressed or width_value.value > height_value.value: toggle_size_buttons() return diff --git a/src/UI/Dialogs/ExportDialog.gd b/src/UI/Dialogs/ExportDialog.gd index a5dbc824c..94bd1d671 100644 --- a/src/UI/Dialogs/ExportDialog.gd +++ b/src/UI/Dialogs/ExportDialog.gd @@ -1,10 +1,11 @@ extends AcceptDialog # called when user resumes export after filename collision -signal resume_export_function() +signal resume_export_function -var animated_preview_current_frame := 0 -var animated_preview_frames = [] +var preview_current_frame := 0 +var preview_frames := [] +var pingpong_direction = Export.AnimationDirection.FORWARD onready var tabs = $VBoxContainer/Tabs onready var popups = $Popups @@ -14,7 +15,7 @@ onready var path_dialog_popup = $Popups/PathDialog onready var export_progress_popup = $Popups/ExportProgressBar onready var export_progress_bar = $Popups/ExportProgressBar/MarginContainer/ProgressBar -onready var animation_options_multiple_animations_directories = $VBoxContainer/AnimationOptions/MultipleAnimationsDirectories +onready var multiple_animations_directories = find_node("MultipleAnimationsDirectories") onready var previews = $VBoxContainer/PreviewPanel/PreviewScroll/Previews onready var frame_timer = $FrameTimer @@ -22,17 +23,16 @@ onready var frame_options = $VBoxContainer/FrameOptions onready var frame_options_frame_number = $VBoxContainer/FrameOptions/FrameNumber/FrameNumber onready var spritesheet_options = $VBoxContainer/SpritesheetOptions -onready var spritesheet_options_frames = $VBoxContainer/SpritesheetOptions/Frames/Frames -onready var spritesheet_options_orientation = $VBoxContainer/SpritesheetOptions/Orientation/Orientation -onready var spritesheet_options_lines_count = $VBoxContainer/SpritesheetOptions/Orientation/LinesCount -onready var spritesheet_options_lines_count_label = $VBoxContainer/SpritesheetOptions/Orientation/LinesCountLabel +onready var spritesheet_frames = $VBoxContainer/SpritesheetOptions/Frames/Frames +onready var spritesheet_orientation = $VBoxContainer/SpritesheetOptions/Orientation/Orientation +onready var spritesheet_lines_count = $VBoxContainer/SpritesheetOptions/Orientation/LinesCount +onready var spritesheet_lines_count_label = spritesheet_options.find_node("LinesCountLabel") onready var animation_options = $VBoxContainer/AnimationOptions onready var animation_options_animation_type = $VBoxContainer/AnimationOptions/AnimationType onready var animation_options_animation_options = $VBoxContainer/AnimationOptions/AnimatedOptions onready var animation_options_direction = $VBoxContainer/AnimationOptions/AnimatedOptions/Direction - onready var options_resize = $VBoxContainer/Options/Resize onready var options_interpolation = $VBoxContainer/Options/Interpolation onready var path_container = $VBoxContainer/Path @@ -82,12 +82,12 @@ func show_tab() -> void: Export.lines_count = int(ceil(sqrt(Export.number_of_frames))) Export.process_spritesheet() file_file_format.selected = Export.FileFormat.PNG - spritesheet_options_frames.select(Export.frame_current_tag) + spritesheet_frames.select(Export.frame_current_tag) frame_timer.stop() - spritesheet_options_orientation.selected = Export.orientation - spritesheet_options_lines_count.max_value = Export.number_of_frames - spritesheet_options_lines_count.value = Export.lines_count - spritesheet_options_lines_count_label.text = "Columns:" + spritesheet_orientation.selected = Export.orientation + spritesheet_lines_count.max_value = Export.number_of_frames + spritesheet_lines_count.value = Export.lines_count + spritesheet_lines_count_label.text = "Columns:" spritesheet_options.show() Export.ExportTab.ANIMATION: set_file_format_selector() @@ -132,24 +132,31 @@ func add_image_preview(image: Image, canvas_number: int = -1) -> void: func add_animated_preview() -> void: - animated_preview_current_frame = Export.processed_images.size() - 1 if Export.direction == Export.AnimationDirection.BACKWARDS else 0 - animated_preview_frames = [] + preview_current_frame = ( + Export.processed_images.size() - 1 + if Export.direction == Export.AnimationDirection.BACKWARDS + else 0 + ) + preview_frames = [] for processed_image in Export.processed_images: var texture = ImageTexture.new() texture.create_from_image(processed_image, 0) - animated_preview_frames.push_back(texture) + preview_frames.push_back(texture) var container = create_preview_container() container.name = "PreviewContainer" var preview = create_preview_rect() preview.name = "Preview" - preview.texture = animated_preview_frames[animated_preview_current_frame] + preview.texture = preview_frames[preview_current_frame] container.add_child(preview) previews.add_child(container) - frame_timer.set_one_shot(true) #The wait_time it can't change correctly if it is playing - frame_timer.wait_time = Global.current_project.frames[animated_preview_current_frame].duration * (1 / Global.current_project.fps) + frame_timer.set_one_shot(true) #The wait_time it can't change correctly if it is playing + frame_timer.wait_time = ( + Global.current_project.frames[preview_current_frame].duration + * (1 / Global.current_project.fps) + ) frame_timer.start() @@ -176,15 +183,15 @@ func remove_previews() -> void: func set_file_format_selector() -> void: - animation_options_multiple_animations_directories.visible = false + multiple_animations_directories.visible = false match Export.animation_type: Export.AnimationType.MULTIPLE_FILES: Export.file_format = Export.FileFormat.PNG file_file_format.selected = Export.FileFormat.PNG frame_timer.stop() animation_options_animation_options.hide() - animation_options_multiple_animations_directories.pressed = Export.new_dir_for_each_frame_tag - animation_options_multiple_animations_directories.visible = true + multiple_animations_directories.pressed = Export.new_dir_for_each_frame_tag + multiple_animations_directories.visible = true Export.AnimationType.ANIMATED: Export.file_format = Export.FileFormat.GIF file_file_format.selected = Export.FileFormat.GIF @@ -193,12 +200,12 @@ func set_file_format_selector() -> void: func create_frame_tag_list() -> void: # Clear existing tag list from entry if it exists - spritesheet_options_frames.clear() - spritesheet_options_frames.add_item("All Frames", 0) # Re-add removed 'All Frames' item + spritesheet_frames.clear() + spritesheet_frames.add_item("All Frames", 0) # Re-add removed 'All Frames' item # Repopulate list with current tag list for item in Global.current_project.animation_tags: - spritesheet_options_frames.add_item(item.name) + spritesheet_frames.add_item(item.name) func open_path_validation_alert_popup() -> void: @@ -229,7 +236,9 @@ func _on_ExportDialog_about_to_show() -> void: Export.directory_path = "user://" if Export.directory_path.empty(): - Export.directory_path = Global.config_cache.get_value("data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)) + Export.directory_path = Global.config_cache.get_value( + "data", "current_dir", OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP) + ) # If export already occured - sets gui to show previous settings options_resize.value = Export.resize @@ -240,16 +249,17 @@ func _on_ExportDialog_about_to_show() -> void: file_file_format.selected = Export.file_format show_tab() - for child in popups.get_children(): # Set the theme for the popups + for child in popups.get_children(): # Set the theme for the popups child.theme = Global.control.theme - Export.file_exists_alert = tr("File %s already exists. Overwrite?") # Update translation + Export.file_exists_alert = tr("File %s already exists. Overwrite?") # Update translation # Set the size of the preview checker var checker = $VBoxContainer/PreviewPanel/TransparentChecker checker.rect_size = checker.get_parent().rect_size -func _on_Tabs_tab_clicked(tab : int) -> void: + +func _on_Tabs_tab_clicked(tab: int) -> void: Export.current_tab = tab show_tab() @@ -260,42 +270,42 @@ func _on_Frame_value_changed(value: float) -> void: set_preview() -func _on_Orientation_item_selected(id : int) -> void: +func _on_Orientation_item_selected(id: int) -> void: Export.orientation = id if Export.orientation == Export.Orientation.ROWS: - spritesheet_options_lines_count_label.text = "Columns:" + spritesheet_lines_count_label.text = "Columns:" else: - spritesheet_options_lines_count_label.text = "Rows:" - spritesheet_options_lines_count.value = Export.frames_divided_by_spritesheet_lines() + spritesheet_lines_count_label.text = "Rows:" + spritesheet_lines_count.value = Export.frames_divided_by_spritesheet_lines() Export.process_spritesheet() set_preview() -func _on_LinesCount_value_changed(value : float) -> void: +func _on_LinesCount_value_changed(value: float) -> void: Export.lines_count = value Export.process_spritesheet() set_preview() -func _on_AnimationType_item_selected(id : int) -> void: +func _on_AnimationType_item_selected(id: int) -> void: Export.animation_type = id set_file_format_selector() set_preview() -func _on_Direction_item_selected(id : int) -> void: +func _on_Direction_item_selected(id: int) -> void: Export.direction = id match id: Export.AnimationDirection.FORWARD: - animated_preview_current_frame = 0 + preview_current_frame = 0 Export.AnimationDirection.BACKWARDS: - animated_preview_current_frame = Export.processed_images.size() - 1 + preview_current_frame = Export.processed_images.size() - 1 Export.AnimationDirection.PING_PONG: - animated_preview_current_frame = 0 + preview_current_frame = 0 pingpong_direction = Export.AnimationDirection.FORWARD -func _on_Resize_value_changed(value : float) -> void: +func _on_Resize_value_changed(value: float) -> void: Export.resize = value @@ -308,7 +318,7 @@ func _on_ExportDialog_confirmed() -> void: hide() -func _on_ExportDialog_custom_action(action : String) -> void: +func _on_ExportDialog_custom_action(action: String) -> void: if action == "cancel": hide() @@ -317,23 +327,23 @@ func _on_PathButton_pressed() -> void: path_dialog_popup.popup_centered() -func _on_PathLineEdit_text_changed(new_text : String) -> void: +func _on_PathLineEdit_text_changed(new_text: String) -> void: Global.current_project.directory_path = new_text Export.directory_path = new_text -func _on_FileLineEdit_text_changed(new_text : String) -> void: +func _on_FileLineEdit_text_changed(new_text: String) -> void: Global.current_project.file_name = new_text Export.file_name = new_text -func _on_FileDialog_dir_selected(dir : String) -> void: +func _on_FileDialog_dir_selected(dir: String) -> void: path_line_edit.text = dir Global.current_project.directory_path = dir Export.directory_path = dir -func _on_FileFormat_item_selected(id : int) -> void: +func _on_FileFormat_item_selected(id: int) -> void: Global.current_project.file_format = id Export.file_format = id @@ -345,7 +355,7 @@ func _on_FileExistsAlert_confirmed() -> void: emit_signal("resume_export_function") -func _on_FileExistsAlert_custom_action(action : String) -> void: +func _on_FileExistsAlert_custom_action(action: String) -> void: if action == "cancel": # Cancel export file_exists_alert_popup.dialog_text = Export.file_exists_alert @@ -354,61 +364,83 @@ func _on_FileExistsAlert_custom_action(action : String) -> void: file_exists_alert_popup.hide() -var pingpong_direction = Export.AnimationDirection.FORWARD func _on_FrameTimer_timeout() -> void: - $VBoxContainer/PreviewPanel/PreviewScroll/Previews/PreviewContainer/Preview.texture = animated_preview_frames[animated_preview_current_frame] + previews.get_node("PreviewContainer/Preview").texture = preview_frames[preview_current_frame] match Export.direction: Export.AnimationDirection.FORWARD: - if animated_preview_current_frame == animated_preview_frames.size() - 1: - animated_preview_current_frame = 0 + if preview_current_frame == preview_frames.size() - 1: + preview_current_frame = 0 else: - animated_preview_current_frame += 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) + preview_current_frame += 1 + frame_timer.wait_time = ( + Global.current_project.frames[( + (preview_current_frame - 1) + % (preview_frames.size()) + )].duration + * (1 / Global.current_project.fps) + ) frame_timer.start() Export.AnimationDirection.BACKWARDS: - if animated_preview_current_frame == 0: - animated_preview_current_frame = Export.processed_images.size() - 1 + if preview_current_frame == 0: + preview_current_frame = Export.processed_images.size() - 1 else: - animated_preview_current_frame -= 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) + preview_current_frame -= 1 + frame_timer.wait_time = ( + Global.current_project.frames[( + (preview_current_frame + 1) + % (preview_frames.size()) + )].duration + * (1 / Global.current_project.fps) + ) frame_timer.start() Export.AnimationDirection.PING_PONG: match pingpong_direction: Export.AnimationDirection.FORWARD: - if animated_preview_current_frame == animated_preview_frames.size() - 1: + if preview_current_frame == preview_frames.size() - 1: pingpong_direction = Export.AnimationDirection.BACKWARDS - animated_preview_current_frame -= 1 - if animated_preview_current_frame <= 0: - animated_preview_current_frame = 0 + preview_current_frame -= 1 + if preview_current_frame <= 0: + preview_current_frame = 0 else: - animated_preview_current_frame += 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) + preview_current_frame += 1 + frame_timer.wait_time = ( + Global.current_project.frames[( + (preview_current_frame - 1) + % (preview_frames.size()) + )].duration + * (1 / Global.current_project.fps) + ) frame_timer.start() Export.AnimationDirection.BACKWARDS: - if animated_preview_current_frame == 0: - animated_preview_current_frame += 1 - if animated_preview_current_frame >= animated_preview_frames.size() - 1: - animated_preview_current_frame = 0 + if preview_current_frame == 0: + preview_current_frame += 1 + if preview_current_frame >= preview_frames.size() - 1: + preview_current_frame = 0 pingpong_direction = Export.AnimationDirection.FORWARD else: - animated_preview_current_frame -= 1 - frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps) + preview_current_frame -= 1 + frame_timer.wait_time = ( + Global.current_project.frames[( + (preview_current_frame + 1) + % (preview_frames.size()) + )].duration + * (1 / Global.current_project.fps) + ) frame_timer.start() - func _on_ExportDialog_popup_hide() -> void: frame_timer.stop() -func _on_MultipleAnimationsDirectories_toggled(button_pressed : bool) -> void: +func _on_MultipleAnimationsDirectories_toggled(button_pressed: bool) -> void: Export.new_dir_for_each_frame_tag = button_pressed -func _on_Frames_item_selected(id : int) -> void: +func _on_Frames_item_selected(id: int) -> void: Export.frame_current_tag = id Export.process_spritesheet() set_preview() - spritesheet_options_lines_count.max_value = Export.number_of_frames - spritesheet_options_lines_count.value = Export.lines_count + spritesheet_lines_count.max_value = Export.number_of_frames + spritesheet_lines_count.value = Export.lines_count diff --git a/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd b/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd index eeca74b72..dba342f7c 100644 --- a/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd +++ b/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd @@ -1,17 +1,18 @@ extends ImageEffect - var red := true var green := true var blue := true var alpha := false -var shaderPath : String = "res://src/Shaders/Desaturate.shader" +var shader_path: String = "res://src/Shaders/Desaturate.shader" var confirmed: bool = false + + func _about_to_show(): - var sm : ShaderMaterial = ShaderMaterial.new() - sm.shader = load(shaderPath) + var sm: ShaderMaterial = ShaderMaterial.new() + sm.shader = load(shader_path) preview.set_material(sm) ._about_to_show() @@ -26,7 +27,8 @@ func _confirmed() -> void: confirmed = true ._confirmed() -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: + +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: var selection = _project.bitmap_to_image(_project.selection_bitmap, false) var selection_tex = ImageTexture.new() selection_tex.create_from_image(selection) @@ -50,25 +52,25 @@ func commit_action(_cel : Image, _project : Project = Global.current_project) -> "has_selection": _project.has_selection } var gen: ShaderImageEffect = ShaderImageEffect.new() - gen.generate_image(_cel, shaderPath, params, _project.size) + gen.generate_image(_cel, shader_path, params, _project.size) yield(gen, "done") -func _on_RButton_toggled(button_pressed : bool) -> void: +func _on_RButton_toggled(button_pressed: bool) -> void: red = button_pressed update_preview() -func _on_GButton_toggled(button_pressed : bool) -> void: +func _on_GButton_toggled(button_pressed: bool) -> void: green = button_pressed update_preview() -func _on_BButton_toggled(button_pressed : bool) -> void: +func _on_BButton_toggled(button_pressed: bool) -> void: blue = button_pressed update_preview() -func _on_AButton_toggled(button_pressed : bool) -> void: +func _on_AButton_toggled(button_pressed: bool) -> void: alpha = button_pressed update_preview() diff --git a/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd b/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd index 83b9b94f7..396e268ba 100644 --- a/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd +++ b/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd @@ -1,8 +1,7 @@ extends ImageEffect - -onready var flip_h : CheckBox = $VBoxContainer/OptionsContainer/FlipHorizontal -onready var flip_v : CheckBox = $VBoxContainer/OptionsContainer/FlipVertical +onready var flip_h: CheckBox = $VBoxContainer/OptionsContainer/FlipHorizontal +onready var flip_v: CheckBox = $VBoxContainer/OptionsContainer/FlipVertical func set_nodes() -> void: @@ -11,42 +10,47 @@ func set_nodes() -> void: affect_option_button = $VBoxContainer/OptionsContainer/AffectOptionButton -func commit_action(_cel : Image, project : Project = Global.current_project) -> void: +func commit_action(_cel: Image, project: Project = Global.current_project) -> void: flip_image(_cel, selection_checkbox.pressed, project) -func _on_FlipHorizontal_toggled(_button_pressed : bool) -> void: +func _on_FlipHorizontal_toggled(_button_pressed: bool) -> void: update_preview() -func _on_FlipVertical_toggled(_button_pressed : bool) -> void: +func _on_FlipVertical_toggled(_button_pressed: bool) -> void: update_preview() -func flip_image(image : Image, affect_selection : bool, project : Project = Global.current_project) -> void: - if !(affect_selection and project.has_selection): +func flip_image(img: Image, affect_selection: bool, proj: Project = Global.current_project) -> void: + if !(affect_selection and proj.has_selection): if flip_h.pressed: - image.flip_x() + img.flip_x() if flip_v.pressed: - image.flip_y() + img.flip_y() else: # Create a temporary image that only has the selected pixels in it var selected_image := Image.new() - selected_image.create(image.get_width(), image.get_height(), false, Image.FORMAT_RGBA8) + selected_image.create(img.get_width(), img.get_height(), false, Image.FORMAT_RGBA8) selected_image.lock() - image.lock() - for x in image.get_width(): - for y in image.get_width(): + img.lock() + for x in img.get_width(): + for y in img.get_width(): var pos := Vector2(x, y) - if project.can_pixel_get_drawn(pos): - var color : Color = image.get_pixelv(pos) + if proj.can_pixel_get_drawn(pos): + var color: Color = img.get_pixelv(pos) selected_image.set_pixelv(pos, color) - image.set_pixelv(pos, Color(0, 0, 0, 0)) + img.set_pixelv(pos, Color(0, 0, 0, 0)) if flip_h.pressed: selected_image.flip_x() if flip_v.pressed: selected_image.flip_y() selected_image.unlock() - image.blit_rect_mask(selected_image, selected_image, Rect2(Vector2.ZERO, selected_image.get_size()), Vector2.ZERO) - image.unlock() + img.blit_rect_mask( + selected_image, + selected_image, + Rect2(Vector2.ZERO, selected_image.get_size()), + Vector2.ZERO + ) + img.unlock() diff --git a/src/UI/Dialogs/ImageEffects/GradientDialog.gd b/src/UI/Dialogs/ImageEffects/GradientDialog.gd index 4213b94cc..3b35f62c9 100644 --- a/src/UI/Dialogs/ImageEffects/GradientDialog.gd +++ b/src/UI/Dialogs/ImageEffects/GradientDialog.gd @@ -1,10 +1,10 @@ extends ImageEffect - -onready var color1 : ColorPickerButton = $VBoxContainer/OptionsContainer/ColorsContainer/ColorPickerButton -onready var color2 : ColorPickerButton = $VBoxContainer/OptionsContainer/ColorsContainer/ColorPickerButton2 -onready var steps : SpinBox = $VBoxContainer/OptionsContainer/StepSpinBox -onready var direction : OptionButton = $VBoxContainer/OptionsContainer/DirectionOptionButton +onready var options_cont = $VBoxContainer/OptionsContainer +onready var color1: ColorPickerButton = options_cont.get_node("ColorsContainer/ColorPickerButton") +onready var color2: ColorPickerButton = options_cont.get_node("ColorsContainer/ColorPickerButton2") +onready var steps: SpinBox = options_cont.get_node("StepSpinBox") +onready var direction: OptionButton = options_cont.get_node("DirectionOptionButton") func _ready() -> void: @@ -18,21 +18,28 @@ func set_nodes() -> void: affect_option_button = $VBoxContainer/OptionsContainer/AffectOptionButton -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: - DrawingAlgos.generate_gradient(_cel, [color1.color, color2.color], steps.value, direction.selected, selection_checkbox.pressed, _project) +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: + DrawingAlgos.generate_gradient( + _cel, + [color1.color, color2.color], + steps.value, + direction.selected, + selection_checkbox.pressed, + _project + ) -func _on_ColorPickerButton_color_changed(_color : Color) -> void: +func _on_ColorPickerButton_color_changed(_color: Color) -> void: update_preview() -func _on_ColorPickerButton2_color_changed(_color : Color) -> void: +func _on_ColorPickerButton2_color_changed(_color: Color) -> void: update_preview() -func _on_StepSpinBox_value_changed(_value : int) -> void: +func _on_StepSpinBox_value_changed(_value: int) -> void: update_preview() -func _on_DirectionOptionButton_item_selected(_index : int) -> void: +func _on_DirectionOptionButton_item_selected(_index: int) -> void: update_preview() diff --git a/src/UI/Dialogs/ImageEffects/HSVDialog.gd b/src/UI/Dialogs/ImageEffects/HSVDialog.gd index 33f079f87..f4af1c285 100644 --- a/src/UI/Dialogs/ImageEffects/HSVDialog.gd +++ b/src/UI/Dialogs/ImageEffects/HSVDialog.gd @@ -1,5 +1,9 @@ extends ImageEffect +var shader_path: String = "res://src/Shaders/HSV.shader" + +var live_preview: bool = true +var confirmed: bool = false onready var hue_slider = $VBoxContainer/HBoxContainer/Sliders/Hue onready var sat_slider = $VBoxContainer/HBoxContainer/Sliders/Saturation @@ -11,15 +15,11 @@ onready var val_spinbox = $VBoxContainer/HBoxContainer/TextBoxes/Value onready var wait_apply_timer = $WaitApply onready var wait_time_spinbox = $VBoxContainer/WaitSettings/WaitTime -var shaderPath : String = "res://src/Shaders/HSV.shader" -var live_preview :bool = true -var confirmed: bool = false - -func _about_to_show(): +func _about_to_show() -> void: reset() - var sm : ShaderMaterial = ShaderMaterial.new() - sm.shader = load(shaderPath) + var sm: ShaderMaterial = ShaderMaterial.new() + sm.shader = load(shader_path) preview.set_material(sm) ._about_to_show() @@ -36,35 +36,35 @@ func _confirmed() -> void: reset() -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: var selection = _project.bitmap_to_image(_project.selection_bitmap, false) var selection_tex = ImageTexture.new() selection_tex.create_from_image(selection) if !confirmed: - preview.material.set_shader_param("hue_shift_amount", hue_slider.value /360) - preview.material.set_shader_param("sat_shift_amount", sat_slider.value /100) - preview.material.set_shader_param("val_shift_amount", val_slider.value /100) + preview.material.set_shader_param("hue_shift_amount", hue_slider.value / 360) + preview.material.set_shader_param("sat_shift_amount", sat_slider.value / 100) + preview.material.set_shader_param("val_shift_amount", val_slider.value / 100) preview.material.set_shader_param("selection", selection_tex) preview.material.set_shader_param("affect_selection", selection_checkbox.pressed) preview.material.set_shader_param("has_selection", _project.has_selection) else: var params = { - "hue_shift_amount": hue_slider.value /360, - "sat_shift_amount": sat_slider.value /100, - "val_shift_amount": val_slider.value /100, + "hue_shift_amount": hue_slider.value / 360, + "sat_shift_amount": sat_slider.value / 100, + "val_shift_amount": val_slider.value / 100, "selection": selection_tex, "affect_selection": selection_checkbox.pressed, "has_selection": _project.has_selection } var gen: ShaderImageEffect = ShaderImageEffect.new() - gen.generate_image(_cel, shaderPath, params, _project.size) + gen.generate_image(_cel, shader_path, params, _project.size) yield(gen, "done") func reset() -> void: disconnect_signals() - wait_apply_timer.wait_time = wait_time_spinbox.value/1000.0 + wait_apply_timer.wait_time = wait_time_spinbox.value / 1000.0 hue_slider.value = 0 sat_slider.value = 0 val_slider.value = 0 @@ -76,24 +76,24 @@ func reset() -> void: func disconnect_signals() -> void: - hue_slider.disconnect("value_changed",self,"_on_Hue_value_changed") - sat_slider.disconnect("value_changed",self,"_on_Saturation_value_changed") - val_slider.disconnect("value_changed",self,"_on_Value_value_changed") - hue_spinbox.disconnect("value_changed",self,"_on_Hue_value_changed") - sat_spinbox.disconnect("value_changed",self,"_on_Saturation_value_changed") - val_spinbox.disconnect("value_changed",self,"_on_Value_value_changed") + hue_slider.disconnect("value_changed", self, "_on_Hue_value_changed") + sat_slider.disconnect("value_changed", self, "_on_Saturation_value_changed") + val_slider.disconnect("value_changed", self, "_on_Value_value_changed") + hue_spinbox.disconnect("value_changed", self, "_on_Hue_value_changed") + sat_spinbox.disconnect("value_changed", self, "_on_Saturation_value_changed") + val_spinbox.disconnect("value_changed", self, "_on_Value_value_changed") func reconnect_signals() -> void: - hue_slider.connect("value_changed",self,"_on_Hue_value_changed") - sat_slider.connect("value_changed",self,"_on_Saturation_value_changed") - val_slider.connect("value_changed",self,"_on_Value_value_changed") - hue_spinbox.connect("value_changed",self,"_on_Hue_value_changed") - sat_spinbox.connect("value_changed",self,"_on_Saturation_value_changed") - val_spinbox.connect("value_changed",self,"_on_Value_value_changed") + hue_slider.connect("value_changed", self, "_on_Hue_value_changed") + sat_slider.connect("value_changed", self, "_on_Saturation_value_changed") + val_slider.connect("value_changed", self, "_on_Value_value_changed") + hue_spinbox.connect("value_changed", self, "_on_Hue_value_changed") + sat_spinbox.connect("value_changed", self, "_on_Saturation_value_changed") + val_spinbox.connect("value_changed", self, "_on_Value_value_changed") -func _on_Hue_value_changed(value : float) -> void: +func _on_Hue_value_changed(value: float) -> void: hue_spinbox.value = value hue_slider.value = value if live_preview: @@ -102,7 +102,7 @@ func _on_Hue_value_changed(value : float) -> void: wait_apply_timer.start() -func _on_Saturation_value_changed(value : float) -> void: +func _on_Saturation_value_changed(value: float) -> void: sat_spinbox.value = value sat_slider.value = value if live_preview: @@ -111,7 +111,7 @@ func _on_Saturation_value_changed(value : float) -> void: wait_apply_timer.start() -func _on_Value_value_changed(value : float) -> void: +func _on_Value_value_changed(value: float) -> void: val_spinbox.value = value val_slider.value = value if live_preview: @@ -125,7 +125,7 @@ func _on_WaitApply_timeout() -> void: func _on_WaitTime_value_changed(value: float) -> void: - wait_apply_timer.wait_time = value/1000.0 + wait_apply_timer.wait_time = value / 1000.0 func _on_LiveCheckbox_toggled(button_pressed: bool) -> void: diff --git a/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd b/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd index 882ab23d1..db0166d36 100644 --- a/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd +++ b/src/UI/Dialogs/ImageEffects/InvertColorsDialog.gd @@ -1,20 +1,22 @@ extends ImageEffect - var red := true var green := true var blue := true var alpha := false -var shaderPath : String = "res://src/Shaders/Invert.shader" +var shader_path: String = "res://src/Shaders/Invert.shader" var confirmed: bool = false -func _about_to_show(): - var sm : ShaderMaterial = ShaderMaterial.new() - sm.shader = load(shaderPath) + + +func _about_to_show() -> void: + var sm: ShaderMaterial = ShaderMaterial.new() + sm.shader = load(shader_path) preview.set_material(sm) ._about_to_show() + func set_nodes() -> void: preview = $VBoxContainer/AspectRatioContainer/Preview selection_checkbox = $VBoxContainer/OptionsContainer/SelectionCheckBox @@ -25,7 +27,8 @@ func _confirmed() -> void: confirmed = true ._confirmed() -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: + +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: var selection = _project.bitmap_to_image(_project.selection_bitmap, false) var selection_tex = ImageTexture.new() selection_tex.create_from_image(selection) @@ -49,25 +52,25 @@ func commit_action(_cel : Image, _project : Project = Global.current_project) -> "has_selection": _project.has_selection } var gen: ShaderImageEffect = ShaderImageEffect.new() - gen.generate_image(_cel, shaderPath, params, _project.size) + gen.generate_image(_cel, shader_path, params, _project.size) yield(gen, "done") -func _on_RButton_toggled(button_pressed : bool) -> void: +func _on_RButton_toggled(button_pressed: bool) -> void: red = button_pressed update_preview() -func _on_GButton_toggled(button_pressed : bool) -> void: +func _on_GButton_toggled(button_pressed: bool) -> void: green = button_pressed update_preview() -func _on_BButton_toggled(button_pressed : bool) -> void: +func _on_BButton_toggled(button_pressed: bool) -> void: blue = button_pressed update_preview() -func _on_AButton_toggled(button_pressed : bool) -> void: +func _on_AButton_toggled(button_pressed: bool) -> void: alpha = button_pressed update_preview() diff --git a/src/UI/Dialogs/ImageEffects/OutlineDialog.gd b/src/UI/Dialogs/ImageEffects/OutlineDialog.gd index d391e519e..08a003f7c 100644 --- a/src/UI/Dialogs/ImageEffects/OutlineDialog.gd +++ b/src/UI/Dialogs/ImageEffects/OutlineDialog.gd @@ -1,6 +1,5 @@ extends ImageEffect - var color := Color.red var thickness := 1 var diagonal := false @@ -20,25 +19,27 @@ func set_nodes() -> void: affect_option_button = $VBoxContainer/OptionsContainer/AffectOptionButton -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: - DrawingAlgos.generate_outline(_cel, selection_checkbox.pressed, _project, color, thickness, diagonal, inside_image) +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: + DrawingAlgos.generate_outline( + _cel, selection_checkbox.pressed, _project, color, thickness, diagonal, inside_image + ) -func _on_ThickValue_value_changed(value : int) -> void: +func _on_ThickValue_value_changed(value: int) -> void: thickness = value update_preview() -func _on_OutlineColor_color_changed(_color : Color) -> void: +func _on_OutlineColor_color_changed(_color: Color) -> void: color = _color update_preview() -func _on_DiagonalCheckBox_toggled(button_pressed : bool) -> void: +func _on_DiagonalCheckBox_toggled(button_pressed: bool) -> void: diagonal = button_pressed update_preview() -func _on_InsideImageCheckBox_toggled(button_pressed : bool) -> void: +func _on_InsideImageCheckBox_toggled(button_pressed: bool) -> void: inside_image = button_pressed update_preview() diff --git a/src/UI/Dialogs/ImageEffects/ResizeCanvas.gd b/src/UI/Dialogs/ImageEffects/ResizeCanvas.gd index 219800f74..f3c6a0a33 100644 --- a/src/UI/Dialogs/ImageEffects/ResizeCanvas.gd +++ b/src/UI/Dialogs/ImageEffects/ResizeCanvas.gd @@ -1,24 +1,25 @@ extends ConfirmationDialog - var width := 64 var height := 64 var offset_x := 0 var offset_y := 0 -var image : Image +var image: Image var first_time := true -onready var width_spinbox : SpinBox = $VBoxContainer/OptionsContainer/WidthValue -onready var height_spinbox : SpinBox = $VBoxContainer/OptionsContainer/HeightValue -onready var x_spinbox : SpinBox = $VBoxContainer/OptionsContainer/XSpinBox -onready var y_spinbox : SpinBox = $VBoxContainer/OptionsContainer/YSpinBox -onready var preview_rect : TextureRect = $VBoxContainer/AspectRatioContainer/Preview +onready var width_spinbox: SpinBox = $VBoxContainer/OptionsContainer/WidthValue +onready var height_spinbox: SpinBox = $VBoxContainer/OptionsContainer/HeightValue +onready var x_spinbox: SpinBox = $VBoxContainer/OptionsContainer/XSpinBox +onready var y_spinbox: SpinBox = $VBoxContainer/OptionsContainer/YSpinBox +onready var preview_rect: TextureRect = $VBoxContainer/AspectRatioContainer/Preview func _on_ResizeCanvas_about_to_show() -> void: Global.canvas.selection.transform_content_confirm() image = Image.new() - image.create(Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8) + image.create( + Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8 + ) image.lock() var layer_i := 0 for cel in Global.current_project.frames[Global.current_project.current_frame].cels: @@ -26,14 +27,18 @@ func _on_ResizeCanvas_about_to_show() -> void: var cel_image := Image.new() cel_image.copy_from(cel.image) cel_image.lock() - if cel.opacity < 1: # If we have cel transparency + if cel.opacity < 1: # If we have cel transparency for xx in cel_image.get_size().x: for yy in cel_image.get_size().y: var pixel_color := cel_image.get_pixel(xx, yy) - var alpha : float = pixel_color.a * cel.opacity - cel_image.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha)) + var alpha: float = pixel_color.a * cel.opacity + cel_image.set_pixel( + xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha) + ) cel_image.unlock() - image.blend_rect(cel_image, Rect2(Vector2.ZERO, Global.current_project.size), Vector2.ZERO) + image.blend_rect( + cel_image, Rect2(Vector2.ZERO, Global.current_project.size), Vector2.ZERO + ) layer_i += 1 image.unlock() @@ -48,7 +53,7 @@ func _on_ResizeCanvas_confirmed() -> void: first_time = false -func _on_WidthValue_value_changed(value : int) -> void: +func _on_WidthValue_value_changed(value: int) -> void: width = value x_spinbox.min_value = min(width - Global.current_project.size.x, 0) x_spinbox.max_value = max(width - Global.current_project.size.x, 0) @@ -56,7 +61,7 @@ func _on_WidthValue_value_changed(value : int) -> void: update_preview() -func _on_HeightValue_value_changed(value : int) -> void: +func _on_HeightValue_value_changed(value: int) -> void: height = value y_spinbox.min_value = min(height - Global.current_project.size.y, 0) y_spinbox.max_value = max(height - Global.current_project.size.y, 0) @@ -64,12 +69,12 @@ func _on_HeightValue_value_changed(value : int) -> void: update_preview() -func _on_XSpinBox_value_changed(value : int) -> void: +func _on_XSpinBox_value_changed(value: int) -> void: offset_x = value update_preview() -func _on_YSpinBox_value_changed(value : int) -> void: +func _on_YSpinBox_value_changed(value: int) -> void: offset_y = value update_preview() @@ -83,14 +88,16 @@ func update_preview() -> void: # preview_image is the same as image but offsetted var preview_image := Image.new() preview_image.create(width, height, false, Image.FORMAT_RGBA8) - preview_image.blend_rect(image, Rect2(Vector2.ZERO, Global.current_project.size), Vector2(offset_x, offset_y)) + preview_image.blend_rect( + image, Rect2(Vector2.ZERO, Global.current_project.size), Vector2(offset_x, offset_y) + ) var preview_texture := ImageTexture.new() preview_texture.create_from_image(preview_image, 0) preview_rect.texture = preview_texture update_transparent_background_size(preview_image) -func update_transparent_background_size(preview_image : Image) -> void: +func update_transparent_background_size(preview_image: Image) -> void: var image_size_y = preview_rect.rect_size.y var image_size_x = preview_rect.rect_size.x if preview_image.get_size().x > preview_image.get_size().y: diff --git a/src/UI/Dialogs/ImageEffects/RotateImage.gd b/src/UI/Dialogs/ImageEffects/RotateImage.gd index fe516d8cd..fc5b53451 100644 --- a/src/UI/Dialogs/ImageEffects/RotateImage.gd +++ b/src/UI/Dialogs/ImageEffects/RotateImage.gd @@ -1,13 +1,12 @@ extends ImageEffect - -onready var type_option_button : OptionButton = $VBoxContainer/HBoxContainer2/TypeOptionButton -onready var angle_hslider : HSlider = $VBoxContainer/AngleOptions/AngleHSlider -onready var angle_spinbox : SpinBox = $VBoxContainer/AngleOptions/AngleSpinBox +var live_preview: bool = true +onready var type_option_button: OptionButton = $VBoxContainer/HBoxContainer2/TypeOptionButton +onready var angle_hslider: HSlider = $VBoxContainer/AngleOptions/AngleHSlider +onready var angle_spinbox: SpinBox = $VBoxContainer/AngleOptions/AngleSpinBox onready var wait_apply_timer = $WaitApply onready var wait_time_spinbox = $VBoxContainer/WaitSettings/WaitTime -var live_preview :bool = true func _ready() -> void: type_option_button.add_item("Rotxel") @@ -23,20 +22,23 @@ func set_nodes() -> void: func _about_to_show() -> void: ._about_to_show() - wait_apply_timer.wait_time = wait_time_spinbox.value/1000.0 + wait_apply_timer.wait_time = wait_time_spinbox.value / 1000.0 angle_hslider.value = 0 -func commit_action(_cel : Image, _project : Project = Global.current_project) -> void: - var angle : float = deg2rad(angle_hslider.value) +func commit_action(_cel: Image, _project: Project = Global.current_project) -> void: + var angle: float = deg2rad(angle_hslider.value) # warning-ignore:integer_division # warning-ignore:integer_division var pivot = Vector2(_cel.get_width() / 2, _cel.get_height() / 2) var image := Image.new() image.copy_from(_cel) if _project.has_selection and selection_checkbox.pressed: - var selection_rectangle : Rect2 = _project.get_selection_rectangle() - pivot = selection_rectangle.position + ((selection_rectangle.end - selection_rectangle.position) / 2) + var selection_rectangle: Rect2 = _project.get_selection_rectangle() + pivot = ( + selection_rectangle.position + + ((selection_rectangle.end - selection_rectangle.position) / 2) + ) image.lock() _cel.lock() for x in _project.size.x: @@ -66,7 +68,7 @@ func _confirmed() -> void: angle_hslider.value = 0 -func _on_HSlider_value_changed(_value : float) -> void: +func _on_HSlider_value_changed(_value: float) -> void: angle_spinbox.value = angle_hslider.value if live_preview: update_preview() @@ -74,11 +76,11 @@ func _on_HSlider_value_changed(_value : float) -> void: wait_apply_timer.start() -func _on_SpinBox_value_changed(_value : float) -> void: +func _on_SpinBox_value_changed(_value: float) -> void: angle_hslider.value = angle_spinbox.value -func _on_TypeOptionButton_item_selected(_id : int) -> void: +func _on_TypeOptionButton_item_selected(_id: int) -> void: update_preview() @@ -87,7 +89,7 @@ func _on_WaitApply_timeout() -> void: func _on_WaitTime_value_changed(value: float) -> void: - wait_apply_timer.wait_time = value/1000.0 + wait_apply_timer.wait_time = value / 1000.0 func _on_LiveCheckbox_toggled(button_pressed: bool) -> void: diff --git a/src/UI/Dialogs/ImageEffects/ScaleImage.gd b/src/UI/Dialogs/ImageEffects/ScaleImage.gd index f4fa43264..f705af9b8 100644 --- a/src/UI/Dialogs/ImageEffects/ScaleImage.gd +++ b/src/UI/Dialogs/ImageEffects/ScaleImage.gd @@ -1,14 +1,13 @@ extends ConfirmationDialog - var aspect_ratio := 1.0 -onready var width_value : SpinBox = find_node("WidthValue") -onready var height_value : SpinBox = find_node("HeightValue") -onready var width_value_perc : SpinBox = find_node("WidthValuePerc") -onready var height_value_perc : SpinBox = find_node("HeightValuePerc") -onready var interpolation_type : OptionButton = find_node("InterpolationType") -onready var ratio_box : BaseButton = find_node("AspectRatioButton") +onready var width_value: SpinBox = find_node("WidthValue") +onready var height_value: SpinBox = find_node("HeightValue") +onready var width_value_perc: SpinBox = find_node("WidthValuePerc") +onready var height_value_perc: SpinBox = find_node("HeightValuePerc") +onready var interpolation_type: OptionButton = find_node("InterpolationType") +onready var ratio_box: BaseButton = find_node("AspectRatioButton") func _on_ScaleImage_about_to_show() -> void: @@ -21,9 +20,9 @@ func _on_ScaleImage_about_to_show() -> void: func _on_ScaleImage_confirmed() -> void: - var width : int = width_value.value - var height : int = height_value.value - var interpolation : int = interpolation_type.selected + var width: int = width_value.value + var height: int = height_value.value + var interpolation: int = interpolation_type.selected DrawingAlgos.scale_image(width, height, interpolation) @@ -31,26 +30,26 @@ func _on_ScaleImage_popup_hide() -> void: Global.dialog_open(false) -func _on_WidthValue_value_changed(value : float) -> void: +func _on_WidthValue_value_changed(value: float) -> void: if ratio_box.pressed: height_value.value = width_value.value / aspect_ratio width_value_perc.value = (value * 100) / Global.current_project.size.x -func _on_HeightValue_value_changed(value : float) -> void: +func _on_HeightValue_value_changed(value: float) -> void: if ratio_box.pressed: width_value.value = height_value.value * aspect_ratio height_value_perc.value = (value * 100) / Global.current_project.size.y -func _on_WidthValuePerc_value_changed(value : float) -> void: +func _on_WidthValuePerc_value_changed(value: float) -> void: width_value.value = (Global.current_project.size.x * value) / 100 -func _on_HeightValuePerc_value_changed(value : float) -> void: +func _on_HeightValuePerc_value_changed(value: float) -> void: height_value.value = (Global.current_project.size.y * value) / 100 -func _on_AspectRatioButton_toggled(button_pressed : bool) -> void: +func _on_AspectRatioButton_toggled(button_pressed: bool) -> void: if button_pressed: height_value.value = width_value.value / aspect_ratio diff --git a/src/UI/Dialogs/ImageEffects/ShaderEffect.gd b/src/UI/Dialogs/ImageEffects/ShaderEffect.gd index 00b904bfd..6a6f635fb 100644 --- a/src/UI/Dialogs/ImageEffects/ShaderEffect.gd +++ b/src/UI/Dialogs/ImageEffects/ShaderEffect.gd @@ -1,17 +1,17 @@ extends ConfirmationDialog +var current_cel: Image +var shader: Shader +var params := [] # String[] -var current_cel : Image -var shader : Shader -var params := [] # String[] - -onready var preview : TextureRect = $VBoxContainer/Preview -onready var shader_loaded_label : Label = $VBoxContainer/ShaderLoadedLabel -onready var shader_params : BoxContainer = $VBoxContainer/ShaderParams +onready var preview: TextureRect = $VBoxContainer/Preview +onready var shader_loaded_label: Label = $VBoxContainer/ShaderLoadedLabel +onready var shader_params: BoxContainer = $VBoxContainer/ShaderParams func _on_ShaderEffect_about_to_show() -> void: - current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image + var current_frame: Frame = Global.current_project.frames[Global.current_project.current_frame] + current_cel = current_frame.cels[Global.current_project.current_layer].image var preview_image := Image.new() preview_image.copy_from(current_cel) @@ -25,7 +25,7 @@ func _on_ShaderEffect_confirmed() -> void: return current_cel.unlock() var viewport_texture := Image.new() - var size : Vector2 = Global.current_project.size + var size: Vector2 = Global.current_project.size var vp = VisualServer.viewport_create() var canvas = VisualServer.canvas_create() VisualServer.viewport_attach_canvas(vp, canvas) @@ -76,14 +76,14 @@ func _on_ChooseShader_pressed() -> void: $FileDialog.popup_centered(Vector2(300, 340)) -func _on_FileDialog_file_selected(path : String) -> void: +func _on_FileDialog_file_selected(path: String) -> void: var _shader = load(path) if !_shader is Shader: return change_shader(_shader, path.get_file().get_basename()) -func change_shader(_shader : Shader, name : String) -> void: +func change_shader(_shader: Shader, name: String) -> void: shader = _shader preview.material.shader = _shader shader_loaded_label.text = tr("Shader loaded:") + " " + name @@ -106,9 +106,9 @@ func change_shader(_shader : Shader, name : String) -> void: u_value = uniform_split[1].replace(";", "").strip_edges() var u_left_side = uniform_split[0].split(":") - var _u_hint := "" + var u_hint := "" if u_left_side.size() > 1: - _u_hint = u_left_side[1].strip_edges() + u_hint = u_left_side[1].strip_edges() var u_init = u_left_side[0].split(" ") var u_type = u_init[1] @@ -144,6 +144,7 @@ func change_shader(_shader : Shader, name : String) -> void: hbox.add_child(spinbox) shader_params.add_child(hbox) + # print("---") # print(uniform_split) # print(u_type) @@ -153,5 +154,5 @@ func change_shader(_shader : Shader, name : String) -> void: # print("--") -func set_shader_param(value, param : String) -> void: +func set_shader_param(value, param: String) -> void: preview.material.set_shader_param(param, value) diff --git a/src/UI/Dialogs/PreviewDialog.gd b/src/UI/Dialogs/PreviewDialog.gd index de356dc9a..b6953202e 100644 --- a/src/UI/Dialogs/PreviewDialog.gd +++ b/src/UI/Dialogs/PreviewDialog.gd @@ -1,19 +1,28 @@ extends ConfirmationDialog +enum ImageImportOptions { + NEW_TAB, + SPRITESHEET_TAB, + SPRITESHEET_LAYER, + NEW_FRAME, + REPLACE_FRAME, + NEW_LAYER, + PALETTE, + BRUSH, + PATTERN +} +enum BrushTypes { FILE, PROJECT, RANDOM } -enum ImageImportOptions {NEW_TAB, SPRITESHEET_TAB, SPRITESHEET_LAYER, NEW_FRAME, REPLACE_FRAME, NEW_LAYER, PALETTE, BRUSH, PATTERN} -enum BrushTypes {FILE, PROJECT, RANDOM} - -var path : String -var image : Image -var current_import_option : int = ImageImportOptions.NEW_TAB +var path: String +var image: Image +var current_import_option: int = ImageImportOptions.NEW_TAB var spritesheet_horizontal := 1 var spritesheet_vertical := 1 -var brush_type : int = BrushTypes.FILE +var brush_type: int = BrushTypes.FILE -onready var texture_rect : TextureRect = $VBoxContainer/CenterContainer/TextureRect -onready var image_size_label : Label = $VBoxContainer/SizeContainer/ImageSizeLabel -onready var frame_size_label : Label = $VBoxContainer/SizeContainer/FrameSizeLabel +onready var texture_rect: TextureRect = $VBoxContainer/CenterContainer/TextureRect +onready var image_size_label: Label = $VBoxContainer/SizeContainer/ImageSizeLabel +onready var frame_size_label: Label = $VBoxContainer/SizeContainer/FrameSizeLabel onready var spritesheet_tab_options = $VBoxContainer/HBoxContainer/SpritesheetTabOptions onready var spritesheet_layer_options = $VBoxContainer/HBoxContainer/SpritesheetLayerOptions onready var new_frame_options = $VBoxContainer/HBoxContainer/NewFrameOptions @@ -24,7 +33,7 @@ onready var new_brush_name = $VBoxContainer/HBoxContainer/NewBrushOptions/BrushN func _on_PreviewDialog_about_to_show() -> void: - var import_options :OptionButton= get_node("VBoxContainer/HBoxContainer/ImportOption") + var import_options: OptionButton = get_node("VBoxContainer/HBoxContainer/ImportOption") # # order as in ImageImportOptions enum import_options.add_item("New tab") @@ -40,10 +49,26 @@ func _on_PreviewDialog_about_to_show() -> void: var img_texture := ImageTexture.new() img_texture.create_from_image(image, 0) texture_rect.texture = img_texture - spritesheet_tab_options.get_node("HorizontalFrames").max_value = min(spritesheet_tab_options.get_node("HorizontalFrames").max_value, image.get_size().x) - spritesheet_tab_options.get_node("VerticalFrames").max_value = min(spritesheet_tab_options.get_node("VerticalFrames").max_value, image.get_size().y) - image_size_label.text = tr("Image Size") + ": " + str(image.get_size().x) + "×" + str(image.get_size().y) - frame_size_label.text = tr("Frame Size") + ": " + str(image.get_size().x) + "×" + str(image.get_size().y) + spritesheet_tab_options.get_node("HorizontalFrames").max_value = min( + spritesheet_tab_options.get_node("HorizontalFrames").max_value, image.get_size().x + ) + spritesheet_tab_options.get_node("VerticalFrames").max_value = min( + spritesheet_tab_options.get_node("VerticalFrames").max_value, image.get_size().y + ) + image_size_label.text = ( + tr("Image Size") + + ": " + + str(image.get_size().x) + + "×" + + str(image.get_size().y) + ) + frame_size_label.text = ( + tr("Frame Size") + + ": " + + str(image.get_size().x) + + "×" + + str(image.get_size().y) + ) func _on_PreviewDialog_popup_hide() -> void: @@ -60,23 +85,32 @@ func _on_PreviewDialog_confirmed() -> void: OpenSave.open_image_as_new_tab(path, image) elif current_import_option == ImageImportOptions.SPRITESHEET_TAB: - OpenSave.open_image_as_spritesheet_tab(path, image, spritesheet_horizontal, spritesheet_vertical) + OpenSave.open_image_as_spritesheet_tab( + path, image, spritesheet_horizontal, spritesheet_vertical + ) elif current_import_option == ImageImportOptions.SPRITESHEET_LAYER: - var frame_index : int = spritesheet_layer_options.get_node("AtFrameSpinbox").value - 1 - OpenSave.open_image_as_spritesheet_layer(path, image, path.get_basename().get_file(), spritesheet_horizontal, spritesheet_vertical, frame_index) + var frame_index: int = spritesheet_layer_options.get_node("AtFrameSpinbox").value - 1 + OpenSave.open_image_as_spritesheet_layer( + path, + image, + path.get_basename().get_file(), + spritesheet_horizontal, + spritesheet_vertical, + frame_index + ) elif current_import_option == ImageImportOptions.NEW_FRAME: - var layer_index : int = new_frame_options.get_node("AtLayerSpinbox").value + var layer_index: int = new_frame_options.get_node("AtLayerSpinbox").value OpenSave.open_image_as_new_frame(image, layer_index) elif current_import_option == ImageImportOptions.REPLACE_FRAME: - var layer_index : int = replace_frame_options.get_node("AtLayerSpinbox").value - var frame_index : int = replace_frame_options.get_node("AtFrameSpinbox").value - 1 + var layer_index: int = replace_frame_options.get_node("AtLayerSpinbox").value + var frame_index: int = replace_frame_options.get_node("AtFrameSpinbox").value - 1 OpenSave.open_image_at_frame(image, layer_index, frame_index) elif current_import_option == ImageImportOptions.NEW_LAYER: - var frame_index : int = new_layer_options.get_node("AtFrameSpinbox").value - 1 + var frame_index: int = new_layer_options.get_node("AtFrameSpinbox").value - 1 OpenSave.open_image_as_new_layer(image, path.get_basename().get_file(), frame_index) elif current_import_option == ImageImportOptions.PALETTE: @@ -86,9 +120,9 @@ func _on_PreviewDialog_confirmed() -> void: add_brush() elif current_import_option == ImageImportOptions.PATTERN: - var file_name_ext : String = path.get_file() + var file_name_ext: String = path.get_file() file_name_ext = file_name_replace(file_name_ext, "Patterns") - var file_name : String = file_name_ext.get_basename() + var file_name: String = file_name_ext.get_basename() image.convert(Image.FORMAT_RGBA8) Global.patterns_popup.add(image, file_name) @@ -98,7 +132,7 @@ func _on_PreviewDialog_confirmed() -> void: dir.copy(path, Global.directory_module.xdg_data_home.plus_file(location)) -func _on_ImportOption_item_selected(id : int) -> void: +func _on_ImportOption_item_selected(id: int) -> void: current_import_option = id frame_size_label.visible = false spritesheet_tab_options.visible = false @@ -122,19 +156,27 @@ func _on_ImportOption_item_selected(id : int) -> void: frame_size_label.visible = true spritesheet_tab_options.visible = true spritesheet_layer_options.visible = true - spritesheet_layer_options.get_node("AtFrameSpinbox").max_value = Global.current_project.frames.size() + var n_of_frames: int = Global.current_project.frames.size() + spritesheet_layer_options.get_node("AtFrameSpinbox").max_value = n_of_frames texture_rect.get_child(0).visible = true texture_rect.get_child(1).visible = true rect_size.x = spritesheet_layer_options.rect_size.x elif id == ImageImportOptions.NEW_FRAME: new_frame_options.visible = true - new_frame_options.get_node("AtLayerSpinbox").max_value = Global.current_project.layers.size() - 1 + new_frame_options.get_node("AtLayerSpinbox").max_value = ( + Global.current_project.layers.size() + - 1 + ) elif id == ImageImportOptions.REPLACE_FRAME: replace_frame_options.visible = true - replace_frame_options.get_node("AtLayerSpinbox").max_value = Global.current_project.layers.size() - 1 - replace_frame_options.get_node("AtFrameSpinbox").max_value = Global.current_project.frames.size() + replace_frame_options.get_node("AtLayerSpinbox").max_value = ( + Global.current_project.layers.size() + - 1 + ) + var at_frame_spinbox: SpinBox = replace_frame_options.get_node("AtFrameSpinbox") + at_frame_spinbox.max_value = Global.current_project.frames.size() elif id == ImageImportOptions.NEW_LAYER: new_layer_options.visible = true @@ -144,7 +186,7 @@ func _on_ImportOption_item_selected(id : int) -> void: new_brush_options.visible = true -func _on_HorizontalFrames_value_changed(value : int) -> void: +func _on_HorizontalFrames_value_changed(value: int) -> void: spritesheet_horizontal = value for child in texture_rect.get_node("HorizLines").get_children(): child.queue_free() @@ -152,7 +194,7 @@ func _on_HorizontalFrames_value_changed(value : int) -> void: spritesheet_frame_value_changed(value, false) -func _on_VerticalFrames_value_changed(value : int) -> void: +func _on_VerticalFrames_value_changed(value: int) -> void: spritesheet_vertical = value for child in texture_rect.get_node("VerticalLines").get_children(): child.queue_free() @@ -160,7 +202,7 @@ func _on_VerticalFrames_value_changed(value : int) -> void: spritesheet_frame_value_changed(value, true) -func spritesheet_frame_value_changed(value : int, vertical : bool) -> void: +func spritesheet_frame_value_changed(value: int, vertical: bool) -> void: var image_size_y = texture_rect.rect_size.y var image_size_x = texture_rect.rect_size.x if image.get_size().x > image.get_size().y: @@ -198,7 +240,7 @@ func spritesheet_frame_value_changed(value : int, vertical : bool) -> void: frame_size_label.text = tr("Frame Size") + ": " + str(frame_width) + "×" + str(frame_height) -func _on_BrushTypeOption_item_selected(index : int) -> void: +func _on_BrushTypeOption_item_selected(index: int) -> void: brush_type = index new_brush_name.visible = false if brush_type == BrushTypes.RANDOM: @@ -208,9 +250,9 @@ func _on_BrushTypeOption_item_selected(index : int) -> void: func add_brush() -> void: image.convert(Image.FORMAT_RGBA8) if brush_type == BrushTypes.FILE: - var file_name_ext : String = path.get_file() + var file_name_ext: String = path.get_file() file_name_ext = file_name_replace(file_name_ext, "Brushes") - var file_name : String = file_name_ext.get_basename() + var file_name: String = file_name_ext.get_basename() Brushes.add_file_brush([image], file_name) @@ -220,7 +262,7 @@ func add_brush() -> void: dir.copy(path, Global.directory_module.xdg_data_home.plus_file(location)) elif brush_type == BrushTypes.PROJECT: - var file_name : String = path.get_file().get_basename() + var file_name: String = path.get_file().get_basename() Global.current_project.brushes.append(image) Brushes.add_project_brush(image, file_name) @@ -243,8 +285,8 @@ func add_brush() -> void: curr_file = dir.get_next() dir.list_dir_end() - var file_ext : String = path.get_file().get_extension() - var index : int = random_brushes.size() + 1 + var file_ext: String = path.get_file().get_extension() + var index: int = random_brushes.size() + 1 var file_name = "~" + brush_name + str(index) + "." + file_ext var location := "Brushes".plus_file(brush_name).plus_file(file_name) dir.copy(path, Global.directory_module.xdg_data_home.plus_file(location)) @@ -253,7 +295,7 @@ func add_brush() -> void: # Checks if the file already exists # If it does, add a number to its name, for example # "Brush_Name" will become "Brush_Name (2)", "Brush_Name (3)", etc. -func file_name_replace(name : String, folder : String) -> String: +func file_name_replace(name: String, folder: String) -> String: var i := 1 var file_ext = name.get_extension() var temp_name := name diff --git a/src/UI/Dialogs/SplashDialog.gd b/src/UI/Dialogs/SplashDialog.gd index c34771d28..9079ea93b 100644 --- a/src/UI/Dialogs/SplashDialog.gd +++ b/src/UI/Dialogs/SplashDialog.gd @@ -1,16 +1,27 @@ extends WindowDialog - var artworks := [ - ["Roroto Sic", preload("res://assets/graphics/splash_screen/artworks/roroto.png"), "https://linktr.ee/Roroto_Sic"], - ["Kamilayza", preload("res://assets/graphics/splash_screen/artworks/kamilayza.png"), "https://twitter.com/kamilayza"], - ["Wishdream", preload("res://assets/graphics/splash_screen/artworks/wishdream.png"), "https://twitter.com/WishdreamStar"] + [ + "Roroto Sic", + preload("res://assets/graphics/splash_screen/artworks/roroto.png"), + "https://linktr.ee/Roroto_Sic" + ], + [ + "Kamilayza", + preload("res://assets/graphics/splash_screen/artworks/kamilayza.png"), + "https://twitter.com/kamilayza" + ], + [ + "Wishdream", + preload("res://assets/graphics/splash_screen/artworks/wishdream.png"), + "https://twitter.com/WishdreamStar" + ] ] -var chosen_artwork : int +var chosen_artwork: int -var splash_art_texturerect : TextureRect -var art_by_label : Button +var splash_art_texturerect: TextureRect +var art_by_label: Button onready var latin_font = preload("res://assets/fonts/Roboto-Small.tres") onready var cjk_font = preload("res://assets/fonts/CJK/DroidSansFallback-Small.tres") @@ -19,8 +30,8 @@ onready var cjk_font = preload("res://assets/fonts/CJK/DroidSansFallback-Small.t func _on_SplashDialog_about_to_show() -> void: splash_art_texturerect = find_node("SplashArt") art_by_label = find_node("ArtistName") - var show_on_startup_button : CheckBox = find_node("ShowOnStartup") - var copyright_label : Label = find_node("CopyrightLabel") + var show_on_startup_button: CheckBox = find_node("ShowOnStartup") + var copyright_label: Label = find_node("CopyrightLabel") if Global.config_cache.has_section_key("preferences", "startup"): show_on_startup_button.pressed = !Global.config_cache.get_value("preferences", "startup") @@ -36,27 +47,33 @@ func _on_SplashDialog_about_to_show() -> void: show_on_startup_button.add_font_override("font", latin_font) copyright_label.add_font_override("font", latin_font) - get_stylebox("panel", "WindowDialog").bg_color = Global.control.theme.get_stylebox("panel", "WindowDialog").bg_color - get_stylebox("panel", "WindowDialog").border_color = Global.control.theme.get_stylebox("panel", "WindowDialog").border_color + get_stylebox("panel", "WindowDialog").bg_color = Global.control.theme.get_stylebox( + "panel", "WindowDialog" + ).bg_color + get_stylebox("panel", "WindowDialog").border_color = Global.control.theme.get_stylebox( + "panel", "WindowDialog" + ).border_color if OS.get_name() == "HTML5": $Contents/ButtonsPatronsLogos/Buttons/OpenLastBtn.visible = false -func change_artwork(var direction : int) -> void: - if chosen_artwork+direction > artworks.size()-1 or chosen_artwork+direction < 0: - chosen_artwork = 0 if direction == 1 else artworks.size()-1 + +func change_artwork(direction: int) -> void: + if chosen_artwork + direction > artworks.size() - 1 or chosen_artwork + direction < 0: + chosen_artwork = 0 if direction == 1 else artworks.size() - 1 else: - chosen_artwork = chosen_artwork+direction + chosen_artwork = chosen_artwork + direction splash_art_texturerect.texture = artworks[chosen_artwork][1] art_by_label.text = tr("Art by: %s") % artworks[chosen_artwork][0] art_by_label.hint_tooltip = artworks[chosen_artwork][2] + func _on_ArtCredits_pressed() -> void: OS.shell_open(artworks[chosen_artwork][2]) -func _on_ShowOnStartup_toggled(pressed : bool) -> void: +func _on_ShowOnStartup_toggled(pressed: bool) -> void: if pressed: Global.config_cache.set_value("preferences", "startup", false) else: @@ -81,7 +98,7 @@ func _on_NewBtn_pressed() -> void: Global.top_menu_container.file_menu_id_pressed(0) -func _on_OpenBtn__pressed() -> void: +func _on_OpenBtn_pressed() -> void: visible = false Global.top_menu_container.file_menu_id_pressed(1) @@ -90,8 +107,10 @@ func _on_OpenLastBtn_pressed() -> void: visible = false Global.top_menu_container.file_menu_id_pressed(2) + func _on_ChangeArtBtnLeft_pressed(): change_artwork(-1) + func _on_ChangeArtBtnRight_pressed(): change_artwork(1) diff --git a/src/UI/Dialogs/SplashDialog.tscn b/src/UI/Dialogs/SplashDialog.tscn index 66aa39904..cd6e2834c 100644 --- a/src/UI/Dialogs/SplashDialog.tscn +++ b/src/UI/Dialogs/SplashDialog.tscn @@ -53,9 +53,7 @@ texture = ExtResource( 2 ) expand = true stretch_mode = 6 -[node name="ChangeArtBtnLeft" type="Button" parent="Contents/SplashArt" groups=[ -"UIButtons", -]] +[node name="ChangeArtBtnLeft" type="Button" parent="Contents/SplashArt" groups=["UIButtons"]] anchor_top = 0.5 anchor_bottom = 0.5 margin_left = 5.0 @@ -87,9 +85,7 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="ChangeArtBtnRight" type="Button" parent="Contents/SplashArt" groups=[ -"UIButtons", -]] +[node name="ChangeArtBtnRight" type="Button" parent="Contents/SplashArt" groups=["UIButtons"]] anchor_left = 1.0 anchor_top = 0.5 anchor_right = 1.0 @@ -308,7 +304,7 @@ __meta__ = { [connection signal="pressed" from="Contents/SplashArt/ChangeArtBtnRight" to="." method="_on_ChangeArtBtnRight_pressed"] [connection signal="pressed" from="Contents/ArtBy/ArtistName" to="." method="_on_ArtCredits_pressed"] [connection signal="pressed" from="Contents/ButtonsPatronsLogos/Buttons/NewBtn" to="." method="_on_NewBtn_pressed"] -[connection signal="pressed" from="Contents/ButtonsPatronsLogos/Buttons/OpenBtn" to="." method="_on_OpenBtn__pressed"] +[connection signal="pressed" from="Contents/ButtonsPatronsLogos/Buttons/OpenBtn" to="." method="_on_OpenBtn_pressed"] [connection signal="pressed" from="Contents/ButtonsPatronsLogos/Buttons/OpenLastBtn" to="." method="_on_OpenLastBtn_pressed"] [connection signal="pressed" from="Contents/ButtonsPatronsLogos/Info/VBoxContainer/Branding/Links/GithubButton" to="." method="_on_GithubButton_pressed"] [connection signal="pressed" from="Contents/ButtonsPatronsLogos/Info/VBoxContainer/Branding/Links/DiscordButton" to="." method="_on_DiscordButton_pressed"] diff --git a/src/UI/Dialogs/WindowOpacityDialog.gd b/src/UI/Dialogs/WindowOpacityDialog.gd index 546e93e70..0da1883b0 100644 --- a/src/UI/Dialogs/WindowOpacityDialog.gd +++ b/src/UI/Dialogs/WindowOpacityDialog.gd @@ -1,9 +1,7 @@ extends AcceptDialog - -onready var hslider : HSlider = $HBoxContainer2/HSlider -onready var spinbox : SpinBox = $HBoxContainer2/SpinBox -onready var alternate_transparent_background : ColorRect = Global.control.alternate_transparent_background +onready var hslider: HSlider = $HBoxContainer2/HSlider +onready var spinbox: SpinBox = $HBoxContainer2/SpinBox func _on_WindowOpacityDialog_about_to_show() -> void: @@ -12,16 +10,20 @@ func _on_WindowOpacityDialog_about_to_show() -> void: func _on_value_changed(value: float) -> void: + set_window_opacity(value) + + +func set_window_opacity(value: float) -> void: if OS.window_fullscreen: value = 100.0 hslider.value = value spinbox.value = value value = value / 100.0 - alternate_transparent_background.visible = value < 1.0 + Global.control.alternate_transparent_background.visible = value < 1.0 Global.default_clear_color.a = value - alternate_transparent_background.color = Global.default_clear_color + Global.control.alternate_transparent_background.color = Global.default_clear_color Global.transparent_checker.transparency(value) diff --git a/src/UI/NotificationLabel.gd b/src/UI/NotificationLabel.gd index 746ea8c8e..d69a3b563 100644 --- a/src/UI/NotificationLabel.gd +++ b/src/UI/NotificationLabel.gd @@ -3,8 +3,24 @@ extends Label func _ready() -> void: var tween := $Tween - tween.interpolate_property(self, "rect_position", rect_position, Vector2(rect_position.x, rect_position.y - 100), 1, Tween.TRANS_LINEAR, Tween.EASE_OUT) - tween.interpolate_property(self, "modulate", modulate, Color(modulate.r, modulate.g, modulate.b, 0), 1, Tween.TRANS_LINEAR, Tween.EASE_OUT) + tween.interpolate_property( + self, + "rect_position", + rect_position, + Vector2(rect_position.x, rect_position.y - 100), + 1, + Tween.TRANS_LINEAR, + Tween.EASE_OUT + ) + tween.interpolate_property( + self, + "modulate", + modulate, + Color(modulate.r, modulate.g, modulate.b, 0), + 1, + Tween.TRANS_LINEAR, + Tween.EASE_OUT + ) tween.start() diff --git a/src/UI/PatternButton.gd b/src/UI/PatternButton.gd index f7f684d81..098a65258 100644 --- a/src/UI/PatternButton.gd +++ b/src/UI/PatternButton.gd @@ -1,6 +1,5 @@ extends BaseButton - var pattern = Global.patterns_popup.Pattern.new() diff --git a/src/UI/PatternsPopup.gd b/src/UI/PatternsPopup.gd index 6a612f5c0..9838a1c99 100644 --- a/src/UI/PatternsPopup.gd +++ b/src/UI/PatternsPopup.gd @@ -1,23 +1,23 @@ -extends PopupPanel class_name Patterns - - -class Pattern: - var image : Image - var index : int +extends PopupPanel signal pattern_selected(pattern) -var default_pattern : Pattern = null +var default_pattern: Pattern = null -func select_pattern(pattern : Pattern) -> void: +class Pattern: + var image: Image + var index: int + + +func select_pattern(pattern: Pattern) -> void: emit_signal("pattern_selected", pattern) hide() -static func create_button(image : Image) -> Node: - var button : BaseButton = preload("res://src/UI/PatternButton.tscn").instance() +static func create_button(image: Image) -> Node: + var button: BaseButton = preload("res://src/UI/PatternButton.tscn").instance() var tex := ImageTexture.new() tex.create_from_image(image, 0) button.get_child(0).texture = tex @@ -25,7 +25,7 @@ static func create_button(image : Image) -> Node: return button -static func add(image : Image, hint := "") -> void: +static func add(image: Image, hint := "") -> void: var button = create_button(image) button.pattern.image = image button.hint_tooltip = hint @@ -37,7 +37,7 @@ static func add(image : Image, hint := "") -> void: Global.patterns_popup.default_pattern = button.pattern -func get_pattern(index : int) -> Pattern: +func get_pattern(index: int) -> Pattern: var container = Global.patterns_popup.get_node("ScrollContainer/PatternContainer") var pattern = default_pattern if index < container.get_child_count(): diff --git a/src/UI/Tabs.gd b/src/UI/Tabs.gd index 308768b7e..70b61cb37 100644 --- a/src/UI/Tabs.gd +++ b/src/UI/Tabs.gd @@ -1,14 +1,15 @@ extends Tabs - -onready var unsaved_changes_dialog : ConfirmationDialog = Global.control.find_node("UnsavedCanvasDialog") +onready var unsaved_changes_dialog: ConfirmationDialog = Global.control.find_node( + "UnsavedCanvasDialog" +) -func _on_Tabs_tab_changed(tab : int) -> void: +func _on_Tabs_tab_changed(tab: int) -> void: Global.current_project_index = tab -func _on_Tabs_tab_close(tab : int) -> void: +func _on_Tabs_tab_close(tab: int) -> void: if Global.projects.size() == 1: return @@ -21,7 +22,7 @@ func _on_Tabs_tab_close(tab : int) -> void: delete_tab(tab) -func _on_Tabs_reposition_active_tab_request(idx_to : int) -> void: +func _on_Tabs_reposition_active_tab_request(idx_to: int) -> void: var temp = Global.projects[Global.current_project_index] Global.projects.erase(temp) Global.projects.insert(idx_to, temp) @@ -35,7 +36,7 @@ func _on_Tabs_reposition_active_tab_request(idx_to : int) -> void: OpenSave.backup_save_paths[idx_to] = temp_backup_path -func delete_tab(tab : int) -> void: +func delete_tab(tab: int) -> void: remove_tab(tab) Global.projects[tab].undo_redo.free() OpenSave.remove_backup(tab) diff --git a/src/UI/Timeline/AnimationTagUI.gd b/src/UI/Timeline/AnimationTagUI.gd index 2d18c047a..6736c881b 100644 --- a/src/UI/Timeline/AnimationTagUI.gd +++ b/src/UI/Timeline/AnimationTagUI.gd @@ -1,4 +1,3 @@ extends VBoxContainer - -var tag : AnimationTag +var tag: AnimationTag diff --git a/src/UI/Timeline/AnimationTimeline.gd b/src/UI/Timeline/AnimationTimeline.gd index 6e4445d13..2c7732120 100644 --- a/src/UI/Timeline/AnimationTimeline.gd +++ b/src/UI/Timeline/AnimationTimeline.gd @@ -1,8 +1,7 @@ extends Panel - var is_animation_running := false -var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop +var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop var animation_forward := true var first_frame := 0 var last_frame := 0 @@ -11,12 +10,12 @@ var cel_size := 36 setget cel_size_changed var min_cel_size := 36 var max_cel_size := 144 -var timeline_scroll : ScrollContainer -var tag_scroll_container : ScrollContainer -var fps_spinbox : SpinBox +var timeline_scroll: ScrollContainer +var tag_scroll_container: ScrollContainer +var fps_spinbox: SpinBox -onready var onion_skinning_button : BaseButton = find_node("OnionSkinning") -onready var loop_animation_button : BaseButton = find_node("LoopAnim") +onready var onion_skinning_button: BaseButton = find_node("OnionSkinning") +onready var loop_animation_button: BaseButton = find_node("LoopAnim") func _ready() -> void: @@ -28,21 +27,27 @@ func _ready() -> void: fps_spinbox.value = Global.current_project.fps -func _input(event : InputEvent) -> void: +func _input(event: InputEvent) -> void: var mouse_pos := get_global_mouse_position() var timeline_rect := Rect2(rect_global_position, rect_size) if timeline_rect.has_point(mouse_pos): if Input.is_key_pressed(KEY_CONTROL): - self.cel_size += (2 * int(event.is_action("zoom_in")) - 2 * int(event.is_action("zoom_out"))) + self.cel_size += ( + 2 * int(event.is_action("zoom_in")) + - 2 * int(event.is_action("zoom_out")) + ) -func _h_scroll_changed(value : float) -> void: +func _h_scroll_changed(value: float) -> void: # Let the main timeline ScrollContainer affect the tag ScrollContainer too - tag_scroll_container.get_child(0).rect_min_size.x = timeline_scroll.get_child(0).rect_size.x - 212 + tag_scroll_container.get_child(0).rect_min_size.x = ( + timeline_scroll.get_child(0).rect_size.x + - 212 + ) tag_scroll_container.scroll_horizontal = value -func cel_size_changed(value : int) -> void: +func cel_size_changed(value: int) -> void: cel_size = clamp(value, min_cel_size, max_cel_size) for layer_button in Global.layers_container.get_children(): layer_button.rect_min_size.y = cel_size @@ -60,28 +65,38 @@ func cel_size_changed(value : int) -> void: for tag_c in Global.tag_container.get_children(): var tag_base_size = cel_size + 4 - var tag : AnimationTag = tag_c.tag - tag_c.rect_position.x = (tag.from - 1) * tag_base_size + 1 # Added 1 to answer to get starting position of next cel - var tag_size : int = tag.to - tag.from - tag_c.rect_min_size.x = (tag_size + 1) * tag_base_size - 4 # We dont need the 4 pixels at the end of last cel - tag_c.rect_size.x = (tag_size + 1) * tag_base_size - 4 # We dont need the 4 pixels at the end of last cel + var tag: AnimationTag = tag_c.tag + # Added 1 to answer to get starting position of next cel + tag_c.rect_position.x = (tag.from - 1) * tag_base_size + 1 + var tag_size: int = tag.to - tag.from + # We dont need the 4 pixels at the end of last cel + tag_c.rect_min_size.x = (tag_size + 1) * tag_base_size - 4 + # We dont need the 4 pixels at the end of last cel + tag_c.rect_size.x = (tag_size + 1) * tag_base_size - 4 tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0) tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32) func add_frame() -> void: - var frame : Frame = Global.canvas.new_empty_frame() - var new_frames : Array = Global.current_project.frames.duplicate() - var new_layers : Array = Global.current_project.layers.duplicate() + var frame: Frame = Global.canvas.new_empty_frame() + var new_frames: Array = Global.current_project.frames.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() new_frames.insert(Global.current_project.current_frame + 1, frame) # Loop through the array to create new classes for each element, so that they # won't be the same as the original array's classes. Needed for undo/redo to work properly. for i in new_layers.size(): var new_linked_cels = new_layers[i].linked_cels.duplicate() - new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels) + new_layers[i] = Layer.new( + new_layers[i].name, + new_layers[i].visible, + new_layers[i].locked, + new_layers[i].frame_container, + new_layers[i].new_cels_linked, + new_linked_cels + ) for l_i in range(new_layers.size()): - if new_layers[l_i].new_cels_linked: # If the link button is pressed + if new_layers[l_i].new_cels_linked: # If the link button is pressed new_layers[l_i].linked_cels.append(frame) frame.cels[l_i].image = new_layers[l_i].linked_cels[0].cels[l_i].image frame.cels[l_i].image_texture = new_layers[l_i].linked_cels[0].cels[l_i].image_texture @@ -92,38 +107,55 @@ func add_frame() -> void: Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", Global.current_project.current_frame + 1) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", Global.current_project.current_frame + 1 + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame ) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "frames", Global.current_project.frames + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.commit_action() func _on_DeleteFrame_pressed(frame := -1) -> void: + delete_frame(frame) + + +func delete_frame(frame := -1) -> void: if Global.current_project.frames.size() == 1: return if frame == -1: frame = Global.current_project.current_frame - var frame_to_delete : Frame = Global.current_project.frames[frame] - var new_frames : Array = Global.current_project.frames.duplicate() + var frame_to_delete: Frame = Global.current_project.frames[frame] + var new_frames: Array = Global.current_project.frames.duplicate() new_frames.erase(frame_to_delete) var current_frame := Global.current_project.current_frame - if current_frame > 0 && current_frame == new_frames.size(): # If it's the last frame + if current_frame > 0 && current_frame == new_frames.size(): # If it's the last frame current_frame -= 1 var new_animation_tags := Global.current_project.animation_tags.duplicate() # Loop through the tags to create new classes for them, so that they won't be the same # as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly. for i in new_animation_tags.size(): - new_animation_tags[i] = AnimationTag.new(new_animation_tags[i].name, new_animation_tags[i].color, new_animation_tags[i].from, new_animation_tags[i].to) + new_animation_tags[i] = AnimationTag.new( + new_animation_tags[i].name, + new_animation_tags[i].color, + new_animation_tags[i].from, + new_animation_tags[i].to + ) # Loop through the tags to see if the frame is in one for tag in new_animation_tags: if frame + 1 >= tag.from && frame + 1 <= tag.to: - if tag.from == tag.to: # If we're deleting the only frame in the tag + if tag.from == tag.to: # If we're deleting the only frame in the tag new_animation_tags.erase(tag) else: tag.to -= 1 @@ -134,12 +166,19 @@ func _on_DeleteFrame_pressed(frame := -1) -> void: # Check if one of the cels of the frame is linked # if they are, unlink them too # this prevents removed cels being kept in linked memory - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() # Loop through the array to create new classes for each element, so that they # won't be the same as the original array's classes. Needed for undo/redo to work properly. for i in new_layers.size(): var new_linked_cels = new_layers[i].linked_cels.duplicate() - new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels) + new_layers[i] = Layer.new( + new_layers[i].name, + new_layers[i].visible, + new_layers[i].locked, + new_layers[i].frame_container, + new_layers[i].new_cels_linked, + new_linked_cels + ) for layer in new_layers: for linked in layer.linked_cels: @@ -150,14 +189,26 @@ func _on_DeleteFrame_pressed(frame := -1) -> void: Global.current_project.undo_redo.create_action("Remove Frame") Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", current_frame) - Global.current_project.undo_redo.add_do_property(Global.current_project, "animation_tags", new_animation_tags) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", current_frame + ) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "animation_tags", new_animation_tags + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "animation_tags", Global.current_project.animation_tags) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "frames", Global.current_project.frames + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "animation_tags", Global.current_project.animation_tags + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.add_do_method(Global, "redo") Global.current_project.undo_redo.add_undo_method(Global, "undo") @@ -165,16 +216,20 @@ func _on_DeleteFrame_pressed(frame := -1) -> void: func _on_CopyFrame_pressed(frame := -1) -> void: + copy_frame(frame) + + +func copy_frame(frame := -1) -> void: Global.canvas.selection.transform_content_confirm() if frame == -1: frame = Global.current_project.current_frame var new_frame := Frame.new() var new_frames := Global.current_project.frames.duplicate() - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() new_frames.insert(frame + 1, new_frame) - for cel in Global.current_project.frames[frame].cels: # Copy every cel + for cel in Global.current_project.frames[frame].cels: # Copy every cel var sprite := Image.new() sprite.copy_from(cel.image) var sprite_texture := ImageTexture.new() @@ -185,10 +240,17 @@ func _on_CopyFrame_pressed(frame := -1) -> void: # won't be the same as the original array's classes. Needed for undo/redo to work properly. for i in new_layers.size(): var new_linked_cels = new_layers[i].linked_cels.duplicate() - new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels) + new_layers[i] = Layer.new( + new_layers[i].name, + new_layers[i].visible, + new_layers[i].locked, + new_layers[i].frame_container, + new_layers[i].new_cels_linked, + new_linked_cels + ) for l_i in range(new_layers.size()): - if new_layers[l_i].new_cels_linked: # If the link button is pressed + if new_layers[l_i].new_cels_linked: # If the link button is pressed new_layers[l_i].linked_cels.append(new_frame) new_frame.cels[l_i].image = new_layers[l_i].linked_cels[0].cels[l_i].image new_frame.cels[l_i].image_texture = new_layers[l_i].linked_cels[0].cels[l_i].image_texture @@ -197,7 +259,12 @@ func _on_CopyFrame_pressed(frame := -1) -> void: # Loop through the tags to create new classes for them, so that they won't be the same # as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly. for i in new_animation_tags.size(): - new_animation_tags[i] = AnimationTag.new(new_animation_tags[i].name, new_animation_tags[i].color, new_animation_tags[i].from, new_animation_tags[i].to) + new_animation_tags[i] = AnimationTag.new( + new_animation_tags[i].name, + new_animation_tags[i].color, + new_animation_tags[i].from, + new_animation_tags[i].to + ) # Loop through the tags to see if the frame is in one for tag in new_animation_tags: @@ -210,14 +277,26 @@ func _on_CopyFrame_pressed(frame := -1) -> void: Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", frame + 1) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", frame + 1 + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_do_property(Global.current_project, "animation_tags", new_animation_tags) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "animation_tags", new_animation_tags + ) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", frame) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "animation_tags", Global.current_project.animation_tags) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "frames", Global.current_project.frames + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_frame", frame + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "animation_tags", Global.current_project.animation_tags + ) Global.current_project.undo_redo.commit_action() @@ -226,14 +305,14 @@ func _on_FrameTagButton_pressed() -> void: func _on_MoveLeft_pressed() -> void: - var frame : int = Global.current_project.current_frame + var frame: int = Global.current_project.current_frame if frame == 0: return Global.frame_ids.get_child(frame).change_frame_order(-1) func _on_MoveRight_pressed() -> void: - var frame : int = Global.current_project.current_frame + var frame: int = Global.current_project.current_frame if frame == last_frame: return Global.frame_ids.get_child(frame).change_frame_order(1) @@ -242,7 +321,7 @@ func _on_MoveRight_pressed() -> void: func _on_OnionSkinning_pressed() -> void: Global.onion_skinning = !Global.onion_skinning Global.canvas.update() - var texture_button : TextureRect = onion_skinning_button.get_child(0) + var texture_button: TextureRect = onion_skinning_button.get_child(0) if Global.onion_skinning: Global.change_button_texturerect(texture_button, "onion_skinning.png") else: @@ -250,27 +329,34 @@ func _on_OnionSkinning_pressed() -> void: func _on_OnionSkinningSettings_pressed() -> void: - $OnionSkinningSettings.popup(Rect2(onion_skinning_button.rect_global_position.x - $OnionSkinningSettings.rect_size.x - 16, onion_skinning_button.rect_global_position.y - 106, 136, 126)) + $OnionSkinningSettings.popup( + Rect2( + onion_skinning_button.rect_global_position.x - $OnionSkinningSettings.rect_size.x - 16, + onion_skinning_button.rect_global_position.y - 106, + 136, + 126 + ) + ) func _on_LoopAnim_pressed() -> void: - var texture_button : TextureRect = loop_animation_button.get_child(0) + var texture_button: TextureRect = loop_animation_button.get_child(0) match animation_loop: - 0: # Make it loop + 0: # Make it loop animation_loop = 1 Global.change_button_texturerect(texture_button, "loop.png") loop_animation_button.hint_tooltip = "Cycle loop" - 1: # Make it ping-pong + 1: # Make it ping-pong animation_loop = 2 Global.change_button_texturerect(texture_button, "loop_pingpong.png") loop_animation_button.hint_tooltip = "Ping-pong loop" - 2: # Make it stop + 2: # Make it stop animation_loop = 0 Global.change_button_texturerect(texture_button, "loop_none.png") loop_animation_button.hint_tooltip = "No loop" -func _on_PlayForward_toggled(button_pressed : bool) -> void: +func _on_PlayForward_toggled(button_pressed: bool) -> void: if button_pressed: Global.change_button_texturerect(Global.play_forward.get_child(0), "pause.png") else: @@ -279,7 +365,7 @@ func _on_PlayForward_toggled(button_pressed : bool) -> void: play_animation(button_pressed, true) -func _on_PlayBackwards_toggled(button_pressed : bool) -> void: +func _on_PlayBackwards_toggled(button_pressed: bool) -> void: if button_pressed: Global.change_button_texturerect(Global.play_backwards.get_child(0), "pause.png") else: @@ -299,21 +385,27 @@ func _on_AnimationTimer_timeout() -> void: if Global.current_project.current_frame < last_frame: Global.current_project.selected_cels.clear() Global.current_project.current_frame += 1 - Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) - Global.animation_timer.start() # Change the frame, change the wait time and start a cycle, this is the best way to do it + Global.animation_timer.wait_time = ( + Global.current_project.frames[Global.current_project.current_frame].duration + * (1 / fps) + ) + Global.animation_timer.start() # Change the frame, change the wait time and start a cycle else: match animation_loop: - 0: # No loop + 0: # No loop Global.play_forward.pressed = false Global.play_backwards.pressed = false Global.animation_timer.stop() is_animation_running = false - 1: # Cycle loop + 1: # Cycle loop Global.current_project.selected_cels.clear() Global.current_project.current_frame = first_frame - Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) + Global.animation_timer.wait_time = ( + Global.current_project.frames[Global.current_project.current_frame].duration + * (1 / fps) + ) Global.animation_timer.start() - 2: # Ping pong loop + 2: # Ping pong loop animation_forward = false _on_AnimationTimer_timeout() @@ -321,31 +413,40 @@ func _on_AnimationTimer_timeout() -> void: if Global.current_project.current_frame > first_frame: Global.current_project.selected_cels.clear() Global.current_project.current_frame -= 1 - Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) + Global.animation_timer.wait_time = ( + Global.current_project.frames[Global.current_project.current_frame].duration + * (1 / fps) + ) Global.animation_timer.start() else: match animation_loop: - 0: # No loop + 0: # No loop Global.play_backwards.pressed = false Global.play_forward.pressed = false Global.animation_timer.stop() is_animation_running = false - 1: # Cycle loop + 1: # Cycle loop Global.current_project.selected_cels.clear() Global.current_project.current_frame = last_frame - Global.animation_timer.wait_time = Global.current_project.frames[Global.current_project.current_frame].duration * (1/fps) + Global.animation_timer.wait_time = ( + Global.current_project.frames[Global.current_project.current_frame].duration + * (1 / fps) + ) Global.animation_timer.start() - 2: # Ping pong loop + 2: # Ping pong loop animation_forward = true _on_AnimationTimer_timeout() -func play_animation(play : bool, forward_dir : bool) -> void: +func play_animation(play: bool, forward_dir: bool) -> void: first_frame = 0 last_frame = Global.current_project.frames.size() - 1 if Global.play_only_tags: for tag in Global.current_project.animation_tags: - if Global.current_project.current_frame + 1 >= tag.from && Global.current_project.current_frame + 1 <= tag.to: + if ( + Global.current_project.current_frame + 1 >= tag.from + && Global.current_project.current_frame + 1 <= tag.to + ): first_frame = tag.from - 1 last_frame = min(Global.current_project.frames.size() - 1, tag.to - 1) @@ -368,8 +469,8 @@ func play_animation(play : bool, forward_dir : bool) -> void: Global.play_forward.connect("toggled", self, "_on_PlayForward_toggled") if play: - Global.animation_timer.set_one_shot(true) # The wait_time can't change correctly if it is playing - var duration : float = Global.current_project.frames[Global.current_project.current_frame].duration + Global.animation_timer.set_one_shot(true) # wait_time can't change correctly if it's playing + var duration: float = Global.current_project.frames[Global.current_project.current_frame].duration var fps = Global.current_project.fps Global.animation_timer.wait_time = duration * (1 / fps) Global.animation_timer.start() @@ -406,34 +507,40 @@ func _on_FirstFrame_pressed() -> void: Global.current_project.current_frame = 0 -func _on_FPSValue_value_changed(value : float) -> void: +func _on_FPSValue_value_changed(value: float) -> void: Global.current_project.fps = float(value) Global.animation_timer.wait_time = 1 / Global.current_project.fps -func _on_PastOnionSkinning_value_changed(value : float) -> void: +func _on_PastOnionSkinning_value_changed(value: float) -> void: Global.onion_skinning_past_rate = int(value) Global.canvas.update() -func _on_FutureOnionSkinning_value_changed(value : float) -> void: +func _on_FutureOnionSkinning_value_changed(value: float) -> void: Global.onion_skinning_future_rate = int(value) Global.canvas.update() -func _on_BlueRedMode_toggled(button_pressed : bool) -> void: +func _on_BlueRedMode_toggled(button_pressed: bool) -> void: Global.onion_skinning_blue_red = button_pressed Global.canvas.update() # Layer buttons + func add_layer(is_new := true) -> void: Global.canvas.selection.transform_content_confirm() - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() var l := Layer.new() - if !is_new: # Clone layer - l.name = Global.current_project.layers[Global.current_project.current_layer].name + " (" + tr("copy") + ")" + if !is_new: # Clone layer + l.name = ( + Global.current_project.layers[Global.current_project.current_layer].name + + " (" + + tr("copy") + + ")" + ) new_layers.append(l) Global.current_project.undos += 1 @@ -442,19 +549,30 @@ func add_layer(is_new := true) -> void: for f in Global.current_project.frames: var new_layer := Image.new() if is_new: - new_layer.create(Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_RGBA8) - else: # Clone layer + new_layer.create( + Global.current_project.size.x, + Global.current_project.size.y, + false, + Image.FORMAT_RGBA8 + ) + else: # Clone layer new_layer.copy_from(f.cels[Global.current_project.current_layer].image) - var new_cels : Array = f.cels.duplicate() + var new_cels: Array = f.cels.duplicate() new_cels.append(Cel.new(new_layer, 1)) Global.current_project.undo_redo.add_do_property(f, "cels", new_cels) Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", Global.current_project.layers.size()) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_layer", Global.current_project.layers.size() + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") @@ -464,49 +582,63 @@ func add_layer(is_new := true) -> void: func _on_RemoveLayer_pressed() -> void: if Global.current_project.layers.size() == 1: return - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() new_layers.remove(Global.current_project.current_layer) Global.current_project.undos += 1 Global.current_project.undo_redo.create_action("Remove Layer") if Global.current_project.current_layer > 0: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", Global.current_project.current_layer - 1) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_layer", Global.current_project.current_layer - 1 + ) else: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", Global.current_project.current_layer) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) for f in Global.current_project.frames: - var new_cels : Array = f.cels.duplicate() + var new_cels: Array = f.cels.duplicate() new_cels.remove(Global.current_project.current_layer) Global.current_project.undo_redo.add_do_property(f, "cels", new_cels) Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.add_do_method(Global, "redo") Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.commit_action() -func change_layer_order(rate : int) -> void: +func change_layer_order(rate: int) -> void: var change = Global.current_project.current_layer + rate - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() var temp = new_layers[Global.current_project.current_layer] new_layers[Global.current_project.current_layer] = new_layers[change] new_layers[change] = temp Global.current_project.undo_redo.create_action("Change Layer Order") for f in Global.current_project.frames: - var new_cels : Array = f.cels.duplicate() + var new_cels: Array = f.cels.duplicate() var temp_canvas = new_cels[Global.current_project.current_layer] new_cels[Global.current_project.current_layer] = new_cels[change] new_cels[change] = temp_canvas Global.current_project.undo_redo.add_do_property(f, "cels", new_cels) Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", change) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_layer", change + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") @@ -514,50 +646,89 @@ func change_layer_order(rate : int) -> void: func _on_MergeDownLayer_pressed() -> void: - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() # Loop through the array to create new classes for each element, so that they # won't be the same as the original array's classes. Needed for undo/redo to work properly. for i in new_layers.size(): var new_linked_cels = new_layers[i].linked_cels.duplicate() - new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels) + new_layers[i] = Layer.new( + new_layers[i].name, + new_layers[i].visible, + new_layers[i].locked, + new_layers[i].frame_container, + new_layers[i].new_cels_linked, + new_linked_cels + ) Global.current_project.undos += 1 Global.current_project.undo_redo.create_action("Merge Layer") for f in Global.current_project.frames: - var new_cels : Array = f.cels.duplicate() + var new_cels: Array = f.cels.duplicate() for i in new_cels.size(): new_cels[i] = Cel.new(new_cels[i].image, new_cels[i].opacity) var selected_layer := Image.new() selected_layer.copy_from(new_cels[Global.current_project.current_layer].image) selected_layer.lock() - if f.cels[Global.current_project.current_layer].opacity < 1: # If we have layer transparency + if f.cels[Global.current_project.current_layer].opacity < 1: # If we have layer transparency for xx in selected_layer.get_size().x: for yy in selected_layer.get_size().y: - var pixel_color : Color = selected_layer.get_pixel(xx, yy) - var alpha : float = pixel_color.a * f.cels[Global.current_project.current_layer].opacity - selected_layer.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha)) + var pixel_color: Color = selected_layer.get_pixel(xx, yy) + var alpha: float = ( + pixel_color.a + * f.cels[Global.current_project.current_layer].opacity + ) + selected_layer.set_pixel( + xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha) + ) selected_layer.unlock() var new_layer := Image.new() new_layer.copy_from(f.cels[Global.current_project.current_layer - 1].image) - new_layer.blend_rect(selected_layer, Rect2(Vector2.ZERO, Global.current_project.size), Vector2.ZERO) + new_layer.blend_rect( + selected_layer, Rect2(Vector2.ZERO, Global.current_project.size), Vector2.ZERO + ) new_cels.remove(Global.current_project.current_layer) - if !selected_layer.is_invisible() and Global.current_project.layers[Global.current_project.current_layer - 1].linked_cels.size() > 1 and (f in Global.current_project.layers[Global.current_project.current_layer - 1].linked_cels): + if ( + !selected_layer.is_invisible() + and ( + Global.current_project.layers[Global.current_project.current_layer - 1].linked_cels.size() + > 1 + ) + and ( + f + in Global.current_project.layers[( + Global.current_project.current_layer + - 1 + )].linked_cels + ) + ): new_layers[Global.current_project.current_layer - 1].linked_cels.erase(f) new_cels[Global.current_project.current_layer - 1].image = new_layer else: - Global.current_project.undo_redo.add_do_property(f.cels[Global.current_project.current_layer - 1].image, "data", new_layer.data) - Global.current_project.undo_redo.add_undo_property(f.cels[Global.current_project.current_layer - 1].image, "data", f.cels[Global.current_project.current_layer - 1].image.data) + Global.current_project.undo_redo.add_do_property( + f.cels[Global.current_project.current_layer - 1].image, "data", new_layer.data + ) + Global.current_project.undo_redo.add_undo_property( + f.cels[Global.current_project.current_layer - 1].image, + "data", + f.cels[Global.current_project.current_layer - 1].image.data + ) Global.current_project.undo_redo.add_do_property(f, "cels", new_cels) Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) new_layers.remove(Global.current_project.current_layer) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", Global.current_project.current_layer - 1) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_layer", Global.current_project.current_layer - 1 + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") @@ -565,7 +736,8 @@ func _on_MergeDownLayer_pressed() -> void: func _on_OpacitySlider_value_changed(value) -> void: - var cel : Cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer] + var current_frame: Frame = Global.current_project.frames[Global.current_project.current_frame] + var cel: Cel = current_frame.cels[Global.current_project.current_layer] cel.opacity = value / 100 Global.layer_opacity_slider.value = value Global.layer_opacity_spinbox.value = value diff --git a/src/UI/Timeline/AnimationTimeline.tscn b/src/UI/Timeline/AnimationTimeline.tscn index cd79cc2bc..ea4b07ac6 100644 --- a/src/UI/Timeline/AnimationTimeline.tscn +++ b/src/UI/Timeline/AnimationTimeline.tscn @@ -504,7 +504,8 @@ margin_top = 2.0 margin_right = 20.0 margin_bottom = 22.0 rect_min_size = Vector2( 20, 0 ) -hint_tooltip = "FIRSTFRAME_HT" +hint_tooltip = "Jump to the first frame +(%s)" focus_mode = 0 mouse_default_cursor_shape = 2 size_flags_vertical = 4 @@ -531,7 +532,8 @@ margin_top = 2.0 margin_right = 44.0 margin_bottom = 22.0 rect_min_size = Vector2( 20, 0 ) -hint_tooltip = "PREVIOUSFRAME_HT" +hint_tooltip = "Go to the previous frame +(%s)" focus_mode = 0 mouse_default_cursor_shape = 2 size_flags_vertical = 4 @@ -558,7 +560,8 @@ margin_top = 2.0 margin_right = 68.0 margin_bottom = 22.0 rect_min_size = Vector2( 20, 0 ) -hint_tooltip = "PLAYBACKWARDS_HT" +hint_tooltip = "Play the animation backwards (from end to beginning) +(%s)" focus_mode = 0 mouse_default_cursor_shape = 2 size_flags_vertical = 4 @@ -586,7 +589,8 @@ margin_top = 2.0 margin_right = 92.0 margin_bottom = 22.0 rect_min_size = Vector2( 20, 0 ) -hint_tooltip = "PLAYFORWARD_HT" +hint_tooltip = "Play the animation forward (from beginning to end) +(%s)" focus_mode = 0 mouse_default_cursor_shape = 2 size_flags_horizontal = 0 @@ -615,7 +619,8 @@ margin_top = 2.0 margin_right = 116.0 margin_bottom = 22.0 rect_min_size = Vector2( 20, 0 ) -hint_tooltip = "NEXTFRAME_HT" +hint_tooltip = "Go to the next frame +(%s)" focus_mode = 0 mouse_default_cursor_shape = 2 size_flags_vertical = 4 @@ -642,7 +647,8 @@ margin_top = 2.0 margin_right = 140.0 margin_bottom = 22.0 rect_min_size = Vector2( 20, 0 ) -hint_tooltip = "LASTFRAME_HT" +hint_tooltip = "Jump to the last frame +(%s)" focus_mode = 0 mouse_default_cursor_shape = 2 size_flags_vertical = 4 diff --git a/src/UI/Timeline/CelButton.gd b/src/UI/Timeline/CelButton.gd index d86f7a293..ef192f877 100644 --- a/src/UI/Timeline/CelButton.gd +++ b/src/UI/Timeline/CelButton.gd @@ -1,17 +1,20 @@ extends Button -enum MenuOptions {DELETE, LINK, PROPERTIES} - +enum MenuOptions { DELETE, LINK, PROPERTIES } var frame := 0 var layer := 0 -var cel : Cel -var image : Image +var cel: Cel +var image: Image -onready var popup_menu : PopupMenu = $PopupMenu +onready var popup_menu: PopupMenu = $PopupMenu func _ready() -> void: + button_setup() + + +func button_setup() -> void: rect_min_size.x = Global.animation_timeline.cel_size rect_min_size.y = Global.animation_timeline.cel_size @@ -47,8 +50,8 @@ func _on_CelButton_pressed() -> void: if Input.is_action_just_released("left_mouse"): Global.canvas.selection.transform_content_confirm() var change_cel := true - var prev_curr_frame : int = project.current_frame - var prev_curr_layer : int = project.current_layer + var prev_curr_frame: int = project.current_frame + var prev_curr_layer: int = project.current_layer if Input.is_action_pressed("shift"): var frame_diff_sign = sign(frame - prev_curr_frame) @@ -70,7 +73,7 @@ func _on_CelButton_pressed() -> void: change_cel = false else: project.selected_cels.append(frame_layer) - else: # If the button is pressed without Shift or Control + else: # If the button is pressed without Shift or Control project.selected_cels.clear() var frame_layer := [frame, layer] if !project.selected_cels.has(frame_layer): @@ -90,27 +93,36 @@ func _on_CelButton_pressed() -> void: elif Input.is_action_just_released("middle_mouse"): pressed = !pressed delete_cel_contents() - else: # An example of this would be Space + else: # An example of this would be Space pressed = !pressed -func _on_PopupMenu_id_pressed(ID : int) -> void: - match ID: +func _on_PopupMenu_id_pressed(id: int) -> void: + match id: MenuOptions.DELETE: delete_cel_contents() MenuOptions.LINK: - var f : Frame = Global.current_project.frames[frame] - var cel_index : int = Global.current_project.layers[layer].linked_cels.find(f) - var new_layers : Array = Global.current_project.layers.duplicate() + var f: Frame = Global.current_project.frames[frame] + var cel_index: int = Global.current_project.layers[layer].linked_cels.find(f) + var new_layers: Array = Global.current_project.layers.duplicate() # Loop through the array to create new classes for each element, so that they # won't be the same as the original array's classes. Needed for undo/redo to work properly. for i in new_layers.size(): - var new_linked_cels : Array = new_layers[i].linked_cels.duplicate() - new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels) - var new_cels : Array = f.cels.duplicate() + var new_linked_cels: Array = new_layers[i].linked_cels.duplicate() + new_layers[i] = Layer.new( + new_layers[i].name, + new_layers[i].visible, + new_layers[i].locked, + new_layers[i].frame_container, + new_layers[i].new_cels_linked, + new_linked_cels + ) + var new_cels: Array = f.cels.duplicate() for i in new_cels.size(): - new_cels[i] = Cel.new(new_cels[i].image, new_cels[i].opacity, new_cels[i].image_texture) + new_cels[i] = Cel.new( + new_cels[i].image, new_cels[i].opacity, new_cels[i].image_texture + ) if popup_menu.get_item_metadata(MenuOptions.LINK) == "Unlink Cel": new_layers[layer].linked_cels.remove(cel_index) @@ -122,9 +134,13 @@ func _on_PopupMenu_id_pressed(ID : int) -> void: new_cels[layer].image_texture = sprite_texture Global.current_project.undo_redo.create_action("Unlink Cel") - Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "layers", new_layers + ) Global.current_project.undo_redo.add_do_property(f, "cels", new_cels) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) Global.current_project.undo_redo.add_undo_method(Global, "undo") @@ -134,7 +150,9 @@ func _on_PopupMenu_id_pressed(ID : int) -> void: elif popup_menu.get_item_metadata(MenuOptions.LINK) == "Link Cel": new_layers[layer].linked_cels.append(f) Global.current_project.undo_redo.create_action("Link Cel") - Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "layers", new_layers + ) if new_layers[layer].linked_cels.size() > 1: # If there are already linked cels, set the current cel's image # to the first linked cel's image @@ -143,7 +161,9 @@ func _on_PopupMenu_id_pressed(ID : int) -> void: Global.current_project.undo_redo.add_do_property(f, "cels", new_cels) Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") Global.current_project.undo_redo.commit_action() @@ -176,7 +196,13 @@ func can_drop_data(_pos, data) -> bool: if typeof(data) == TYPE_ARRAY and data[0] == "Cel": var new_frame = data[1] var new_layer = data[2] - if Global.current_project.frames[frame] in Global.current_project.layers[layer].linked_cels or Global.current_project.frames[new_frame] in Global.current_project.layers[new_layer].linked_cels: + if ( + Global.current_project.frames[frame] in Global.current_project.layers[layer].linked_cels + or ( + Global.current_project.frames[new_frame] + in Global.current_project.layers[new_layer].linked_cels + ) + ): # If the cel we're dragging or the cel we are targeting are linked, don't allow dragging return false else: @@ -202,20 +228,36 @@ func drop_data(_pos, data) -> void: new_frame_new_cels[new_layer] = temp Global.current_project.undo_redo.create_action("Move Cels") - Global.current_project.undo_redo.add_do_property(Global.current_project.frames[frame], "cels", this_frame_new_cels) + Global.current_project.undo_redo.add_do_property( + Global.current_project.frames[frame], "cels", this_frame_new_cels + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", layer) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) - if frame != new_frame: # If the cel moved to a different frame - Global.current_project.undo_redo.add_do_property(Global.current_project.frames[new_frame], "cels", new_frame_new_cels) + if frame != new_frame: # If the cel moved to a different frame + Global.current_project.undo_redo.add_do_property( + Global.current_project.frames[new_frame], "cels", new_frame_new_cels + ) - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", frame) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", frame + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) - Global.current_project.undo_redo.add_undo_property(Global.current_project.frames[new_frame], "cels", Global.current_project.frames[new_frame].cels) + Global.current_project.undo_redo.add_undo_property( + Global.current_project.frames[new_frame], + "cels", + Global.current_project.frames[new_frame].cels + ) - Global.current_project.undo_redo.add_undo_property(Global.current_project.frames[frame], "cels", Global.current_project.frames[frame].cels) + Global.current_project.undo_redo.add_undo_property( + Global.current_project.frames[frame], "cels", Global.current_project.frames[frame].cels + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") diff --git a/src/UI/Timeline/FrameButton.gd b/src/UI/Timeline/FrameButton.gd index 010573306..8a978b28d 100644 --- a/src/UI/Timeline/FrameButton.gd +++ b/src/UI/Timeline/FrameButton.gd @@ -1,10 +1,9 @@ extends Button - var frame := 0 -onready var popup_menu : PopupMenu = $PopupMenu -onready var frame_properties : ConfirmationDialog = Global.control.find_node("FrameProperties") +onready var popup_menu: PopupMenu = $PopupMenu +onready var frame_properties: ConfirmationDialog = Global.control.find_node("FrameProperties") func _ready() -> void: @@ -14,7 +13,7 @@ func _ready() -> void: func _button_pressed() -> void: if Input.is_action_just_released("left_mouse"): Global.canvas.selection.transform_content_confirm() - var prev_curr_frame : int = Global.current_project.current_frame + var prev_curr_frame: int = Global.current_project.current_frame if Input.is_action_pressed("shift"): var frame_diff_sign = sign(frame - prev_curr_frame) if frame_diff_sign == 0: @@ -29,7 +28,7 @@ func _button_pressed() -> void: var frame_layer := [frame, j] if !Global.current_project.selected_cels.has(frame_layer): Global.current_project.selected_cels.append(frame_layer) - else: # If the button is pressed without Shift or Control + else: # If the button is pressed without Shift or Control Global.current_project.selected_cels.clear() var frame_layer := [frame, Global.current_project.current_layer] if !Global.current_project.selected_cels.has(frame_layer): @@ -52,45 +51,53 @@ func _button_pressed() -> void: pressed = !pressed elif Input.is_action_just_released("middle_mouse"): pressed = !pressed - Global.animation_timeline._on_DeleteFrame_pressed(frame) - else: # An example of this would be Space + Global.animation_timeline.delete_frame(frame) + else: # An example of this would be Space pressed = !pressed -func _on_PopupMenu_id_pressed(id : int) -> void: +func _on_PopupMenu_id_pressed(id: int) -> void: match id: - 0: # Remove Frame - Global.animation_timeline._on_DeleteFrame_pressed(frame) - 1: # Clone Frame - Global.animation_timeline._on_CopyFrame_pressed(frame) - 2: # Move Left + 0: # Remove Frame + Global.animation_timeline.delete_frame(frame) + 1: # Clone Frame + Global.animation_timeline.copy_frame(frame) + 2: # Move Left change_frame_order(-1) - 3: # Move Right + 3: # Move Right change_frame_order(1) - 4: # Frame Properties + 4: # Frame Properties frame_properties.popup_centered() Global.dialog_open(true) frame_properties.set_frame_label(frame) frame_properties.set_frame_dur(Global.current_project.frames[frame].duration) -func change_frame_order(rate : int) -> void: +func change_frame_order(rate: int) -> void: var change = frame + rate - var new_frames : Array = Global.current_project.frames.duplicate() + var new_frames: Array = Global.current_project.frames.duplicate() var temp = new_frames[frame] new_frames[frame] = new_frames[change] new_frames[change] = temp Global.current_project.undo_redo.create_action("Change Frame Order") Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "frames", Global.current_project.frames + ) if Global.current_project.current_frame == frame: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", change) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", change + ) else: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", Global.current_project.current_frame) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") @@ -119,22 +126,29 @@ func drop_data(_pos, data) -> void: if frame == new_frame: return - var new_frames : Array = Global.current_project.frames.duplicate() + var new_frames: Array = Global.current_project.frames.duplicate() var temp = new_frames[frame] new_frames[frame] = new_frames[new_frame] new_frames[new_frame] = temp Global.current_project.undo_redo.create_action("Change Frame Order") Global.current_project.undo_redo.add_do_property(Global.current_project, "frames", new_frames) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "frames", Global.current_project.frames) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "frames", Global.current_project.frames + ) if Global.current_project.current_frame == new_frame: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", frame) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", frame + ) else: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", Global.current_project.current_frame) - - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_frame", Global.current_project.current_frame + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") diff --git a/src/UI/Timeline/FrameProperties.gd b/src/UI/Timeline/FrameProperties.gd index a9c456d72..225dfae50 100644 --- a/src/UI/Timeline/FrameProperties.gd +++ b/src/UI/Timeline/FrameProperties.gd @@ -3,26 +3,36 @@ extends ConfirmationDialog onready var frame_num = $VBoxContainer/GridContainer/FrameNum onready var frame_dur = $VBoxContainer/GridContainer/FrameTime -func set_frame_label(frame : int) -> void: + +func set_frame_label(frame: int) -> void: frame_num.set_text(str(frame + 1)) -func set_frame_dur(duration : float) -> void: + +func set_frame_dur(duration: float) -> void: frame_dur.set_value(duration) + func _on_FrameProperties_popup_hide() -> void: Global.dialog_open(false) + func _on_FrameProperties_confirmed(): - var frame : int = int(frame_num.get_text()) - 1 - var duration : float = frame_dur.get_value() + var frame: int = int(frame_num.get_text()) - 1 + var duration: float = frame_dur.get_value() var new_duration = Global.current_project.frames[frame].duration new_duration = duration Global.current_project.undos += 1 Global.current_project.undo_redo.create_action("Change frame duration") - Global.current_project.undo_redo.add_do_property(Global.current_project.frames[frame], "duration", new_duration) - Global.current_project.undo_redo.add_undo_property(Global.current_project.frames[frame], "duration", Global.current_project.frames[frame].duration) + Global.current_project.undo_redo.add_do_property( + Global.current_project.frames[frame], "duration", new_duration + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project.frames[frame], + "duration", + Global.current_project.frames[frame].duration + ) Global.current_project.undo_redo.add_do_method(Global, "redo") Global.current_project.undo_redo.add_undo_method(Global, "undo") diff --git a/src/UI/Timeline/FrameTagDialog.gd b/src/UI/Timeline/FrameTagDialog.gd index 4f0b8dce9..cf8797ee4 100644 --- a/src/UI/Timeline/FrameTagDialog.gd +++ b/src/UI/Timeline/FrameTagDialog.gd @@ -1,12 +1,11 @@ extends AcceptDialog - var current_tag_id := 0 var tag_vboxes := [] -var delete_tag_button : Button +var delete_tag_button: Button -onready var main_vbox_cont : VBoxContainer = $VBoxContainer/ScrollContainer/VBoxTagContainer -onready var add_tag_button : Button = $VBoxContainer/ScrollContainer/VBoxTagContainer/AddTag +onready var main_vbox_cont: VBoxContainer = $VBoxContainer/ScrollContainer/VBoxTagContainer +onready var add_tag_button: Button = $VBoxContainer/ScrollContainer/VBoxTagContainer/AddTag onready var options_dialog = $TagOptions @@ -63,18 +62,27 @@ func _on_FrameTagDialog_popup_hide() -> void: func _on_AddTag_pressed() -> void: options_dialog.popup_centered() current_tag_id = Global.current_project.animation_tags.size() - options_dialog.get_node("GridContainer/FromSpinBox").value = Global.current_project.current_frame + 1 - options_dialog.get_node("GridContainer/ToSpinBox").value = Global.current_project.current_frame + 1 - options_dialog.get_node("GridContainer/ColorPickerButton").color = Color(randf(),randf(),randf()) + options_dialog.get_node("GridContainer/FromSpinBox").value = ( + Global.current_project.current_frame + + 1 + ) + options_dialog.get_node("GridContainer/ToSpinBox").value = ( + Global.current_project.current_frame + + 1 + ) + options_dialog.get_node("GridContainer/ColorPickerButton").color = Color( + randf(), randf(), randf() + ) -func _on_EditButton_pressed(_tag_id : int) -> void: +func _on_EditButton_pressed(_tag_id: int) -> void: options_dialog.popup_centered() current_tag_id = _tag_id - options_dialog.get_node("GridContainer/NameLineEdit").text = Global.current_project.animation_tags[_tag_id].name - options_dialog.get_node("GridContainer/ColorPickerButton").color = Global.current_project.animation_tags[_tag_id].color - options_dialog.get_node("GridContainer/FromSpinBox").value = Global.current_project.animation_tags[_tag_id].from - options_dialog.get_node("GridContainer/ToSpinBox").value = Global.current_project.animation_tags[_tag_id].to + var animation_tag: AnimationTag = Global.current_project.animation_tags[_tag_id] + options_dialog.get_node("GridContainer/NameLineEdit").text = animation_tag.name + options_dialog.get_node("GridContainer/ColorPickerButton").color = animation_tag.color + options_dialog.get_node("GridContainer/FromSpinBox").value = animation_tag.from + options_dialog.get_node("GridContainer/ToSpinBox").value = animation_tag.to if !delete_tag_button: delete_tag_button = options_dialog.add_button("Delete", true, "delete_tag") else: @@ -82,10 +90,10 @@ func _on_EditButton_pressed(_tag_id : int) -> void: func _on_TagOptions_confirmed() -> void: - var tag_name : String = options_dialog.get_node("GridContainer/NameLineEdit").text - var tag_color : Color = options_dialog.get_node("GridContainer/ColorPickerButton").color - var tag_from : int = options_dialog.get_node("GridContainer/FromSpinBox").value - var tag_to : int = options_dialog.get_node("GridContainer/ToSpinBox").value + var tag_name: String = options_dialog.get_node("GridContainer/NameLineEdit").text + var tag_color: Color = options_dialog.get_node("GridContainer/ColorPickerButton").color + var tag_from: int = options_dialog.get_node("GridContainer/FromSpinBox").value + var tag_to: int = options_dialog.get_node("GridContainer/ToSpinBox").value if tag_to > Global.current_project.frames.size(): tag_to = Global.current_project.frames.size() @@ -97,7 +105,12 @@ func _on_TagOptions_confirmed() -> void: # Loop through the tags to create new classes for them, so that they won't be the same # as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly. for i in new_animation_tags.size(): - new_animation_tags[i] = AnimationTag.new(new_animation_tags[i].name, new_animation_tags[i].color, new_animation_tags[i].from, new_animation_tags[i].to) + new_animation_tags[i] = AnimationTag.new( + new_animation_tags[i].name, + new_animation_tags[i].color, + new_animation_tags[i].from, + new_animation_tags[i].to + ) if current_tag_id == Global.current_project.animation_tags.size(): new_animation_tags.append(AnimationTag.new(tag_name, tag_color, tag_from, tag_to)) @@ -112,13 +125,17 @@ func _on_TagOptions_confirmed() -> void: Global.current_project.undo_redo.create_action("Modify Frame Tag") Global.current_project.undo_redo.add_do_method(Global, "general_redo") Global.current_project.undo_redo.add_undo_method(Global, "general_undo") - Global.current_project.undo_redo.add_do_property(Global.current_project, "animation_tags", new_animation_tags) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "animation_tags", Global.current_project.animation_tags) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "animation_tags", new_animation_tags + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "animation_tags", Global.current_project.animation_tags + ) Global.current_project.undo_redo.commit_action() _on_FrameTagDialog_about_to_show() -func _on_TagOptions_custom_action(action : String) -> void: +func _on_TagOptions_custom_action(action: String) -> void: if action == "delete_tag": var new_animation_tags := Global.current_project.animation_tags.duplicate() new_animation_tags.remove(current_tag_id) @@ -127,8 +144,12 @@ func _on_TagOptions_custom_action(action : String) -> void: Global.current_project.undo_redo.create_action("Delete Frame Tag") Global.current_project.undo_redo.add_do_method(Global, "general_redo") Global.current_project.undo_redo.add_undo_method(Global, "general_undo") - Global.current_project.undo_redo.add_do_property(Global.current_project, "animation_tags", new_animation_tags) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "animation_tags", Global.current_project.animation_tags) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "animation_tags", new_animation_tags + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "animation_tags", Global.current_project.animation_tags + ) Global.current_project.undo_redo.commit_action() options_dialog.hide() @@ -140,5 +161,5 @@ func _on_TagOptions_popup_hide() -> void: delete_tag_button.visible = false -func _on_PlayOnlyTags_toggled(button_pressed : bool) -> void: +func _on_PlayOnlyTags_toggled(button_pressed: bool) -> void: Global.play_only_tags = button_pressed diff --git a/src/UI/Timeline/LayerButton.gd b/src/UI/Timeline/LayerButton.gd index 824ead56d..d6db2cf0f 100644 --- a/src/UI/Timeline/LayerButton.gd +++ b/src/UI/Timeline/LayerButton.gd @@ -1,14 +1,13 @@ class_name LayerButton extends Button - var layer := 0 -onready var visibility_button : BaseButton = find_node("VisibilityButton") -onready var lock_button : BaseButton = find_node("LockButton") -onready var linked_button : BaseButton = find_node("LinkButton") -onready var label : Label = find_node("Label") -onready var line_edit : LineEdit = find_node("LineEdit") +onready var visibility_button: BaseButton = find_node("VisibilityButton") +onready var lock_button: BaseButton = find_node("LockButton") +onready var linked_button: BaseButton = find_node("LinkButton") +onready var label: Label = find_node("Label") +onready var line_edit: LineEdit = find_node("LineEdit") func _ready() -> void: @@ -34,23 +33,27 @@ func _ready() -> void: else: Global.change_button_texturerect(lock_button.get_child(0), "unlock.png") - if Global.current_project.layers[layer].new_cels_linked: # If new layers will be linked + if Global.current_project.layers[layer].new_cels_linked: # If new layers will be linked Global.change_button_texturerect(linked_button.get_child(0), "linked_layer.png") else: Global.change_button_texturerect(linked_button.get_child(0), "unlinked_layer.png") -func _input(event : InputEvent) -> void: - if (event.is_action_released("ui_accept") or event.is_action_released("ui_cancel")) and line_edit.visible and event.scancode != KEY_SPACE: +func _input(event: InputEvent) -> void: + if ( + (event.is_action_released("ui_accept") or event.is_action_released("ui_cancel")) + and line_edit.visible + and event.scancode != KEY_SPACE + ): save_layer_name(line_edit.text) -func _on_LayerContainer_gui_input(event : InputEvent) -> void: +func _on_LayerContainer_gui_input(event: InputEvent) -> void: var project = Global.current_project if event is InputEventMouseButton and event.button_index == BUTTON_LEFT: Global.canvas.selection.transform_content_confirm() - var prev_curr_layer : int = project.current_layer + var prev_curr_layer: int = project.current_layer if Input.is_action_pressed("shift"): var layer_diff_sign = sign(layer - prev_curr_layer) if layer_diff_sign == 0: @@ -65,7 +68,7 @@ func _on_LayerContainer_gui_input(event : InputEvent) -> void: var frame_layer := [i, layer] if !project.selected_cels.has(frame_layer): project.selected_cels.append(frame_layer) - else: # If the button is pressed without Shift or Control + else: # If the button is pressed without Shift or Control project.selected_cels.clear() var frame_layer := [project.current_frame, layer] if !project.selected_cels.has(frame_layer): @@ -84,7 +87,7 @@ func _on_LineEdit_focus_exited() -> void: save_layer_name(line_edit.text) -func save_layer_name(new_name : String) -> void: +func save_layer_name(new_name: String) -> void: label.visible = true line_edit.visible = false line_edit.editable = false @@ -106,11 +109,16 @@ func _on_LockButton_pressed() -> void: func _on_LinkButton_pressed() -> void: Global.canvas.selection.transform_content_confirm() - Global.current_project.layers[layer].new_cels_linked = !Global.current_project.layers[layer].new_cels_linked - if Global.current_project.layers[layer].new_cels_linked && !Global.current_project.layers[layer].linked_cels: + var layer_class: Layer = Global.current_project.layers[layer] + layer_class.new_cels_linked = !layer_class.new_cels_linked + if layer_class.new_cels_linked && !layer_class.linked_cels: # If button is pressed and there are no linked cels in the layer - Global.current_project.layers[layer].linked_cels.append(Global.current_project.frames[Global.current_project.current_frame]) - Global.current_project.layers[layer].frame_container.get_child(Global.current_project.current_frame)._ready() + layer_class.linked_cels.append( + Global.current_project.frames[Global.current_project.current_frame] + ) + layer_class.frame_container.get_child(Global.current_project.current_frame).button_setup() + + Global.current_project.layers = Global.current_project.layers # Call the setter func get_drag_data(_position) -> Array: @@ -135,14 +143,14 @@ func drop_data(_pos, data) -> void: if layer == new_layer: return - var new_layers : Array = Global.current_project.layers.duplicate() + var new_layers: Array = Global.current_project.layers.duplicate() var temp = new_layers[layer] new_layers[layer] = new_layers[new_layer] new_layers[new_layer] = temp Global.current_project.undo_redo.create_action("Change Layer Order") for f in Global.current_project.frames: - var new_cels : Array = f.cels.duplicate() + var new_cels: Array = f.cels.duplicate() var temp_canvas = new_cels[layer] new_cels[layer] = new_cels[new_layer] new_cels[new_layer] = temp_canvas @@ -150,10 +158,16 @@ func drop_data(_pos, data) -> void: Global.current_project.undo_redo.add_undo_property(f, "cels", f.cels) if Global.current_project.current_layer == layer: - Global.current_project.undo_redo.add_do_property(Global.current_project, "current_layer", new_layer) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_layer", Global.current_project.current_layer) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "current_layer", new_layer + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "current_layer", Global.current_project.current_layer + ) Global.current_project.undo_redo.add_do_property(Global.current_project, "layers", new_layers) - Global.current_project.undo_redo.add_undo_property(Global.current_project, "layers", Global.current_project.layers) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "layers", Global.current_project.layers + ) Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") diff --git a/src/UI/ToolButtons.gd b/src/UI/ToolButtons.gd index eeaa1297d..bb04d6029 100644 --- a/src/UI/ToolButtons.gd +++ b/src/UI/ToolButtons.gd @@ -1,5 +1,6 @@ extends GridContainer +var tooltips := [] # Node, shortcut onready var tools := [ @@ -13,39 +14,53 @@ onready var tools := [ [$Zoom, "zoom"], [$Pan, "pan"], [$ColorPicker, "colorpicker"], - [$Pencil, "pencil"], - [$Eraser, "eraser"], + [$Pencil, "pencil", "Shift"], + [$Eraser, "eraser", "Shift"], [$Bucket, "fill"], [$Shading, "shading"], - [$LineTool, "linetool"], - [$RectangleTool, "rectangletool"], - [$EllipseTool, "ellipsetool"], + [$LineTool, "linetool", "Shift", "Ctrl", "Alt"], + [$RectangleTool, "rectangletool", "Shift", "Ctrl", "Alt"], + [$EllipseTool, "ellipsetool", "Shift", "Ctrl", "Alt"], ] func _ready() -> void: for t in tools: t[0].connect("pressed", self, "_on_Tool_pressed", [t[0]]) + tooltips.append(t[0].hint_tooltip) # Resize tools panel when window gets resized get_tree().get_root().connect("size_changed", self, "_on_ToolsAndCanvas_dragged") -func _input(event : InputEvent) -> void: +func update_hintooltips() -> void: + for i in tools.size(): + var toolname: String = tools[i][1] + var shortcuts := [] + shortcuts.append(InputMap.get_action_list("left_" + toolname + "_tool")[0].as_text()) + shortcuts.append(InputMap.get_action_list("right_" + toolname + "_tool")[0].as_text()) + for j in range(2, tools[i].size()): + shortcuts.append(tools[i][j]) + tools[i][0].hint_tooltip = tr(tooltips[i]) % shortcuts + + +func _input(event: InputEvent) -> void: if not Global.has_focus or not event is InputEventKey: return for action in ["undo", "redo", "redo_secondary"]: if event.is_action_pressed(action): return - for t in tools: # Handle tool shortcuts - if event.is_action_pressed("right_" + t[1] + "_tool") and !event.control: # Shortcut for right button (with Alt) + for t in tools: # Handle tool shortcuts + if event.is_action_pressed("right_" + t[1] + "_tool") and !event.control: + # Shortcut for right button (with Alt) Tools.assign_tool(t[0].name, BUTTON_RIGHT) - elif event.is_action_pressed("left_" + t[1] + "_tool") and !event.control: # Shortcut for left button + elif event.is_action_pressed("left_" + t[1] + "_tool") and !event.control: + # Shortcut for left button Tools.assign_tool(t[0].name, BUTTON_LEFT) -func _on_Tool_pressed(tool_pressed : BaseButton) -> void: +func _on_Tool_pressed(tool_pressed: BaseButton) -> void: var button := -1 button = BUTTON_LEFT if Input.is_action_just_released("left_mouse") else button button = BUTTON_RIGHT if Input.is_action_just_released("right_mouse") else button @@ -53,8 +68,8 @@ func _on_Tool_pressed(tool_pressed : BaseButton) -> void: Tools.assign_tool(tool_pressed.name, button) -func _on_ToolsAndCanvas_dragged(_offset : int = 0) -> void: - var tool_panel_size : Vector2 = get_parent().get_parent().get_parent().rect_size +func _on_ToolsAndCanvas_dragged(_offset: int = 0) -> void: + var tool_panel_size: Vector2 = get_parent().get_parent().get_parent().rect_size if Global.tool_button_size == Global.ButtonSize.SMALL: columns = tool_panel_size.x / 28.5 else: diff --git a/src/UI/TopMenuContainer.gd b/src/UI/TopMenuContainer.gd index d2d127f33..390637d2f 100644 --- a/src/UI/TopMenuContainer.gd +++ b/src/UI/TopMenuContainer.gd @@ -1,27 +1,58 @@ extends Panel +enum FileMenuId { NEW, OPEN, OPEN_LAST_PROJECT, SAVE, SAVE_AS, EXPORT, EXPORT_AS, QUIT } +enum EditMenuId { UNDO, REDO, COPY, CUT, PASTE, DELETE, NEW_BRUSH, PREFERENCES } +enum ViewMenuId { + TILE_MODE, + WINDOW_OPACITY, + PANEL_LAYOUT, + MIRROR_VIEW, + SHOW_GRID, + SHOW_PIXEL_GRID, + SHOW_RULERS, + SHOW_GUIDES, + SHOW_ANIMATION_TIMELINE, + ZEN_MODE, + FULLSCREEN_MODE +} +enum ImageMenuId { + SCALE_IMAGE, + CENTRALIZE_IMAGE, + CROP_IMAGE, + RESIZE_CANVAS, + FLIP, + ROTATE, + INVERT_COLORS, + DESATURATION, + OUTLINE, + HSV, + GRADIENT, + SHADER +} +enum SelectMenuId { SELECT_ALL, CLEAR_SELECTION, INVERT } +enum HelpMenuId { + VIEW_SPLASH_SCREEN, + ONLINE_DOCS, + ISSUE_TRACKER, + OPEN_LOGS_FOLDER, + CHANGELOG, + ABOUT_PIXELORAMA +} -enum FileMenuId {NEW, OPEN, OPEN_LAST_PROJECT, SAVE, SAVE_AS, EXPORT, EXPORT_AS, QUIT} -enum EditMenuId {UNDO, REDO, COPY, CUT, PASTE, DELETE, NEW_BRUSH, PREFERENCES} -enum ViewMenuId {TILE_MODE, WINDOW_OPACITY, PANEL_LAYOUT, MIRROR_VIEW, SHOW_GRID, SHOW_PIXEL_GRID, SHOW_RULERS, SHOW_GUIDES, SHOW_ANIMATION_TIMELINE, ZEN_MODE, FULLSCREEN_MODE} -enum ImageMenuId {SCALE_IMAGE, CENTRALIZE_IMAGE, CROP_IMAGE, RESIZE_CANVAS, FLIP, ROTATE, INVERT_COLORS, DESATURATION, OUTLINE, HSV, GRADIENT, SHADER} -enum SelectMenuId {SELECT_ALL, CLEAR_SELECTION, INVERT} -enum HelpMenuId {VIEW_SPLASH_SCREEN, ONLINE_DOCS, ISSUE_TRACKER, OPEN_LOGS_FOLDER, CHANGELOG, ABOUT_PIXELORAMA} - -var file_menu : PopupMenu -var view_menu : PopupMenu +var file_menu: PopupMenu +var view_menu: PopupMenu var zen_mode := false var recent_projects := [] -onready var file_menu_button : MenuButton = find_node("FileMenu") -onready var edit_menu_button : MenuButton = find_node("EditMenu") -onready var view_menu_button : MenuButton = find_node("ViewMenu") -onready var image_menu_button : MenuButton = find_node("ImageMenu") -onready var select_menu_button : MenuButton = find_node("SelectMenu") -onready var help_menu_button : MenuButton = find_node("HelpMenu") +onready var file_menu_button: MenuButton = find_node("FileMenu") +onready var edit_menu_button: MenuButton = find_node("EditMenu") +onready var view_menu_button: MenuButton = find_node("ViewMenu") +onready var image_menu_button: MenuButton = find_node("ImageMenu") +onready var select_menu_button: MenuButton = find_node("SelectMenu") +onready var help_menu_button: MenuButton = find_node("HelpMenu") -onready var new_image_dialog : ConfirmationDialog = Global.control.find_node("CreateNewImage") -onready var window_opacity_dialog : AcceptDialog = Global.control.find_node("WindowOpacityDialog") +onready var new_image_dialog: ConfirmationDialog = Global.control.find_node("CreateNewImage") +onready var window_opacity_dialog: AcceptDialog = Global.control.find_node("WindowOpacityDialog") onready var tile_mode_submenu := PopupMenu.new() onready var panel_layout_submenu := PopupMenu.new() onready var recent_projects_submenu := PopupMenu.new() @@ -37,17 +68,17 @@ func _ready() -> void: func setup_file_menu() -> void: - var file_menu_items := { # order as in FileMenuId enum - "New..." : InputMap.get_action_list("new_file")[0].get_scancode_with_modifiers(), - "Open..." : InputMap.get_action_list("open_file")[0].get_scancode_with_modifiers(), - 'Open last project...' : 0, + var file_menu_items := { # order as in FileMenuId enum + "New...": InputMap.get_action_list("new_file")[0].get_scancode_with_modifiers(), + "Open...": InputMap.get_action_list("open_file")[0].get_scancode_with_modifiers(), + "Open last project...": 0, "Recent projects": 0, - "Save..." : InputMap.get_action_list("save_file")[0].get_scancode_with_modifiers(), - "Save as..." : InputMap.get_action_list("save_file_as")[0].get_scancode_with_modifiers(), - "Export..." : InputMap.get_action_list("export_file")[0].get_scancode_with_modifiers(), - "Export as..." : InputMap.get_action_list("export_file_as")[0].get_scancode_with_modifiers(), - "Quit" : InputMap.get_action_list("quit")[0].get_scancode_with_modifiers(), - } + "Save...": InputMap.get_action_list("save_file")[0].get_scancode_with_modifiers(), + "Save as...": InputMap.get_action_list("save_file_as")[0].get_scancode_with_modifiers(), + "Export...": InputMap.get_action_list("export_file")[0].get_scancode_with_modifiers(), + "Export as...": InputMap.get_action_list("export_file_as")[0].get_scancode_with_modifiers(), + "Quit": InputMap.get_action_list("quit")[0].get_scancode_with_modifiers(), + } file_menu = file_menu_button.get_popup() var i := 0 @@ -65,7 +96,7 @@ func setup_file_menu() -> void: file_menu.set_item_disabled(FileMenuId.SAVE, true) -func setup_recent_projects_submenu(item : String) -> void: +func setup_recent_projects_submenu(item: String) -> void: recent_projects = Global.config_cache.get_value("data", "recent_projects", []) recent_projects_submenu.connect("id_pressed", self, "on_recent_projects_submenu_id_pressed") update_recent_projects_submenu() @@ -80,17 +111,17 @@ func update_recent_projects_submenu() -> void: func setup_edit_menu() -> void: - var edit_menu_items := { # order as in EditMenuId enum - "Undo" : InputMap.get_action_list("undo")[0].get_scancode_with_modifiers(), - "Redo" : InputMap.get_action_list("redo")[0].get_scancode_with_modifiers(), - "Copy" : InputMap.get_action_list("copy")[0].get_scancode_with_modifiers(), - "Cut" : InputMap.get_action_list("cut")[0].get_scancode_with_modifiers(), - "Paste" : InputMap.get_action_list("paste")[0].get_scancode_with_modifiers(), - "Delete" : InputMap.get_action_list("delete")[0].get_scancode_with_modifiers(), - "New Brush" : InputMap.get_action_list("new_brush")[0].get_scancode_with_modifiers(), - "Preferences" : 0 - } - var edit_menu : PopupMenu = edit_menu_button.get_popup() + var edit_menu_items := { # order as in EditMenuId enum + "Undo": InputMap.get_action_list("undo")[0].get_scancode_with_modifiers(), + "Redo": InputMap.get_action_list("redo")[0].get_scancode_with_modifiers(), + "Copy": InputMap.get_action_list("copy")[0].get_scancode_with_modifiers(), + "Cut": InputMap.get_action_list("cut")[0].get_scancode_with_modifiers(), + "Paste": InputMap.get_action_list("paste")[0].get_scancode_with_modifiers(), + "Delete": InputMap.get_action_list("delete")[0].get_scancode_with_modifiers(), + "New Brush": InputMap.get_action_list("new_brush")[0].get_scancode_with_modifiers(), + "Preferences": 0 + } + var edit_menu: PopupMenu = edit_menu_button.get_popup() var i := 0 for item in edit_menu_items.keys(): @@ -102,19 +133,21 @@ func setup_edit_menu() -> void: func setup_view_menu() -> void: - var view_menu_items := { # order as in ViewMenuId enum - "Tile Mode" : 0, - "Window Opacity" : 0, - "Panel Layout" : 0, - "Mirror View" : InputMap.get_action_list("mirror_view")[0].get_scancode_with_modifiers(), - "Show Grid" : InputMap.get_action_list("show_grid")[0].get_scancode_with_modifiers(), - "Show Pixel Grid" : InputMap.get_action_list("show_pixel_grid")[0].get_scancode_with_modifiers(), - "Show Rulers" : InputMap.get_action_list("show_rulers")[0].get_scancode_with_modifiers(), - "Show Guides" : InputMap.get_action_list("show_guides")[0].get_scancode_with_modifiers(), - "Show Animation Timeline" : 0, - "Zen Mode" : InputMap.get_action_list("zen_mode")[0].get_scancode_with_modifiers(), - "Fullscreen Mode" : InputMap.get_action_list("toggle_fullscreen")[0].get_scancode_with_modifiers(), - } + var view_menu_items := { # order as in ViewMenuId enum + "Tile Mode": 0, + "Window Opacity": 0, + "Panel Layout": 0, + "Mirror View": InputMap.get_action_list("mirror_view")[0].get_scancode_with_modifiers(), + "Show Grid": InputMap.get_action_list("show_grid")[0].get_scancode_with_modifiers(), + "Show Pixel Grid": + InputMap.get_action_list("show_pixel_grid")[0].get_scancode_with_modifiers(), + "Show Rulers": InputMap.get_action_list("show_rulers")[0].get_scancode_with_modifiers(), + "Show Guides": InputMap.get_action_list("show_guides")[0].get_scancode_with_modifiers(), + "Show Animation Timeline": 0, + "Zen Mode": InputMap.get_action_list("zen_mode")[0].get_scancode_with_modifiers(), + "Fullscreen Mode": + InputMap.get_action_list("toggle_fullscreen")[0].get_scancode_with_modifiers(), + } view_menu = view_menu_button.get_popup() var i := 0 @@ -134,10 +167,13 @@ func setup_view_menu() -> void: view_menu.hide_on_checkable_item_selection = false view_menu.connect("id_pressed", self, "view_menu_id_pressed") # Disable window opacity item if per pixel transparency is not allowed - view_menu.set_item_disabled(ViewMenuId.WINDOW_OPACITY, !ProjectSettings.get_setting("display/window/per_pixel_transparency/allowed")) + view_menu.set_item_disabled( + ViewMenuId.WINDOW_OPACITY, + !ProjectSettings.get_setting("display/window/per_pixel_transparency/allowed") + ) -func setup_tile_mode_submenu(item : String): +func setup_tile_mode_submenu(item: String): tile_mode_submenu.set_name("tile_mode_submenu") tile_mode_submenu.add_radio_check_item("None", Global.TileMode.NONE) tile_mode_submenu.set_item_checked(Global.TileMode.NONE, true) @@ -151,7 +187,7 @@ func setup_tile_mode_submenu(item : String): view_menu.add_submenu_item(item, tile_mode_submenu.get_name()) -func setup_panel_layout_submenu(item : String): +func setup_panel_layout_submenu(item: String): panel_layout_submenu.set_name("panel_layout_submenu") panel_layout_submenu.add_radio_check_item("Auto", Global.PanelLayout.AUTO) panel_layout_submenu.add_radio_check_item("Widescreen", Global.PanelLayout.WIDESCREEN) @@ -165,21 +201,21 @@ func setup_panel_layout_submenu(item : String): func setup_image_menu() -> void: - var image_menu_items := { # order as in ImageMenuId enum - "Scale Image" : 0, - "Centralize Image" : 0, - "Crop Image" : 0, - "Resize Canvas" : 0, - "Flip" : 0, - "Rotate Image" : 0, - "Invert Colors" : 0, - "Desaturation" : 0, - "Outline" : 0, - "Adjust Hue/Saturation/Value" : 0, - "Gradient" : 0, + var image_menu_items := { # order as in ImageMenuId enum + "Scale Image": 0, + "Centralize Image": 0, + "Crop Image": 0, + "Resize Canvas": 0, + "Flip": 0, + "Rotate Image": 0, + "Invert Colors": 0, + "Desaturation": 0, + "Outline": 0, + "Adjust Hue/Saturation/Value": 0, + "Gradient": 0, # "Shader" : 0 - } - var image_menu : PopupMenu = image_menu_button.get_popup() + } + var image_menu: PopupMenu = image_menu_button.get_popup() var i := 0 for item in image_menu_items.keys(): @@ -192,12 +228,12 @@ func setup_image_menu() -> void: func setup_select_menu() -> void: - var select_menu_items := { # order as in EditMenuId enum - "All" : InputMap.get_action_list("select_all")[0].get_scancode_with_modifiers(), - "Clear" : InputMap.get_action_list("clear_selection")[0].get_scancode_with_modifiers(), - "Invert" : InputMap.get_action_list("invert_selection")[0].get_scancode_with_modifiers(), - } - var select_menu : PopupMenu = select_menu_button.get_popup() + var select_menu_items := { # order as in EditMenuId enum + "All": InputMap.get_action_list("select_all")[0].get_scancode_with_modifiers(), + "Clear": InputMap.get_action_list("clear_selection")[0].get_scancode_with_modifiers(), + "Invert": InputMap.get_action_list("invert_selection")[0].get_scancode_with_modifiers(), + } + var select_menu: PopupMenu = select_menu_button.get_popup() var i := 0 for item in select_menu_items.keys(): @@ -208,15 +244,15 @@ func setup_select_menu() -> void: func setup_help_menu() -> void: - var help_menu_items := { # order as in HelpMenuId enum - "View Splash Screen" : 0, - "Online Docs" : InputMap.get_action_list("open_docs")[0].get_scancode_with_modifiers(), - "Issue Tracker" : 0, - "Open Logs Folder" :0, - "Changelog" : 0, - "About Pixelorama" : 0 - } - var help_menu : PopupMenu = help_menu_button.get_popup() + var help_menu_items := { # order as in HelpMenuId enum + "View Splash Screen": 0, + "Online Docs": InputMap.get_action_list("open_docs")[0].get_scancode_with_modifiers(), + "Issue Tracker": 0, + "Open Logs Folder": 0, + "Changelog": 0, + "About Pixelorama": 0 + } + var help_menu: PopupMenu = help_menu_button.get_popup() var i := 0 for item in help_menu_items.keys(): @@ -226,7 +262,7 @@ func setup_help_menu() -> void: help_menu.connect("id_pressed", self, "help_menu_id_pressed") -func file_menu_id_pressed(id : int) -> void: +func file_menu_id_pressed(id: int) -> void: match id: FileMenuId.NEW: on_new_project_file_menu_option_pressed() @@ -262,10 +298,9 @@ func open_project_file() -> void: func on_open_last_project_file_menu_option_pressed() -> void: - # Check if last project path is set and if yes then open if Global.config_cache.has_section_key("preferences", "last_project_path"): Global.control.load_last_project() - else: # if not then warn user that he didn't edit any project yet + else: Global.error_dialog.set_text("You haven't saved or opened any project in Pixelorama yet!") Global.error_dialog.popup_centered() Global.dialog_open(true) @@ -276,21 +311,25 @@ func save_project_file() -> void: var path = OpenSave.current_save_paths[Global.current_project_index] if path == "": if OS.get_name() == "HTML5": - Global.save_sprites_html5_dialog.popup_centered() - Global.save_sprites_html5_dialog.get_node("FileNameContainer/FileNameLineEdit").text = Global.current_project.name + var save_dialog: ConfirmationDialog = Global.save_sprites_html5_dialog + var save_filename = save_dialog.get_node("FileNameContainer/FileNameLineEdit") + save_dialog.popup_centered() + save_filename.text = Global.current_project.name else: Global.save_sprites_dialog.popup_centered() Global.save_sprites_dialog.current_file = Global.current_project.name Global.dialog_open(true) else: - Global.control._on_SaveSprite_file_selected(path) + Global.control.save_project(path) func save_project_file_as() -> void: Global.control.is_quitting_on_save = false if OS.get_name() == "HTML5": - Global.save_sprites_html5_dialog.popup_centered() - Global.save_sprites_html5_dialog.get_node("FileNameContainer/FileNameLineEdit").text = Global.current_project.name + var save_dialog: ConfirmationDialog = Global.save_sprites_html5_dialog + var save_filename = save_dialog.get_node("FileNameContainer/FileNameLineEdit") + save_dialog.popup_centered() + save_filename.text = Global.current_project.name else: Global.save_sprites_dialog.popup_centered() Global.save_sprites_dialog.current_file = Global.current_project.name @@ -305,11 +344,11 @@ func export_file() -> void: Export.external_export() -func on_recent_projects_submenu_id_pressed(id : int) -> void: +func on_recent_projects_submenu_id_pressed(id: int) -> void: Global.control.load_recent_project_file(recent_projects[id]) -func edit_menu_id_pressed(id : int) -> void: +func edit_menu_id_pressed(id: int) -> void: match id: EditMenuId.UNDO: Global.current_project.commit_undo() @@ -330,7 +369,7 @@ func edit_menu_id_pressed(id : int) -> void: Global.dialog_open(true) -func view_menu_id_pressed(id : int) -> void: +func view_menu_id_pressed(id: int) -> void: match id: ViewMenuId.WINDOW_OPACITY: window_opacity_dialog.popup_centered() @@ -354,7 +393,7 @@ func view_menu_id_pressed(id : int) -> void: Global.canvas.update() -func tile_mode_submenu_id_pressed(id : int) -> void: +func tile_mode_submenu_id_pressed(id: int) -> void: Global.current_project.tile_mode = id Global.transparent_checker.fit_rect(Global.current_project.get_tile_mode_rect()) for i in Global.TileMode.values(): @@ -364,7 +403,7 @@ func tile_mode_submenu_id_pressed(id : int) -> void: Global.canvas.grid.update() -func panel_layout_submenu_id_pressed(id : int) -> void: +func panel_layout_submenu_id_pressed(id: int) -> void: Global.panel_layout = id for i in Global.PanelLayout.values(): panel_layout_submenu.set_item_checked(i, i == id) @@ -373,9 +412,13 @@ func panel_layout_submenu_id_pressed(id : int) -> void: func toggle_mirror_view() -> void: Global.mirror_view = !Global.mirror_view - Global.canvas.selection.marching_ants_outline.scale.x = -Global.canvas.selection.marching_ants_outline.scale.x + var marching_ants_outline: Sprite = Global.canvas.selection.marching_ants_outline + marching_ants_outline.scale.x = -marching_ants_outline.scale.x if Global.mirror_view: - Global.canvas.selection.marching_ants_outline.position.x = Global.canvas.selection.marching_ants_outline.position.x + Global.current_project.size.x + marching_ants_outline.position.x = ( + marching_ants_outline.position.x + + Global.current_project.size.x + ) else: Global.canvas.selection.marching_ants_outline.position.x = 0 Global.canvas.selection.update() @@ -428,7 +471,7 @@ func toggle_zen_mode() -> void: Global.tool_panel.visible = zen_mode Global.right_panel.visible = zen_mode Global.control.find_node("TabsContainer").visible = zen_mode - Global.control.tallscreen_hsplit_container.visible = zen_mode + Global.control.tallscreen_hsplit.visible = zen_mode zen_mode = !zen_mode view_menu.set_item_checked(ViewMenuId.ZEN_MODE, zen_mode) @@ -436,11 +479,11 @@ func toggle_zen_mode() -> void: func toggle_fullscreen() -> void: OS.window_fullscreen = !OS.window_fullscreen view_menu.set_item_checked(ViewMenuId.FULLSCREEN_MODE, OS.window_fullscreen) - if OS.window_fullscreen: # If window is fullscreen then reset transparency - window_opacity_dialog._on_value_changed(1.0) + if OS.window_fullscreen: # If window is fullscreen then reset transparency + window_opacity_dialog.set_window_opacity(1.0) -func image_menu_id_pressed(id : int) -> void: +func image_menu_id_pressed(id: int) -> void: match id: ImageMenuId.SCALE_IMAGE: show_scale_image_popup() @@ -509,7 +552,7 @@ func show_hsv_configuration_popup() -> void: Global.dialog_open(true) -func select_menu_id_pressed(id : int) -> void: +func select_menu_id_pressed(id: int) -> void: match id: SelectMenuId.SELECT_ALL: Global.canvas.selection.select_all() @@ -519,7 +562,7 @@ func select_menu_id_pressed(id : int) -> void: Global.canvas.selection.invert() -func help_menu_id_pressed(id : int) -> void: +func help_menu_id_pressed(id: int) -> void: match id: HelpMenuId.VIEW_SPLASH_SCREEN: Global.control.get_node("Dialogs/SplashDialog").popup_centered() @@ -530,10 +573,12 @@ func help_menu_id_pressed(id : int) -> void: OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/issues") HelpMenuId.OPEN_LOGS_FOLDER: var dir = Directory.new() - dir.make_dir_recursive("user://logs") #incase someone deleted it + dir.make_dir_recursive("user://logs") #incase someone deleted it OS.shell_open(ProjectSettings.globalize_path("user://logs")) HelpMenuId.CHANGELOG: - OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/blob/master/CHANGELOG.md#v09---2021-09-18") + OS.shell_open( + "https://github.com/Orama-Interactive/Pixelorama/blob/master/CHANGELOG.md#v09---2021-09-18" + ) HelpMenuId.ABOUT_PIXELORAMA: Global.control.get_node("Dialogs/AboutDialog").popup_centered() Global.dialog_open(true) diff --git a/src/UI/TransparentChecker.gd b/src/UI/TransparentChecker.gd index 854005e51..2f7b94338 100644 --- a/src/UI/TransparentChecker.gd +++ b/src/UI/TransparentChecker.gd @@ -2,11 +2,15 @@ extends ColorRect func _ready() -> void: + update_rect() + + +func update_rect() -> void: rect_size = Global.current_project.size if self == Global.transparent_checker: fit_rect(Global.current_project.get_tile_mode_rect()) - Global.second_viewport.get_node("Viewport/TransparentChecker")._ready() - Global.small_preview_viewport.get_node("Viewport/TransparentChecker")._ready() + Global.second_viewport.get_node("Viewport/TransparentChecker").update_rect() + Global.small_preview_viewport.get_node("Viewport/TransparentChecker").update_rect() material.set_shader_param("size", Global.checker_size) material.set_shader_param("color1", Global.checker_color_1) material.set_shader_param("color2", Global.checker_color_2) @@ -14,7 +18,7 @@ func _ready() -> void: material.set_shader_param("follow_scale", Global.checker_follow_scale) -func update_offset(offset : Vector2, scale : Vector2) -> void: +func update_offset(offset: Vector2, scale: Vector2) -> void: material.set_shader_param("offset", offset) material.set_shader_param("scale", scale) @@ -23,12 +27,12 @@ func _on_TransparentChecker_resized() -> void: material.set_shader_param("rect_size", rect_size) -func fit_rect(rect : Rect2) -> void: +func fit_rect(rect: Rect2) -> void: rect_position = rect.position rect_size = rect.size -func transparency(value :float) -> void: +func transparency(value: float) -> void: # first make viewport transparent then background and then viewport if value == 1.0: get_parent().transparent_bg = false @@ -40,4 +44,4 @@ func transparency(value :float) -> void: # this controls opacity 0 for transparent, 1 or a greater value than 1 is opaque # i have set a minimum amount for the fade (We would'nt want the canvas to dissapear now would we?) - material.set("shader_param/alpha",clamp(value,0.1,1)) + material.set("shader_param/alpha", clamp(value, 0.1, 1)) diff --git a/src/UI/UI.tscn b/src/UI/UI.tscn index 3a06e6d7f..4e789de2d 100644 --- a/src/UI/UI.tscn +++ b/src/UI/UI.tscn @@ -140,6 +140,10 @@ script = ExtResource( 1 ) margin_right = 24.0 margin_bottom = 24.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Rectangular Selection + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -192,6 +196,10 @@ margin_top = 28.0 margin_right = 24.0 margin_bottom = 52.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Elliptical Selection + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -244,6 +252,11 @@ margin_top = 56.0 margin_right = 24.0 margin_bottom = 80.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Polygonal Selection +Double-click to connect the last point to the starting point + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -296,6 +309,10 @@ margin_top = 84.0 margin_right = 24.0 margin_bottom = 108.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Select By Color + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -348,6 +365,10 @@ margin_top = 112.0 margin_right = 24.0 margin_bottom = 136.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Magic Wand + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -400,6 +421,10 @@ margin_top = 140.0 margin_right = 24.0 margin_bottom = 164.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Lasso / Free Select Tool + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -452,6 +477,10 @@ margin_top = 168.0 margin_right = 24.0 margin_bottom = 192.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Move + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -504,6 +533,10 @@ margin_top = 196.0 margin_right = 24.0 margin_bottom = 220.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Zoom + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -556,6 +589,10 @@ margin_top = 224.0 margin_right = 24.0 margin_bottom = 248.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Pan + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -608,6 +645,11 @@ margin_top = 252.0 margin_right = 24.0 margin_bottom = 276.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Color Picker +Select a color from a pixel of the sprite + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -660,6 +702,12 @@ margin_top = 280.0 margin_right = 24.0 margin_bottom = 304.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Pencil + +%s for left mouse button +%s for right mouse button + +Hold %s to make a line" mouse_default_cursor_shape = 2 button_mask = 3 @@ -711,6 +759,12 @@ margin_top = 308.0 margin_right = 24.0 margin_bottom = 332.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Eraser + +%s for left mouse button +%s for right mouse button + +Hold %s to make a line" mouse_default_cursor_shape = 2 button_mask = 3 @@ -762,6 +816,10 @@ margin_top = 336.0 margin_right = 24.0 margin_bottom = 360.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Bucket + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -814,6 +872,10 @@ margin_top = 364.0 margin_right = 24.0 margin_bottom = 388.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Shading Tool + +%s for left mouse button +%s for right mouse button" mouse_default_cursor_shape = 2 button_mask = 3 @@ -866,6 +928,14 @@ margin_top = 392.0 margin_right = 24.0 margin_bottom = 416.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Line Tool + +%s for left mouse button +%s for right mouse button + +Hold %s to snap the angle of the line +Hold %s to center the shape on the click origin +Hold %s to displace the shape's origin" mouse_default_cursor_shape = 2 button_mask = 3 @@ -918,6 +988,14 @@ margin_top = 420.0 margin_right = 24.0 margin_bottom = 444.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Rectangle Tool + +%s for left mouse button +%s for right mouse button + +Hold %s to create a 1:1 shape +Hold %s to center the shape on the click origin +Hold %s to displace the shape's origin" mouse_default_cursor_shape = 2 button_mask = 3 @@ -970,6 +1048,14 @@ margin_top = 448.0 margin_right = 24.0 margin_bottom = 472.0 rect_min_size = Vector2( 24, 24 ) +hint_tooltip = "Ellipse Tool + +%s for left mouse button +%s for right mouse button + +Hold %s to create a 1:1 shape +Hold %s to center the shape on the click origin +Hold %s to displace the shape's origin" mouse_default_cursor_shape = 2 button_mask = 3 @@ -1189,6 +1275,14 @@ custom_constants/autohide = 0 [node name="ColorAndToolOptions" parent="RightPanel/MarginContainer/PreviewAndPalettes/ToolAndPaletteVSplit" instance=ExtResource( 17 )] margin_right = 328.0 margin_bottom = 372.0 +hint_tooltip = "Ellipse Tool + +%s for left mouse button +%s for right mouse button + +Hold %s to create a 1:1 shape +Hold %s to center the shape on the click origin +Hold %s to displace the shape's origin" [node name="PalettePanel" parent="RightPanel/MarginContainer/PreviewAndPalettes/ToolAndPaletteVSplit" instance=ExtResource( 20 )] margin_top = 384.0 diff --git a/src/XDGDataPaths.gd b/src/XDGDataPaths.gd index 4a5b97b17..c2891970c 100644 --- a/src/XDGDataPaths.gd +++ b/src/XDGDataPaths.gd @@ -1,23 +1,23 @@ extends Reference +# Default location for xdg_data_home relative to $HOME +const DEFAULT_XDG_DATA_HOME_REL := ".local/share" +const DEFAULT_XDG_DATA_DIRS := ["/usr/local/share", "/usr/share"] + +const CONFIG_SUBDIR_NAME := "pixelorama_data" +const XDG_CONFIG_SUBDIR_NAME := "pixelorama" + +const PALETTES_DATA_SUBDIRECTORY := "Palettes" +const BRUSHES_DATA_SUBDIRECTORY := "Brushes" +const PATTERNS_DATA_SUBDIRECTORY := "Patterns" + # These are *with* the config subdirectory name -var xdg_data_home : String -var xdg_data_dirs : Array +var xdg_data_home: String +var xdg_data_dirs: Array # These are *without* the config subdirectory name -var raw_xdg_data_home : String -var raw_xdg_data_dirs : Array - -# Default location for xdg_data_home relative to $HOME -const default_xdg_data_home_rel := ".local/share" -const default_xdg_data_dirs := ["/usr/local/share", "/usr/share"] - -const config_subdir_name := "pixelorama_data" -const xdg_config_subdir_name := "pixelorama" - -const palettes_data_subdirectory := "Palettes" -const brushes_data_subdirectory := "Brushes" -const patterns_data_subdirectory := "Patterns" +var raw_xdg_data_home: String +var raw_xdg_data_dirs: Array # Get if we should use XDG standard or not nyaaaa @@ -32,20 +32,14 @@ func _init() -> void: if use_xdg_standard(): print("Detected system where we should use XDG basedir standard (currently Linux or BSD)") var home := OS.get_environment("HOME") - raw_xdg_data_home = home.plus_file( - default_xdg_data_home_rel - ) - xdg_data_home = raw_xdg_data_home.plus_file( - xdg_config_subdir_name - ) + raw_xdg_data_home = home.plus_file(DEFAULT_XDG_DATA_HOME_REL) + xdg_data_home = raw_xdg_data_home.plus_file(XDG_CONFIG_SUBDIR_NAME) # Create defaults xdg_data_dirs = [] - raw_xdg_data_dirs = default_xdg_data_dirs + raw_xdg_data_dirs = DEFAULT_XDG_DATA_DIRS for default_loc in raw_xdg_data_dirs: - xdg_data_dirs.append( - default_loc.plus_file(xdg_config_subdir_name) - ) + xdg_data_dirs.append(default_loc.plus_file(XDG_CONFIG_SUBDIR_NAME)) # Now check the XDG environment variables and if # present, replace the defaults with them! @@ -53,7 +47,7 @@ func _init() -> void: # Checks the xdg data home var if OS.has_environment("XDG_DATA_HOME"): raw_xdg_data_home = OS.get_environment("XDG_DATA_HOME") - xdg_data_home = raw_xdg_data_home.plus_file(xdg_config_subdir_name) + xdg_data_home = raw_xdg_data_home.plus_file(XDG_CONFIG_SUBDIR_NAME) # Checks the list of files var, and processes them. if OS.has_environment("XDG_DATA_DIRS"): var raw_env_var := OS.get_environment("XDG_DATA_DIRS") @@ -62,12 +56,12 @@ func _init() -> void: raw_xdg_data_dirs = unappended_subdirs xdg_data_dirs = [] for unapp_subdir in raw_xdg_data_dirs: - xdg_data_dirs.append(unapp_subdir.plus_file(xdg_config_subdir_name)) - xdg_data_dirs.append(Global.root_directory.plus_file(config_subdir_name)) + xdg_data_dirs.append(unapp_subdir.plus_file(XDG_CONFIG_SUBDIR_NAME)) + xdg_data_dirs.append(Global.root_directory.plus_file(CONFIG_SUBDIR_NAME)) else: raw_xdg_data_home = Global.root_directory - xdg_data_home = raw_xdg_data_home.plus_file(config_subdir_name) + xdg_data_home = raw_xdg_data_home.plus_file(CONFIG_SUBDIR_NAME) raw_xdg_data_dirs = [] xdg_data_dirs = [] @@ -87,39 +81,39 @@ func get_search_paths_in_order() -> Array: # Gets the paths, in order of search priority, for palettes. func get_palette_search_path_in_order() -> Array: var base_paths := get_search_paths_in_order() - return append_file_to_all(base_paths, palettes_data_subdirectory) + return append_file_to_all(base_paths, PALETTES_DATA_SUBDIRECTORY) # Gets the paths, in order of search priority, for brushes. func get_brushes_search_path_in_order() -> Array: var base_paths := get_search_paths_in_order() - return append_file_to_all(base_paths, brushes_data_subdirectory) + return append_file_to_all(base_paths, BRUSHES_DATA_SUBDIRECTORY) # Gets the paths, in order of search priority, for patterns. func get_patterns_search_path_in_order() -> Array: var base_paths := get_search_paths_in_order() - return append_file_to_all(base_paths, patterns_data_subdirectory) + return append_file_to_all(base_paths, PATTERNS_DATA_SUBDIRECTORY) # Get the path that we are ok to be writing palettes to: func get_palette_write_path() -> String: - return xdg_data_home.plus_file(palettes_data_subdirectory) + return xdg_data_home.plus_file(PALETTES_DATA_SUBDIRECTORY) # Get the path that we are ok to be writing brushes to: func get_brushes_write_path() -> String: - return xdg_data_home.plus_file(brushes_data_subdirectory) + return xdg_data_home.plus_file(BRUSHES_DATA_SUBDIRECTORY) # Get the path that we are ok to be writing patterns to: func get_patterns_write_path() -> String: - return xdg_data_home.plus_file(patterns_data_subdirectory) + return xdg_data_home.plus_file(PATTERNS_DATA_SUBDIRECTORY) # Ensure the user xdg directories exist: func ensure_xdg_user_dirs_exist() -> void: - if !OS.has_feature("standalone"): # Don't execute if we're in the editor + if !OS.has_feature("standalone"): # Don't execute if we're in the editor return var base_dir := Directory.new()