main_work_window.gd 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. extends PanelContainer
  2. @onready var avatar_type_combo: OptionButton = $VBoxContainer/MarginContainer/ToolBar/AvatarTypeCombo
  3. @onready var avatar_part_combo: OptionButton = $VBoxContainer/MarginContainer/ToolBar/AvatarPartCombo
  4. @onready var palette_combo: OptionButton = $VBoxContainer/MarginContainer/ToolBar/PaletteCombo
  5. @onready var state_panel: VBoxContainer = $VBoxContainer/HSplitContainer/StatePanel
  6. @onready var canvas_2d: Node2D = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer/SubViewportContainer/SubViewport/Canvas2d
  7. @onready var sub_viewport_container: SubViewportContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer/SubViewportContainer
  8. @onready var asset_panel: PanelContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer2/AssetPanel
  9. @onready var panel_container: PanelContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/PanelContainer
  10. @onready var asset_line_edit: LineEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/AssetLineEdit
  11. @onready var layer_line_edit: LineEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerLineEdit
  12. @onready var layer_button: Button = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerButton
  13. @onready var layer_offset_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/LayerOffsetSpinBox
  14. @onready var position_x_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer2/PositionXSpinBox
  15. @onready var position_y_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer2/PositionYSpinBox
  16. @onready var rotation_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/RotationSpinBox
  17. @onready var scale_x_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer4/ScaleXSpinBox
  18. @onready var scale_y_spin_box: SpinBox = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer4/ScaleYSpinBox
  19. @onready var popup_panel: PopupPanel = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerButton/PopupPanel
  20. @onready var layer_selecter: Panel = $VBoxContainer/HSplitContainer/HSplitContainer/VBoxContainer2/PanelContainer2/MarginContainer/VBoxContainer/GridContainer/HBoxContainer/LayerButton/PopupPanel/LayerSelecter
  21. var avatar_type: String = "Clothes"
  22. var _current_part = null
  23. var _current_state = null
  24. var _current_elements = null
  25. var _current_element_index = -1
  26. var _current_element = null
  27. func _ready() -> void:
  28. state_panel.avatar_type = avatar_type
  29. _init_gui()
  30. func _init_gui():
  31. get_tree().get_root().files_dropped.connect(_on_files_dropped)
  32. visibility_changed.connect(_on_visibility_changed)
  33. avatar_type_combo.item_selected.connect(_on_avatar_type_combo_item_selected)
  34. sub_viewport_container.mouse_entered.connect(_on_canvas_mouse_entered)
  35. sub_viewport_container.mouse_exited.connect(_on_canvas_mouse_exited)
  36. canvas_2d.element_property_changed.connect(_on_canvas_element_property_changed)
  37. canvas_2d.element_selected.connect(_on_canvas_element_selected)
  38. canvas_2d.element_action.connect(_on_canvas_element_action, ConnectFlags.CONNECT_DEFERRED)
  39. canvas_2d.asset_drop.connect(_on_asset_dropped)
  40. asset_panel.asset_updated.connect(_on_asset_updated)
  41. avatar_part_combo.item_selected.connect(_on_avatar_part_combo_item_selected)
  42. state_panel.on_select_change.connect(_on_state_treeview_select_change)
  43. palette_combo.item_selected.connect(_on_palette_combo_item_selected)
  44. position_x_spin_box.value_changed.connect(_on_property_changed.bind("PositionX"))
  45. position_y_spin_box.value_changed.connect(_on_property_changed.bind("PositionY"))
  46. rotation_spin_box.value_changed.connect(_on_property_changed.bind("Rotation"))
  47. scale_x_spin_box.value_changed.connect(_on_property_changed.bind("ScaleX"))
  48. scale_y_spin_box.value_changed.connect(_on_property_changed.bind("ScaleY"))
  49. layer_button.pressed.connect(_on_layer_button_pressed)
  50. layer_selecter.pressed.connect(_on_layer_selecter_pressed)
  51. func _on_visibility_changed() -> void:
  52. if is_visible_in_tree() == true:
  53. #load_data()
  54. update_data()
  55. canvas_2d.sync_background()
  56. else:
  57. canvas_2d.cancle_free_transform()
  58. func load_data():
  59. if AvatarDollDataMgr.initialed == false or avatar_type not in AvatarDollDataMgr.avatar_doll_data:
  60. avatar_part_combo.clear()
  61. return
  62. avatar_part_combo.clear()
  63. var parts = AvatarDollDataMgr.avatar_doll_data[avatar_type]
  64. for part in parts:
  65. avatar_part_combo.add_item(part["Name"])
  66. if parts.size() > 0:
  67. avatar_part_combo.selected = 0
  68. _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][0]
  69. palette_combo.clear()
  70. palette_combo.add_item("Default")
  71. for i in range(_current_part["Palettes"].size()):
  72. var palette = _current_part["Palettes"][i]
  73. palette_combo.add_item(palette["Name"])
  74. else:
  75. _current_part = null
  76. state_panel.set_avatar_type(0, true)
  77. update_data()
  78. pass
  79. func update_data():
  80. if _current_part != null:
  81. var part_index = avatar_part_combo.selected
  82. _current_state = state_panel.current_state_code
  83. _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][part_index]
  84. _current_element = null
  85. _current_element_index = -1
  86. state_panel.set_avatar_type(part_index, false)
  87. if _current_state in _current_part["Elements"]:
  88. _current_elements = _current_part["Elements"][_current_state]
  89. canvas_2d.set_editable(true)
  90. canvas_2d.load_elements(_current_elements)
  91. elif _current_state != "":
  92. _current_elements = []
  93. _current_part["Elements"][_current_state] = _current_elements
  94. canvas_2d.set_editable(true)
  95. canvas_2d.load_elements(_current_elements)
  96. else:
  97. _current_elements = null
  98. canvas_2d.set_editable(false)
  99. canvas_2d.load_elements([])
  100. canvas_2d.zoom_fit()
  101. # palette
  102. palette_combo.clear()
  103. palette_combo.add_item("Default")
  104. for i in range(_current_part["Palettes"].size()):
  105. var palette = _current_part["Palettes"][i]
  106. palette_combo.add_item(palette["Name"])
  107. asset_panel.update_data()
  108. else:
  109. canvas_2d.load_elements([])
  110. canvas_2d.set_editable(false)
  111. update_property()
  112. pass
  113. func update_property():
  114. if _current_element != null:
  115. asset_line_edit.text = AvatarDollDataMgr.get_asset_name(_current_element["AssetId"])
  116. layer_line_edit.text = str(_current_element["Layer"])
  117. layer_offset_spin_box.set_value_no_signal(_current_element["LayerOffset"])
  118. position_x_spin_box.set_value_no_signal(_current_element["PositionX"])
  119. position_y_spin_box.set_value_no_signal(_current_element["PositionY"])
  120. rotation_spin_box.set_value_no_signal(_current_element["Rotation"])
  121. scale_x_spin_box.set_value_no_signal(_current_element["ScaleX"])
  122. scale_y_spin_box.set_value_no_signal(_current_element["ScaleY"])
  123. layer_button.disabled = false
  124. layer_offset_spin_box.editable = true
  125. position_x_spin_box.editable = true
  126. position_y_spin_box.editable = true
  127. rotation_spin_box.editable = true
  128. scale_x_spin_box.editable = true
  129. scale_y_spin_box.editable = true
  130. else:
  131. asset_line_edit.text = "-1"
  132. layer_line_edit.text = "0"
  133. layer_offset_spin_box.set_value_no_signal(0)
  134. position_x_spin_box.set_value_no_signal(0)
  135. position_y_spin_box.set_value_no_signal(0)
  136. rotation_spin_box.set_value_no_signal(0)
  137. scale_x_spin_box.set_value_no_signal(0)
  138. scale_y_spin_box.set_value_no_signal(0)
  139. layer_button.disabled = true
  140. layer_offset_spin_box.editable = false
  141. position_x_spin_box.editable = false
  142. position_y_spin_box.editable = false
  143. rotation_spin_box.editable = false
  144. scale_x_spin_box.editable = false
  145. scale_y_spin_box.editable = false
  146. func set_select(new_type, part_index, state_code, element_index):
  147. if AvatarDollDataMgr.initialed == false or new_type not in AvatarDollDataMgr.avatar_doll_data:
  148. return
  149. avatar_type_combo.set_block_signals(true)
  150. avatar_type_combo.selected = AvatarDollDataMgr.avatar_part_scope.keys().find(new_type)
  151. avatar_type_combo.set_block_signals(false)
  152. state_panel.avatar_type = new_type
  153. avatar_type = new_type
  154. load_data()
  155. if part_index < AvatarDollDataMgr.avatar_doll_data[avatar_type].size():
  156. avatar_part_combo.selected = part_index
  157. _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][part_index]
  158. if state_code in _current_part["Elements"]:
  159. state_panel.set_state_code(state_code)
  160. _current_state = state_code
  161. if element_index >= 0 and element_index < _current_part["Elements"][state_code].size():
  162. _current_elements = _current_part["Elements"][state_code]
  163. _current_element_index = element_index
  164. _current_element = _current_elements[element_index]
  165. canvas_2d.load_elements(_current_elements, element_index)
  166. #update_property()
  167. func set_palette(index):
  168. var state_code = state_panel.current_state_code
  169. if state_code not in _current_part["Elements"]:
  170. _current_state = null
  171. return
  172. var palettes = AvatarDollDataMgr.get_render_palettes(avatar_type, avatar_part_combo.selected, state_code, index - 1, false)
  173. for asset_name in palettes:
  174. canvas_2d.update_palette(asset_name, palettes[asset_name])
  175. func _on_avatar_type_combo_item_selected(index):
  176. avatar_type = avatar_type_combo.get_item_text(index)
  177. state_panel.avatar_type = avatar_type
  178. load_data()
  179. func _on_avatar_part_combo_item_selected(index):
  180. _current_part = AvatarDollDataMgr.avatar_doll_data[avatar_type][index]
  181. update_data()
  182. canvas_2d.zoom_fit()
  183. func _on_palette_combo_item_selected(index):
  184. set_palette(index)
  185. func _on_state_treeview_select_change(_avatar_type, _index, _state_code):
  186. update_data()
  187. set_palette(palette_combo.selected)
  188. canvas_2d.zoom_fit()
  189. func _on_canvas_mouse_entered():
  190. canvas_2d.update_mouse_in_canvas(true)
  191. func _on_canvas_mouse_exited():
  192. canvas_2d.update_mouse_in_canvas(false)
  193. func _on_canvas_element_selected(index: int):
  194. _current_element_index = index
  195. _current_element = _current_elements[index] if index != -1 else null
  196. update_property()
  197. func _on_canvas_element_property_changed(_index: int, _position: Vector2, _rotation: float, _scale: Vector2, _skew: float):
  198. if _current_part == null or _current_state == null:
  199. return
  200. _current_element["PositionX"] = _position.x
  201. _current_element["PositionY"] = _position.y
  202. _current_element["Rotation"] = _rotation
  203. _current_element["ScaleX"] = _scale.x
  204. _current_element["ScaleY"] = _scale.y
  205. _current_element["Skew"] = _skew
  206. update_property()
  207. func _on_canvas_element_action(index: int, action: String, data: Dictionary):
  208. if action == "UP" and index > 0:
  209. var temp = _current_elements[index - 1]
  210. _current_elements[index - 1] = _current_elements[index]
  211. _current_elements[index] = temp
  212. canvas_2d.load_elements(_current_elements, index - 1)
  213. elif action == "DOWN" and index < _current_elements.size() - 1:
  214. var temp = _current_elements[index + 1]
  215. _current_elements[index + 1] = _current_elements[index]
  216. _current_elements[index] = temp
  217. canvas_2d.load_elements(_current_elements, index + 1)
  218. elif action == "REMOVE":
  219. var msg = "确定删除 %s 吗?" % AvatarDollDataMgr.get_asset_name(_current_elements[index]["AssetId"])
  220. var msg_box = MessageBox.warning(self,
  221. "警告", msg,
  222. MessageBox.StandardButton.YES | MessageBox.StandardButton.NO)
  223. msg_box.accepted.connect(func():
  224. _current_elements.remove_at(index)
  225. canvas_2d.load_elements(_current_elements)
  226. state_panel.update_data()
  227. )
  228. pass
  229. func _on_property_changed(value, property: String):
  230. _current_element[property] = value
  231. update_property()
  232. canvas_2d.update_element(_current_element_index, _current_element)
  233. func _on_layer_button_pressed():
  234. var pos = layer_button.global_position + layer_button.get_rect().size
  235. pos.x -= popup_panel.size.x
  236. popup_panel.position = pos
  237. popup_panel.show()
  238. func _on_layer_selecter_pressed(index):
  239. popup_panel.hide()
  240. _current_element["Layer"] = index
  241. update_property()
  242. func _on_files_dropped(files):
  243. if not AvatarDollDataMgr.initialed:
  244. return
  245. if mouse_over_control(sub_viewport_container):
  246. if _current_state:
  247. for file_path in files:
  248. var asset_id = AvatarDollDataMgr.load_asset(file_path)
  249. if _current_elements != null:
  250. var element = {}
  251. element["AssetId"] = asset_id
  252. element["LayerOffset"] = 0
  253. element["PositionX"] = 0.0
  254. element["PositionY"] = 0.0
  255. element["Rotation"] = 0.0
  256. element["ScaleX"] = 1.0
  257. element["ScaleY"] = 1.0
  258. element["Skew"] = 0.0
  259. match avatar_type:
  260. "Bodies": element["Layer"] = 0
  261. "Heads": element["Layer"] = 9
  262. "Hairs": element["Layer"] = 10
  263. "Faces": element["Layer"] = 14
  264. "Clothes": element["Layer"] = 7
  265. _current_elements.append(element)
  266. update_data()
  267. canvas_2d.set_selected(_current_elements.size() - 1)
  268. else:
  269. for file_path in files:
  270. var asset_id = AvatarDollDataMgr.load_asset(file_path)
  271. update_data()
  272. elif mouse_over_control(asset_panel):
  273. for file_path in files:
  274. var asset_id = AvatarDollDataMgr.load_asset(file_path)
  275. update_data()
  276. func _on_asset_dropped(asset_name, pos):
  277. if _current_elements == null:
  278. return
  279. var element = {}
  280. element["AssetId"] = AvatarDollDataMgr.get_asset_id(asset_name)
  281. element["LayerOffset"] = 0
  282. element["PositionX"] = pos.x
  283. element["PositionY"] = pos.y
  284. element["Rotation"] = 0.0
  285. element["ScaleX"] = 1.0
  286. element["ScaleY"] = 1.0
  287. element["Skew"] = 0.0
  288. match avatar_type:
  289. "Bodies": element["Layer"] = 0
  290. "Heads": element["Layer"] = 9
  291. "Hairs": element["Layer"] = 10
  292. "Faces": element["Layer"] = 14
  293. "Clothes": element["Layer"] = 7
  294. _current_elements.append(element)
  295. update_data()
  296. canvas_2d.set_selected(_current_elements.size() - 1)
  297. func _on_asset_updated():
  298. update_data()
  299. func mouse_over_control(node: Control):
  300. var rect = node.get_global_transform() * node.get_rect()
  301. var mouse = get_global_mouse_position()
  302. return rect.has_point(mouse)