| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- extends PanelContainer
- @onready var avatar_type_combo: OptionButton = $VBoxContainer/MarginContainer/ToolBar/AvatarTypeCombo
- @onready var avatar_part_combo: OptionButton = $VBoxContainer/MarginContainer/ToolBar/AvatarPartCombo
- @onready var palette_combo: OptionButton = $VBoxContainer/MarginContainer/ToolBar/PaletteCombo
- @onready var state_panel: VBoxContainer = $VBoxContainer/HSplitContainer/StatePanel
- @onready var canvas_2d: Node2D = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer/SubViewportContainer/SubViewport/Canvas2d
- @onready var sub_viewport_container: SubViewportContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer/SubViewportContainer
- @onready var asset_panel: PanelContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer2/AssetPanel
- @onready var panel_container: PanelContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer
- @onready var asset_line_edit: LineEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/AssetLineEdit
- @onready var layer_line_edit: LineEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerLineEdit
- @onready var layer_button: Button = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerButton
- @onready var layer_offset_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/LayerOffsetSpinBox
- @onready var position_x_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer2/PositionXSpinBox
- @onready var position_y_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer2/PositionYSpinBox
- @onready var rotation_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/RotationSpinBox
- @onready var scale_x_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer4/ScaleXSpinBox
- @onready var scale_y_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer4/ScaleYSpinBox
- @onready var popup_panel: PopupPanel = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerButton/PopupPanel
- @onready var layer_selecter: Panel = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerButton/PopupPanel/LayerSelecter
- var avatar_type: String = "Clothes"
- var _current_part = null
- var _current_state = null
- var _current_elements = null
- var _current_element_index = -1
- var _current_element = null
- func _ready() -> void:
- state_panel.avatar_type = avatar_type
- _init_gui()
- func _init_gui():
-
- get_tree().get_root().files_dropped.connect(_on_files_dropped)
- visibility_changed.connect(_on_visibility_changed)
-
- avatar_type_combo.item_selected.connect(_on_avatar_type_combo_item_selected)
-
- sub_viewport_container.mouse_entered.connect(_on_canvas_mouse_entered)
- sub_viewport_container.mouse_exited.connect(_on_canvas_mouse_exited)
- canvas_2d.element_property_changed.connect(_on_canvas_element_property_changed)
- canvas_2d.element_selected.connect(_on_canvas_element_selected)
- canvas_2d.element_action.connect(_on_canvas_element_action, ConnectFlags.CONNECT_DEFERRED)
- canvas_2d.asset_drop.connect(_on_asset_dropped)
- asset_panel.asset_updated.connect(_on_asset_updated)
- avatar_part_combo.item_selected.connect(_on_avatar_part_combo_item_selected)
- state_panel.on_select_change.connect(_on_state_treeview_select_change)
- palette_combo.item_selected.connect(_on_palette_combo_item_selected)
-
- position_x_spin_box.value_changed.connect(_on_property_changed.bind("PositionX"))
- position_y_spin_box.value_changed.connect(_on_property_changed.bind("PositionY"))
- rotation_spin_box.value_changed.connect(_on_property_changed.bind("Rotation"))
- scale_x_spin_box.value_changed.connect(_on_property_changed.bind("ScaleX"))
- scale_y_spin_box.value_changed.connect(_on_property_changed.bind("ScaleY"))
- layer_button.pressed.connect(_on_layer_button_pressed)
- layer_selecter.pressed.connect(_on_layer_selecter_pressed)
- func _on_visibility_changed() -> void:
- if is_visible_in_tree() == true:
- #load_data()
- update_data()
- canvas_2d.sync_background()
- else:
- canvas_2d.cancle_free_transform()
- func load_data():
- if AvatarDollDataMgr.initialed == false or avatar_type not in AvatarDollDataMgr.avatar_doll_data:
- avatar_part_combo.clear()
- return
-
- avatar_part_combo.clear()
- var parts = AvatarDollDataMgr.avatar_doll_data[avatar_type]
- for part in parts:
- avatar_part_combo.add_item(part["Name"])
-
- if parts.size() > 0:
- avatar_part_combo.selected = 0
- _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][0]
-
- palette_combo.clear()
- palette_combo.add_item("Default")
- for i in range(_current_part["Palettes"].size()):
- var palette = _current_part["Palettes"][i]
- palette_combo.add_item(palette["Name"])
- else:
- _current_part = null
-
- state_panel.set_avatar_type(0, true)
- update_data()
- pass
- func update_data():
- if _current_part != null:
- var part_index = avatar_part_combo.selected
- _current_state = state_panel.current_state_code
- _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][part_index]
- _current_element = null
- _current_element_index = -1
- state_panel.set_avatar_type(part_index, false)
- if _current_state in _current_part["Elements"]:
- _current_elements = _current_part["Elements"][_current_state]
- canvas_2d.set_editable(true)
- canvas_2d.load_elements(_current_elements)
-
- elif _current_state != "":
- _current_elements = []
- _current_part["Elements"][_current_state] = _current_elements
- canvas_2d.set_editable(true)
- canvas_2d.load_elements(_current_elements)
-
- else:
- _current_elements = null
- canvas_2d.set_editable(false)
- canvas_2d.load_elements([])
- canvas_2d.zoom_fit()
-
- # palette
- palette_combo.clear()
- palette_combo.add_item("Default")
- for i in range(_current_part["Palettes"].size()):
- var palette = _current_part["Palettes"][i]
- palette_combo.add_item(palette["Name"])
-
- asset_panel.update_data()
- else:
- canvas_2d.load_elements([])
- canvas_2d.set_editable(false)
- update_property()
- pass
-
- func update_property():
- if _current_element != null:
- asset_line_edit.text = AvatarDollDataMgr.get_asset_name(_current_element["AssetId"])
- layer_line_edit.text = str(_current_element["Layer"])
- layer_offset_spin_box.set_value_no_signal(_current_element["LayerOffset"])
- position_x_spin_box.set_value_no_signal(_current_element["PositionX"])
- position_y_spin_box.set_value_no_signal(_current_element["PositionY"])
- rotation_spin_box.set_value_no_signal(_current_element["Rotation"])
- scale_x_spin_box.set_value_no_signal(_current_element["ScaleX"])
- scale_y_spin_box.set_value_no_signal(_current_element["ScaleY"])
-
- layer_button.disabled = false
- layer_offset_spin_box.editable = true
- position_x_spin_box.editable = true
- position_y_spin_box.editable = true
- rotation_spin_box.editable = true
- scale_x_spin_box.editable = true
- scale_y_spin_box.editable = true
-
- else:
- asset_line_edit.text = "-1"
- layer_line_edit.text = "0"
- layer_offset_spin_box.set_value_no_signal(0)
- position_x_spin_box.set_value_no_signal(0)
- position_y_spin_box.set_value_no_signal(0)
- rotation_spin_box.set_value_no_signal(0)
- scale_x_spin_box.set_value_no_signal(0)
- scale_y_spin_box.set_value_no_signal(0)
-
- layer_button.disabled = true
- layer_offset_spin_box.editable = false
- position_x_spin_box.editable = false
- position_y_spin_box.editable = false
- rotation_spin_box.editable = false
- scale_x_spin_box.editable = false
- scale_y_spin_box.editable = false
- func set_select(new_type, part_index, state_code, element_index):
- if AvatarDollDataMgr.initialed == false or new_type not in AvatarDollDataMgr.avatar_doll_data:
- return
-
- avatar_type_combo.set_block_signals(true)
- avatar_type_combo.selected = AvatarDollDataMgr.avatar_part_scope.keys().find(new_type)
- avatar_type_combo.set_block_signals(false)
- state_panel.avatar_type = new_type
- avatar_type = new_type
- load_data()
-
- if part_index < AvatarDollDataMgr.avatar_doll_data[avatar_type].size():
- avatar_part_combo.selected = part_index
- _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][part_index]
-
- if state_code in _current_part["Elements"]:
- state_panel.set_state_code(state_code)
- _current_state = state_code
-
- if element_index >= 0 and element_index < _current_part["Elements"][state_code].size():
- _current_elements = _current_part["Elements"][state_code]
- _current_element_index = element_index
- _current_element = _current_elements[element_index]
- canvas_2d.load_elements(_current_elements, element_index)
-
- #update_property()
- func set_palette(index):
- var state_code = state_panel.current_state_code
- if state_code not in _current_part["Elements"]:
- _current_state = null
- return
- var palettes = AvatarDollDataMgr.get_render_palettes(avatar_type, avatar_part_combo.selected, state_code, index - 1, false)
- for asset_name in palettes:
- canvas_2d.update_palette(asset_name, palettes[asset_name])
- func _on_avatar_type_combo_item_selected(index):
- avatar_type = avatar_type_combo.get_item_text(index)
- state_panel.avatar_type = avatar_type
- load_data()
- func _on_avatar_part_combo_item_selected(index):
- _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][index]
-
- update_data()
- canvas_2d.zoom_fit()
- func _on_palette_combo_item_selected(index):
- set_palette(index)
- func _on_state_treeview_select_change(_avatar_type, _index, _state_code):
- update_data()
- set_palette(palette_combo.selected)
- canvas_2d.zoom_fit()
- func _on_canvas_mouse_entered():
- canvas_2d.update_mouse_in_canvas(true)
- func _on_canvas_mouse_exited():
- canvas_2d.update_mouse_in_canvas(false)
- func _on_canvas_element_selected(index: int):
- _current_element_index = index
- _current_element = _current_elements[index] if index != -1 else null
- update_property()
- func _on_canvas_element_property_changed(_index: int, _position: Vector2, _rotation: float, _scale: Vector2, _skew: float):
- if _current_part == null or _current_state == null:
- return
-
- _current_element["PositionX"] = _position.x
- _current_element["PositionY"] = _position.y
- _current_element["Rotation"] = _rotation
- _current_element["ScaleX"] = _scale.x
- _current_element["ScaleY"] = _scale.y
- _current_element["Skew"] = _skew
- update_property()
- func _on_canvas_element_action(index: int, action: String, data: Dictionary):
- if action == "UP" and index > 0:
- var temp = _current_elements[index - 1]
- _current_elements[index - 1] = _current_elements[index]
- _current_elements[index] = temp
- canvas_2d.load_elements(_current_elements, index - 1)
-
- elif action == "DOWN" and index < _current_elements.size() - 1:
- var temp = _current_elements[index + 1]
- _current_elements[index + 1] = _current_elements[index]
- _current_elements[index] = temp
- canvas_2d.load_elements(_current_elements, index + 1)
-
- elif action == "REMOVE":
- var msg = "确定删除 %s 吗?" % AvatarDollDataMgr.get_asset_name(_current_elements[index]["AssetId"])
- var msg_box = MessageBox.warning(self,
- "警告", msg,
- MessageBox.StandardButton.YES | MessageBox.StandardButton.NO)
- msg_box.accepted.connect(func():
- _current_elements.remove_at(index)
- canvas_2d.load_elements(_current_elements)
- state_panel.update_data()
- )
- pass
-
- func _on_property_changed(value, property: String):
- _current_element[property] = value
- update_property()
- canvas_2d.update_element(_current_element_index, _current_element)
- func _on_layer_button_pressed():
- var pos = layer_button.global_position + layer_button.get_rect().size
- pos.x -= popup_panel.size.x
- popup_panel.position = pos
- popup_panel.show()
- func _on_layer_selecter_pressed(index):
- popup_panel.hide()
- _current_element["Layer"] = index
- update_property()
-
- func _on_files_dropped(files):
- if not AvatarDollDataMgr.initialed:
- return
-
- if mouse_over_control(sub_viewport_container):
- if _current_state:
- for file_path in files:
- var asset_id = AvatarDollDataMgr.load_asset(file_path)
- if _current_elements != null:
- var element = {}
- element["AssetId"] = asset_id
- element["LayerOffset"] = 0
- element["PositionX"] = 0.0
- element["PositionY"] = 0.0
- element["Rotation"] = 0.0
- element["ScaleX"] = 1.0
- element["ScaleY"] = 1.0
- element["Skew"] = 0.0
-
- match avatar_type:
- "Bodies": element["Layer"] = 0
- "Heads": element["Layer"] = 9
- "Hairs": element["Layer"] = 10
- "Faces": element["Layer"] = 14
- "Clothes": element["Layer"] = 7
-
- _current_elements.append(element)
- update_data()
- canvas_2d.set_selected(_current_elements.size() - 1)
-
- else:
- for file_path in files:
- var asset_id = AvatarDollDataMgr.load_asset(file_path)
- update_data()
-
- elif mouse_over_control(asset_panel):
- for file_path in files:
- var asset_id = AvatarDollDataMgr.load_asset(file_path)
- update_data()
- func _on_asset_dropped(asset_name, pos):
- if _current_elements == null:
- return
-
- var element = {}
- element["AssetId"] = AvatarDollDataMgr.get_asset_id(asset_name)
- element["LayerOffset"] = 0
- element["PositionX"] = pos.x
- element["PositionY"] = pos.y
- element["Rotation"] = 0.0
- element["ScaleX"] = 1.0
- element["ScaleY"] = 1.0
- element["Skew"] = 0.0
-
- match avatar_type:
- "Bodies": element["Layer"] = 0
- "Heads": element["Layer"] = 9
- "Hairs": element["Layer"] = 10
- "Faces": element["Layer"] = 14
- "Clothes": element["Layer"] = 7
-
- _current_elements.append(element)
- update_data()
- canvas_2d.set_selected(_current_elements.size() - 1)
- func _on_asset_updated():
- update_data()
- func mouse_over_control(node: Control):
- var rect = node.get_global_transform() * node.get_rect()
- var mouse = get_global_mouse_position()
- return rect.has_point(mouse)
|