mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-19 01:29:49 +00:00
Make the opacity slider affect layer opacity instead of cel opacity
And move cel opacity inside the cel properties.
This commit is contained in:
parent
c0a8202145
commit
359f509d57
|
@ -35,7 +35,8 @@ func blend_layers(
|
||||||
metadata_image.set_pixel(ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0))
|
metadata_image.set_pixel(ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0))
|
||||||
# Store the opacity
|
# Store the opacity
|
||||||
if include:
|
if include:
|
||||||
metadata_image.set_pixel(ordered_index, 1, Color(cel.opacity, 0.0, 0.0, 0.0))
|
var opacity := cel.get_final_opacity(layer)
|
||||||
|
metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0))
|
||||||
else:
|
else:
|
||||||
metadata_image.set_pixel(ordered_index, 1, Color())
|
metadata_image.set_pixel(ordered_index, 1, Color())
|
||||||
var texture_array := Texture2DArray.new()
|
var texture_array := Texture2DArray.new()
|
||||||
|
|
|
@ -14,8 +14,15 @@ var image_texture: Texture2D:
|
||||||
## [br] If the cel is not linked then it is [code]null[/code].
|
## [br] If the cel is not linked then it is [code]null[/code].
|
||||||
var link_set = null # { "cels": Array, "hue": float } or null
|
var link_set = null # { "cels": Array, "hue": float } or null
|
||||||
var transformed_content: Image ## Used in transformations (moving, scaling etc with selections).
|
var transformed_content: Image ## Used in transformations (moving, scaling etc with selections).
|
||||||
|
## Used for individual cel ordering. Used for when cels need to be drawn above or below
|
||||||
|
## their corresponding layer.
|
||||||
var z_index := 0
|
var z_index := 0
|
||||||
|
|
||||||
|
|
||||||
|
func get_final_opacity(layer: BaseLayer) -> float:
|
||||||
|
return layer.opacity * opacity
|
||||||
|
|
||||||
|
|
||||||
# Methods to Override:
|
# Methods to Override:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ var visible := true ## Sets visibility of the layer.
|
||||||
var locked := false ## Images of a locked layer won't be overritten.
|
var locked := false ## Images of a locked layer won't be overritten.
|
||||||
var new_cels_linked := false ## Determines if new cel of the layer should be linked or not.
|
var new_cels_linked := false ## Determines if new cel of the layer should be linked or not.
|
||||||
var blend_mode := BlendModes.NORMAL ## Blend mode of the current layer.
|
var blend_mode := BlendModes.NORMAL ## Blend mode of the current layer.
|
||||||
|
var opacity := 1.0 ## The opacity of the layer, affects all frames that belong to that layer.
|
||||||
var cel_link_sets: Array[Dictionary] = [] ## Each Dictionary represents a cel's "link set"
|
var cel_link_sets: Array[Dictionary] = [] ## Each Dictionary represents a cel's "link set"
|
||||||
var effects: Array[LayerEffect] ## An array for non-destructive effects of the layer.
|
var effects: Array[LayerEffect] ## An array for non-destructive effects of the layer.
|
||||||
var effects_enabled := true ## If [code]true[/code], the effects are being applied.
|
var effects_enabled := true ## If [code]true[/code], the effects are being applied.
|
||||||
|
@ -214,6 +215,7 @@ func serialize() -> Dictionary:
|
||||||
"visible": visible,
|
"visible": visible,
|
||||||
"locked": locked,
|
"locked": locked,
|
||||||
"blend_mode": blend_mode,
|
"blend_mode": blend_mode,
|
||||||
|
"opacity": opacity,
|
||||||
"parent": parent.index if is_instance_valid(parent) else -1,
|
"parent": parent.index if is_instance_valid(parent) else -1,
|
||||||
"effects": effect_data
|
"effects": effect_data
|
||||||
}
|
}
|
||||||
|
@ -236,6 +238,8 @@ func deserialize(dict: Dictionary) -> void:
|
||||||
locked = dict.locked
|
locked = dict.locked
|
||||||
if dict.has("blend_mode"):
|
if dict.has("blend_mode"):
|
||||||
blend_mode = dict.blend_mode
|
blend_mode = dict.blend_mode
|
||||||
|
if dict.has("opacity"):
|
||||||
|
opacity = dict.opacity
|
||||||
if dict.get("parent", -1) != -1:
|
if dict.get("parent", -1) != -1:
|
||||||
parent = project.layers[dict.parent]
|
parent = project.layers[dict.parent]
|
||||||
if dict.has("linked_cels") and not dict["linked_cels"].is_empty(): # Backwards compatibility
|
if dict.has("linked_cels") and not dict["linked_cels"].is_empty(): # Backwards compatibility
|
||||||
|
|
|
@ -24,7 +24,7 @@ func blend_children(frame: Frame, origin := Vector2i.ZERO) -> Image:
|
||||||
var cel := frame.cels[layer.index]
|
var cel := frame.cels[layer.index]
|
||||||
var cel_image := Image.new()
|
var cel_image := Image.new()
|
||||||
cel_image.copy_from(cel.get_image())
|
cel_image.copy_from(cel.get_image())
|
||||||
if cel.opacity < 1.0: # If we have cel transparency
|
if cel.get_final_opacity(layer) < 1.0: # If we have cel transparency
|
||||||
for xx in cel_image.get_size().x:
|
for xx in cel_image.get_size().x:
|
||||||
for yy in cel_image.get_size().y:
|
for yy in cel_image.get_size().y:
|
||||||
var pixel_color := cel_image.get_pixel(xx, yy)
|
var pixel_color := cel_image.get_pixel(xx, yy)
|
||||||
|
|
|
@ -34,6 +34,10 @@ var layers: Array[BaseLayer] = []
|
||||||
var current_frame := 0
|
var current_frame := 0
|
||||||
var current_layer := 0
|
var current_layer := 0
|
||||||
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)
|
||||||
|
## Array that contains the order of the [BaseLayer] indices that are being drawn.
|
||||||
|
## Takes into account each [BaseCel]'s invidiual z-index. If all z-indexes are 0, then the
|
||||||
|
## array just contains the indices of the layers in increasing order.
|
||||||
|
## See [method order_layers].
|
||||||
var ordered_layers: Array[int] = [0]
|
var ordered_layers: Array[int] = [0]
|
||||||
|
|
||||||
var animation_tags: Array[AnimationTag] = []:
|
var animation_tags: Array[AnimationTag] = []:
|
||||||
|
@ -615,6 +619,8 @@ func find_first_drawable_cel(frame := frames[current_frame]) -> BaseCel:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
## Re-order layers to take each cel's z-index into account. If all z-indexes are 0,
|
||||||
|
## then the order of drawing is the same as the order of the layers itself.
|
||||||
func order_layers(frame_index := current_frame) -> void:
|
func order_layers(frame_index := current_frame) -> void:
|
||||||
ordered_layers = []
|
ordered_layers = []
|
||||||
for i in layers.size():
|
for i in layers.size():
|
||||||
|
@ -622,6 +628,8 @@ func order_layers(frame_index := current_frame) -> void:
|
||||||
ordered_layers.sort_custom(_z_index_sort.bind(frame_index))
|
ordered_layers.sort_custom(_z_index_sort.bind(frame_index))
|
||||||
|
|
||||||
|
|
||||||
|
## Used as a [Callable] for [method Array.sort_custom] to sort layers
|
||||||
|
## while taking each cel's z-index into account.
|
||||||
func _z_index_sort(a: int, b: int, frame_index: int) -> bool:
|
func _z_index_sort(a: int, b: int, frame_index: int) -> bool:
|
||||||
var z_index_a := frames[frame_index].cels[a].z_index
|
var z_index_a := frames[frame_index].cels[a].z_index
|
||||||
var z_index_b := frames[frame_index].cels[b].z_index
|
var z_index_b := frames[frame_index].cels[b].z_index
|
||||||
|
|
|
@ -169,7 +169,8 @@ func draw_layers() -> void:
|
||||||
)
|
)
|
||||||
# Store the opacity
|
# Store the opacity
|
||||||
if layer.is_visible_in_hierarchy():
|
if layer.is_visible_in_hierarchy():
|
||||||
layer_metadata_image.set_pixel(ordered_index, 1, Color(cel.opacity, 0.0, 0.0, 0.0))
|
var opacity := cel.get_final_opacity(layer)
|
||||||
|
layer_metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0))
|
||||||
else:
|
else:
|
||||||
layer_metadata_image.set_pixel(ordered_index, 1, Color())
|
layer_metadata_image.set_pixel(ordered_index, 1, Color())
|
||||||
# Store the origin
|
# Store the origin
|
||||||
|
@ -203,9 +204,8 @@ func draw_layers() -> void:
|
||||||
ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0)
|
ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0)
|
||||||
)
|
)
|
||||||
if layer.is_visible_in_hierarchy():
|
if layer.is_visible_in_hierarchy():
|
||||||
layer_metadata_image.set_pixel(
|
var opacity := cel.get_final_opacity(layer)
|
||||||
ordered_index, 1, Color(cel.opacity, 0.0, 0.0, 0.0)
|
layer_metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0))
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
layer_metadata_image.set_pixel(ordered_index, 1, Color())
|
layer_metadata_image.set_pixel(ordered_index, 1, Color())
|
||||||
var origin := Vector2(move_preview_location).abs() / Vector2(cel_image.get_size())
|
var origin := Vector2(move_preview_location).abs() / Vector2(cel_image.get_size())
|
||||||
|
|
|
@ -81,18 +81,20 @@ func _draw_layers() -> void:
|
||||||
var metadata_image := Image.create(project.layers.size(), 3, false, Image.FORMAT_R8)
|
var metadata_image := Image.create(project.layers.size(), 3, false, Image.FORMAT_R8)
|
||||||
# Draw current frame layers
|
# Draw current frame layers
|
||||||
for i in project.ordered_layers:
|
for i in project.ordered_layers:
|
||||||
|
var cel := current_cels[i]
|
||||||
if current_cels[i] is GroupCel:
|
if current_cels[i] is GroupCel:
|
||||||
continue
|
continue
|
||||||
var layer := project.layers[i]
|
var layer := project.layers[i]
|
||||||
var cel_image: Image
|
var cel_image: Image
|
||||||
if Global.display_layer_effects:
|
if Global.display_layer_effects:
|
||||||
cel_image = layer.display_effects(current_cels[i])
|
cel_image = layer.display_effects(cel)
|
||||||
else:
|
else:
|
||||||
cel_image = current_cels[i].get_image()
|
cel_image = cel.get_image()
|
||||||
textures.append(cel_image)
|
textures.append(cel_image)
|
||||||
metadata_image.set_pixel(i, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0))
|
metadata_image.set_pixel(i, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0))
|
||||||
if layer.is_visible_in_hierarchy():
|
if layer.is_visible_in_hierarchy():
|
||||||
metadata_image.set_pixel(i, 1, Color(current_cels[i].opacity, 0.0, 0.0, 0.0))
|
var opacity := cel.get_final_opacity(layer)
|
||||||
|
metadata_image.set_pixel(i, 1, Color(opacity, 0.0, 0.0, 0.0))
|
||||||
else:
|
else:
|
||||||
metadata_image.set_pixel(i, 1, Color(0.0, 0.0, 0.0, 0.0))
|
metadata_image.set_pixel(i, 1, Color(0.0, 0.0, 0.0, 0.0))
|
||||||
var texture_array := Texture2DArray.new()
|
var texture_array := Texture2DArray.new()
|
||||||
|
|
|
@ -19,10 +19,12 @@ func _on_ResizeCanvas_about_to_show() -> void:
|
||||||
|
|
||||||
var layer_i := 0
|
var layer_i := 0
|
||||||
for cel in Global.current_project.frames[Global.current_project.current_frame].cels:
|
for cel in Global.current_project.frames[Global.current_project.current_frame].cels:
|
||||||
if cel is PixelCel and Global.current_project.layers[layer_i].is_visible_in_hierarchy():
|
var layer := Global.current_project.layers[layer_i]
|
||||||
|
if cel is PixelCel and layer.is_visible_in_hierarchy():
|
||||||
var cel_image := Image.new()
|
var cel_image := Image.new()
|
||||||
cel_image.copy_from(cel.get_image())
|
cel_image.copy_from(cel.get_image())
|
||||||
if cel.opacity < 1: # If we have cel transparency
|
var opacity := cel.get_final_opacity(layer)
|
||||||
|
if opacity < 1.0: # If we have cel transparency
|
||||||
for xx in cel_image.get_size().x:
|
for xx in cel_image.get_size().x:
|
||||||
for yy in cel_image.get_size().y:
|
for yy in cel_image.get_size().y:
|
||||||
var pixel_color := cel_image.get_pixel(xx, yy)
|
var pixel_color := cel_image.get_pixel(xx, yy)
|
||||||
|
|
|
@ -930,7 +930,8 @@ func _on_MergeDownLayer_pressed() -> void:
|
||||||
metadata_image.set_pixel(0, 1, Color(1.0, 0.0, 0.0, 0.0))
|
metadata_image.set_pixel(0, 1, Color(1.0, 0.0, 0.0, 0.0))
|
||||||
textures.append(top_image)
|
textures.append(top_image)
|
||||||
metadata_image.set_pixel(1, 0, Color(top_layer.blend_mode / 255.0, 0.0, 0.0, 0.0))
|
metadata_image.set_pixel(1, 0, Color(top_layer.blend_mode / 255.0, 0.0, 0.0, 0.0))
|
||||||
metadata_image.set_pixel(1, 1, Color(frame.cels[top_layer.index].opacity, 0.0, 0.0, 0.0))
|
var opacity := frame.cels[top_layer.index].get_final_opacity(top_layer)
|
||||||
|
metadata_image.set_pixel(1, 1, Color(opacity, 0.0, 0.0, 0.0))
|
||||||
var texture_array := Texture2DArray.new()
|
var texture_array := Texture2DArray.new()
|
||||||
texture_array.create_from_images(textures)
|
texture_array.create_from_images(textures)
|
||||||
var params := {
|
var params := {
|
||||||
|
@ -978,9 +979,8 @@ func _on_OpacitySlider_value_changed(value: float) -> void:
|
||||||
# Also update all selected frames.
|
# Also update all selected frames.
|
||||||
for idx_pair in Global.current_project.selected_cels:
|
for idx_pair in Global.current_project.selected_cels:
|
||||||
if idx_pair[1] == current_layer_idx:
|
if idx_pair[1] == current_layer_idx:
|
||||||
var frame := Global.current_project.frames[idx_pair[0]]
|
var layer := Global.current_project.layers[current_layer_idx]
|
||||||
var cel := frame.cels[current_layer_idx]
|
layer.opacity = new_opacity
|
||||||
cel.opacity = new_opacity
|
|
||||||
Global.canvas.queue_redraw()
|
Global.canvas.queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
@ -999,8 +999,8 @@ func _cel_changed() -> void:
|
||||||
_toggle_frame_buttons()
|
_toggle_frame_buttons()
|
||||||
_toggle_layer_buttons()
|
_toggle_layer_buttons()
|
||||||
var project := Global.current_project
|
var project := Global.current_project
|
||||||
var cel_opacity := project.get_current_cel().opacity
|
var layer_opacity := project.layers[project.current_layer].opacity
|
||||||
opacity_slider.value = cel_opacity * 100
|
opacity_slider.value = layer_opacity * 100
|
||||||
var blend_mode_index := blend_modes_button.get_item_index(
|
var blend_mode_index := blend_modes_button.get_item_index(
|
||||||
project.layers[project.current_layer].blend_mode
|
project.layers[project.current_layer].blend_mode
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,6 +11,7 @@ var cel: BaseCel
|
||||||
@onready var cel_texture: TextureRect = $CelTexture
|
@onready var cel_texture: TextureRect = $CelTexture
|
||||||
@onready var transparent_checker: ColorRect = $CelTexture/TransparentChecker
|
@onready var transparent_checker: ColorRect = $CelTexture/TransparentChecker
|
||||||
@onready var properties: AcceptDialog = $Properties
|
@onready var properties: AcceptDialog = $Properties
|
||||||
|
@onready var opacity_slider: ValueSlider = %OpacitySlider
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
@ -100,6 +101,7 @@ func _on_CelButton_pressed() -> void:
|
||||||
func _on_PopupMenu_id_pressed(id: int) -> void:
|
func _on_PopupMenu_id_pressed(id: int) -> void:
|
||||||
match id:
|
match id:
|
||||||
MenuOptions.PROPERTIES:
|
MenuOptions.PROPERTIES:
|
||||||
|
opacity_slider.value = cel.opacity * 100.0
|
||||||
properties.popup_centered()
|
properties.popup_centered()
|
||||||
MenuOptions.DELETE:
|
MenuOptions.DELETE:
|
||||||
_delete_cel_content()
|
_delete_cel_content()
|
||||||
|
@ -299,6 +301,11 @@ func _get_region_rect(x_begin: float, x_end: float) -> Rect2:
|
||||||
return rect
|
return rect
|
||||||
|
|
||||||
|
|
||||||
|
func _on_opacity_slider_value_changed(value: float) -> void:
|
||||||
|
cel.opacity = value / 100.0
|
||||||
|
Global.canvas.queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
func _on_z_index_slider_value_changed(value: float) -> void:
|
func _on_z_index_slider_value_changed(value: float) -> void:
|
||||||
cel.z_index = value
|
cel.z_index = value
|
||||||
Global.current_project.order_layers()
|
Global.current_project.order_layers()
|
||||||
|
|
|
@ -72,7 +72,7 @@ polygon = PackedVector2Array(0, 0, 36, 0, 36, 36, 0, 36)
|
||||||
|
|
||||||
[node name="Properties" type="AcceptDialog" parent="."]
|
[node name="Properties" type="AcceptDialog" parent="."]
|
||||||
title = "Cel properties"
|
title = "Cel properties"
|
||||||
size = Vector2i(300, 100)
|
size = Vector2i(300, 111)
|
||||||
exclusive = false
|
exclusive = false
|
||||||
popup_window = true
|
popup_window = true
|
||||||
|
|
||||||
|
@ -80,10 +80,30 @@ popup_window = true
|
||||||
offset_left = 8.0
|
offset_left = 8.0
|
||||||
offset_top = 8.0
|
offset_top = 8.0
|
||||||
offset_right = 292.0
|
offset_right = 292.0
|
||||||
offset_bottom = 55.0
|
offset_bottom = 66.0
|
||||||
columns = 2
|
columns = 2
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Properties/GridContainer"]
|
[node name="OpacityLabel" type="Label" parent="Properties/GridContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Opacity:"
|
||||||
|
|
||||||
|
[node name="OpacitySlider" type="TextureProgressBar" parent="Properties/GridContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_default_cursor_shape = 2
|
||||||
|
theme_type_variation = &"ValueSlider"
|
||||||
|
value = 100.0
|
||||||
|
nine_patch_stretch = true
|
||||||
|
stretch_margin_left = 3
|
||||||
|
stretch_margin_top = 3
|
||||||
|
stretch_margin_right = 3
|
||||||
|
stretch_margin_bottom = 3
|
||||||
|
script = ExtResource("4_wcpcc")
|
||||||
|
|
||||||
|
[node name="ZIndexLabel" type="Label" parent="Properties/GridContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
text = "Z-Index:"
|
text = "Z-Index:"
|
||||||
|
@ -109,4 +129,5 @@ script = ExtResource("4_wcpcc")
|
||||||
[connection signal="resized" from="." to="." method="_on_CelButton_resized"]
|
[connection signal="resized" from="." to="." method="_on_CelButton_resized"]
|
||||||
[connection signal="id_pressed" from="PopupMenu" to="." method="_on_PopupMenu_id_pressed"]
|
[connection signal="id_pressed" from="PopupMenu" to="." method="_on_PopupMenu_id_pressed"]
|
||||||
[connection signal="visibility_changed" from="Properties" to="." method="_on_properties_visibility_changed"]
|
[connection signal="visibility_changed" from="Properties" to="." method="_on_properties_visibility_changed"]
|
||||||
|
[connection signal="value_changed" from="Properties/GridContainer/OpacitySlider" to="." method="_on_opacity_slider_value_changed"]
|
||||||
[connection signal="value_changed" from="Properties/GridContainer/ZIndexSlider" to="." method="_on_z_index_slider_value_changed"]
|
[connection signal="value_changed" from="Properties/GridContainer/ZIndexSlider" to="." method="_on_z_index_slider_value_changed"]
|
||||||
|
|
Loading…
Reference in a new issue