palette_window.gd 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. extends Control
  2. @onready var avatar_type_combo: OptionButton = $VBoxContainer/HSplitContainer/VSplitContainer/PanelContainer/MarginContainer/VBoxContainer/AvatarTypeCombo
  3. @onready var avatar_part_listview: Tree = $VBoxContainer/HSplitContainer/VSplitContainer/PanelContainer/MarginContainer/VBoxContainer/AvatarPartListview
  4. @onready var palette_listview: Tree = $VBoxContainer/HSplitContainer/VSplitContainer/PanelContainer2/MarginContainer2/VBoxContainer/PaletteListview
  5. @onready var main_content_tab_container: TabBar = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/VBoxContainer/PanelContainer2/MainContentTabContainer
  6. @onready var state_selecter: PanelContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/StateSelecter
  7. @onready var palette_param_container: VBoxContainer = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer2/PanelContainer2/MarginContainer/VBoxContainer/ScrollContainer/ParamVBoxContainer
  8. @onready var palette_add_button: Button = $VBoxContainer/HSplitContainer/VSplitContainer/PanelContainer2/MarginContainer2/VBoxContainer/HBoxContainer/Add
  9. @onready var palette_param_add_button: Button = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer2/PanelContainer2/MarginContainer/VBoxContainer/HBoxContainer/Add
  10. @onready var canvas_2d: Node2D = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer/VBoxContainer/PanelContainer/SubViewportContainer/SubViewport/Canvas2d
  11. @onready var palette_property_rich_text_label: RichTextLabel = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer2/PanelContainer/MarginContainer/VBoxContainer/PalettePropertyRichTextLabel
  12. @onready var guid_line_edit: LineEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer2/PanelContainer/MarginContainer/VBoxContainer/GridContainer/GuidLineEdit
  13. @onready var name_line_edit: LineEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer2/PanelContainer/MarginContainer/VBoxContainer/GridContainer/NameLineEdit
  14. @onready var intro_text_edit: TextEdit = $VBoxContainer/HSplitContainer/HSplitContainer/VSplitContainer2/PanelContainer/MarginContainer/VBoxContainer/GridContainer/IntroTextEdit
  15. const MAX_PALETTE_PARAM_PANEL = 8
  16. const PALETTE_PARAM_PANEL = preload("res://Scenes/control/PaletteParamPanel.tscn")
  17. const ICON_DELETE: Texture2D = preload("res://Resources/UI/Trash.png")
  18. const ICON_UP: Texture2D = preload("res://Resources/UI/Up.png")
  19. const ICON_DOWN: Texture2D = preload("res://Resources/UI/Down.png")
  20. var palette_param_panels = []
  21. var palette_param_panel_data = []
  22. var palette_param_count = 0
  23. var camera_zoom_texture = 100
  24. var camera_position_texture = Vector2.ZERO
  25. var camera_zoom_icon = 100
  26. var camera_position_icon = Vector2.ZERO
  27. var _current_avatar_type = "Clothes"
  28. var _current_avatar_index = -1
  29. var _current_part
  30. var _current_palette_index = -1
  31. var _current_part_assets = {}
  32. var _current_state_code = null
  33. func _ready() -> void:
  34. _init_gui()
  35. func _init_gui():
  36. canvas_2d.set_editable(false)
  37. visibility_changed.connect(_on_visibility_changed)
  38. avatar_type_combo.item_selected.connect(_on_avatar_type_combo_item_selected)
  39. main_content_tab_container.tab_changed.connect(_on_main_content_tab_container_tab_changed)
  40. state_selecter.state_selected.connect(_on_state_selected)
  41. # avatar_part
  42. avatar_part_listview.columns = 2
  43. avatar_part_listview.hide_root = true
  44. avatar_part_listview.set_column_title(0, "ID")
  45. avatar_part_listview.set_column_title(1, "Name")
  46. avatar_part_listview.set_column_custom_minimum_width(0, 80)
  47. avatar_part_listview.set_column_expand(0, false)
  48. avatar_part_listview.set_column_expand(1, true)
  49. avatar_part_listview.item_selected.connect(_on_avatar_part_listview_item_selected)
  50. # palette
  51. palette_add_button.pressed.connect(_on_palette_add_button_preessed)
  52. palette_listview.columns = 5
  53. palette_listview.hide_root = true
  54. palette_listview.set_column_title(0, "ID")
  55. palette_listview.set_column_title(1, "Name")
  56. palette_listview.set_column_custom_minimum_width(0, 40)
  57. palette_listview.set_column_custom_minimum_width(2, 16)
  58. palette_listview.set_column_custom_minimum_width(3, 16)
  59. palette_listview.set_column_custom_minimum_width(4, 16)
  60. palette_listview.set_column_expand(0, false)
  61. palette_listview.set_column_expand(1, true)
  62. palette_listview.set_column_expand(2, false)
  63. palette_listview.set_column_expand(3, false)
  64. palette_listview.set_column_expand(4, false)
  65. palette_listview.item_selected.connect(_on_palette_listview_item_selected)
  66. # palette_param
  67. palette_param_add_button.pressed.connect(_on_palette_param_add_button_preessed)
  68. for i in range(MAX_PALETTE_PARAM_PANEL):
  69. var param_panel = PALETTE_PARAM_PANEL.instantiate()
  70. param_panel.name = "palette_param_%d" % i
  71. param_panel.visible = false
  72. palette_param_panel_data.append({})
  73. palette_param_panels.append(param_panel)
  74. palette_param_container.add_child(param_panel)
  75. param_panel.reset_parameters()
  76. param_panel.value_change.connect(_on_palette_param_panel_value_change)
  77. param_panel.action.connect(_on_palette_param_panel_action)
  78. # palette property
  79. name_line_edit.text_changed.connect(_on_name_line_edit_text_submitted)
  80. intro_text_edit.text_changed.connect(_on_intro_text_edit_text_submitted)
  81. func load_data():
  82. if AvatarDollDataMgr.initialed == false:
  83. return
  84. update_avatar_part_listview()
  85. func update_avatar_part_listview(selected_index=-1):
  86. if AvatarDollDataMgr.initialed == false:
  87. return
  88. _current_part = null
  89. _current_part_assets = {}
  90. _current_avatar_index = -1
  91. _current_state_code = null
  92. avatar_part_listview.clear()
  93. avatar_part_listview.create_item() # root
  94. var _data = AvatarDollDataMgr.avatar_doll_data
  95. if not _data.has(_current_avatar_type):
  96. return
  97. for i in _data[_current_avatar_type].size():
  98. var part = _data[_current_avatar_type][i]
  99. var row = avatar_part_listview.create_item()
  100. row.set_text(0, "%d" % i)
  101. row.set_text(1, part["Name"])
  102. if i == selected_index:
  103. avatar_part_listview.set_selected(row, 0)
  104. func update_state_selecter(select_code = null):
  105. if AvatarDollDataMgr.initialed == false or _current_part == null:
  106. _current_state_code = null
  107. state_selecter.load_data(null)
  108. return
  109. _current_state_code = null
  110. state_selecter.load_data(_current_avatar_type, _current_part)
  111. if select_code in _current_part["Elements"]:
  112. _current_state_code = select_code
  113. state_selecter.set_state_list_select(_current_state_code)
  114. elif _current_part["Elements"].size() > 0:
  115. _current_state_code = _current_part["Elements"].keys()[0]
  116. state_selecter.set_state_list_select(_current_state_code)
  117. func update_palette_listview(selected_index=-1, rebuild=true):
  118. palette_listview.deselect_all()
  119. if rebuild:
  120. palette_listview.clear()
  121. palette_listview.create_item() # root
  122. if AvatarDollDataMgr.initialed == false or _current_part == null or _current_state_code == null:
  123. _current_part_assets = {}
  124. return
  125. # palette_listview
  126. palette_listview.set_block_signals(true)
  127. if rebuild:
  128. var row = palette_listview.create_item() # default
  129. row.set_text(0, "-1")
  130. row.set_text(1, "Default")
  131. for i in _current_part["Palettes"].size():
  132. var palette = _current_part["Palettes"][i]
  133. if rebuild:
  134. var row = palette_listview.create_item()
  135. row.set_cell_mode(2, TreeItem.CELL_MODE_ICON)
  136. row.set_cell_mode(3, TreeItem.CELL_MODE_ICON)
  137. row.set_cell_mode(4, TreeItem.CELL_MODE_ICON)
  138. row.set_text(0, "%d" % i)
  139. row.set_text(1, palette["Name"])
  140. row.set_icon(2, ICON_UP if i > 0 else null)
  141. row.set_icon(3, ICON_DOWN if i < _current_part["Palettes"].size() - 1 else null)
  142. row.set_icon(4, ICON_DELETE)
  143. else:
  144. var row = palette_listview.get_root().get_child(i + 1)
  145. row.set_text(0, "%d" % i)
  146. row.set_text(1, palette["Name"])
  147. row.set_icon(2, ICON_UP if i > 0 else null)
  148. row.set_icon(3, ICON_DOWN if i < _current_part["Palettes"].size() - 1 else null)
  149. # finish
  150. if selected_index >= 0 and selected_index < _current_part["Palettes"].size():
  151. _current_palette_index = selected_index
  152. var item = palette_listview.get_root().get_child(selected_index + 1)
  153. palette_listview.set_selected(item, 0)
  154. else:
  155. _current_palette_index = -1
  156. palette_listview.set_selected(palette_listview.get_root().get_child(0), 0)
  157. palette_listview.set_block_signals(false)
  158. palette_listview.queue_redraw()
  159. func update_palette_property():
  160. if AvatarDollDataMgr.initialed == false or _current_part == null or _current_state_code == null:
  161. name_line_edit.editable = false
  162. intro_text_edit.editable = false
  163. guid_line_edit.text = ""
  164. name_line_edit.text = ""
  165. intro_text_edit.text = ""
  166. palette_property_rich_text_label.text = "[font_size=20][b]Property[/b][/font_size]"
  167. return
  168. name_line_edit.editable = true
  169. intro_text_edit.editable = true
  170. if _current_palette_index < 0:
  171. palette_property_rich_text_label.text = "[font_size=20][b]Property [Default][/b][/font_size]"
  172. guid_line_edit.text = str(_current_palette_index)
  173. name_line_edit.text = _current_part["Name"]
  174. intro_text_edit.text = _current_part["Introduction"]
  175. else:
  176. palette_property_rich_text_label.text = "[font_size=20][b]Property [Palette %d][/b][/font_size]" % _current_palette_index
  177. guid_line_edit.text = str(_current_palette_index)
  178. name_line_edit.text = _current_part["Palettes"][_current_palette_index]["Name"]
  179. intro_text_edit.text = _current_part["Palettes"][_current_palette_index]["Introduction"]
  180. func update_palette_param():
  181. if AvatarDollDataMgr.initialed == false or _current_part == null or _current_state_code == null:
  182. _current_part_assets = {}
  183. palette_param_add_button.disabled = true
  184. for i in range(MAX_PALETTE_PARAM_PANEL):
  185. palette_param_panels[i].visible = false
  186. return
  187. # set enable
  188. var palette_param = []
  189. if _current_palette_index < 0:
  190. palette_param_count = 0
  191. palette_param_add_button.disabled = true
  192. else:
  193. palette_param = get_current_palette_param_list()
  194. palette_param_count = min(MAX_PALETTE_PARAM_PANEL, palette_param.size())
  195. palette_param_add_button.disabled = false
  196. # update asset combo
  197. var assets = {}
  198. assets[-1] = "All"
  199. if main_content_tab_container.current_tab == 0:
  200. var elements = _current_part["Elements"][_current_state_code]
  201. for i in elements.size():
  202. var asset_name = AvatarDollDataMgr.get_asset_name(elements[i]["AssetId"])
  203. if asset_name != "__blank__":
  204. assets[i] = asset_name
  205. _current_part_assets = assets
  206. for i in range(MAX_PALETTE_PARAM_PANEL):
  207. var param_panel = palette_param_panels[i]
  208. param_panel.set_block_signal(true)
  209. param_panel.setup_data(i, _current_part_assets, i==0, i == palette_param_count - 1)
  210. param_panel.set_block_signal(false)
  211. param_panel.visible = false
  212. # set param
  213. for i in range(MAX_PALETTE_PARAM_PANEL):
  214. var param_panel = palette_param_panels[i]
  215. if i < palette_param_count:
  216. param_panel.visible = true
  217. var param = palette_param[i]
  218. var basic_color = Color(param["BasicColor"]["R"], param["BasicColor"]["G"], param["BasicColor"]["B"], param["BasicColor"]["A"])
  219. var modulate_color = Color(param["ModulateColor"]["R"], param["ModulateColor"]["G"], param["ModulateColor"]["B"], param["ModulateColor"]["A"])
  220. palette_param_panel_data[i] = param
  221. param_panel.set_block_signal(true)
  222. param_panel.load_parameters(param["ElementIndex"], basic_color, param["Tolerance"], modulate_color, int(param["BlendMode"]))
  223. param_panel.set_block_signal(false)
  224. else:
  225. param_panel.visible = false
  226. update_canvas()
  227. func get_current_palette_param_list():
  228. if _current_palette_index == -1 or _current_part == null:
  229. return []
  230. var color_palette = _current_part["Palettes"][_current_palette_index]
  231. if main_content_tab_container.current_tab == 0:
  232. return color_palette["ElementPaletteParam"]
  233. else:
  234. return color_palette["IconPaletteParam"]
  235. func update_canvas():
  236. if AvatarDollDataMgr.initialed == false or _current_part == null or _current_state_code == null:
  237. canvas_2d.load_elements([])
  238. canvas_2d.zoom_fit()
  239. return
  240. if main_content_tab_container.current_tab == 0:
  241. var palettes = AvatarDollDataMgr.get_render_palettes(
  242. _current_avatar_type,
  243. _current_avatar_index,
  244. _current_state_code,
  245. _current_palette_index,
  246. false)
  247. var elements = _current_part["Elements"][_current_state_code]
  248. canvas_2d.load_elements(elements)
  249. for element_index in palettes:
  250. canvas_2d.update_palette(element_index, palettes[element_index])
  251. else:
  252. canvas_2d.load_icon(_current_part["IconAssetId"])
  253. canvas_2d.update_palette(0, get_current_palette_param_list())
  254. canvas_2d.queue_redraw()
  255. func _on_visibility_changed() -> void:
  256. if is_visible_in_tree() == true:
  257. update_avatar_part_listview(_current_avatar_index)
  258. update_state_selecter(_current_state_code)
  259. update_palette_listview(_current_palette_index)
  260. update_palette_property()
  261. update_palette_param()
  262. update_canvas()
  263. canvas_2d.sync_background()
  264. else:
  265. canvas_2d.cancle_free_transform()
  266. func _on_avatar_type_combo_item_selected(_index: int) -> void:
  267. _current_avatar_type = avatar_type_combo.get_item_text(avatar_type_combo.selected)
  268. update_avatar_part_listview()
  269. update_state_selecter()
  270. update_palette_listview()
  271. update_palette_property()
  272. update_palette_param()
  273. update_canvas()
  274. func _on_avatar_part_listview_item_selected():
  275. _current_avatar_index = int(avatar_part_listview.get_selected().get_text(0))
  276. _current_part = AvatarDollDataMgr.avatar_doll_data[_current_avatar_type][_current_avatar_index]
  277. update_state_selecter(_current_state_code)
  278. update_palette_listview()
  279. update_palette_property()
  280. update_palette_param()
  281. update_canvas()
  282. canvas_2d.zoom_fit()
  283. func _on_palette_add_button_preessed():
  284. if _current_part == null:
  285. return
  286. var palette_data = {
  287. "Guid": 0,
  288. "Name": "Palette %d" % _current_part["Palettes"].size(),
  289. "Introduction": "",
  290. "IconPaletteParam": [],
  291. "ElementPaletteParam": []
  292. }
  293. _current_part["Palettes"].append(palette_data)
  294. update_palette_listview(_current_part["Palettes"].size() - 1)
  295. update_palette_property()
  296. update_palette_param()
  297. update_canvas()
  298. func _on_palette_listview_item_selected():
  299. var index = int(palette_listview.get_selected().get_text(0))
  300. _current_palette_index = index
  301. var column = palette_listview.get_column_at_position(palette_listview.get_local_mouse_position())
  302. if _current_palette_index >= 0:
  303. if column == 2 and _current_palette_index > 0:
  304. var temp = _current_part["Palettes"][_current_palette_index - 1]
  305. _current_part["Palettes"][_current_palette_index - 1] = _current_part["Palettes"][_current_palette_index]
  306. _current_part["Palettes"][_current_palette_index] = temp
  307. update_palette_listview(_current_palette_index - 1, false)
  308. elif column == 3 and _current_palette_index >= 0 and _current_palette_index < _current_part["Palettes"].size() - 1:
  309. var temp = _current_part["Palettes"][_current_palette_index + 1]
  310. _current_part["Palettes"][_current_palette_index + 1] = _current_part["Palettes"][_current_palette_index]
  311. _current_part["Palettes"][_current_palette_index] = temp
  312. update_palette_listview(_current_palette_index + 1, false)
  313. elif column == 4:
  314. var msg = "确定要删除 Palette %d (%s) 吗?" % [_current_palette_index, _current_part["Palettes"][_current_palette_index]["Name"]]
  315. var msg_box = MessageBox.question(self,
  316. "提示", msg,
  317. MessageBox.StandardButton.YES | MessageBox.StandardButton.NO)
  318. msg_box.accepted.connect(func():
  319. _current_part["Palettes"].remove_at(_current_palette_index)
  320. _current_palette_index = -1
  321. update_palette_listview()
  322. update_palette_property()
  323. update_palette_param()
  324. update_canvas()
  325. )
  326. update_palette_property()
  327. update_palette_param()
  328. update_canvas()
  329. func _on_main_content_tab_container_tab_changed(new_index: int):
  330. update_palette_listview(_current_palette_index)
  331. if new_index == 0:
  332. state_selecter.visible = true
  333. camera_position_icon = canvas_2d.camera.position
  334. camera_zoom_icon = canvas_2d.current_zoom
  335. canvas_2d.zoom_camera(camera_zoom_texture)
  336. canvas_2d.camera.position = camera_position_texture
  337. canvas_2d.set_background(Vector2(2048, 2048))
  338. else:
  339. state_selecter.visible = false
  340. camera_position_texture = canvas_2d.camera.position
  341. camera_zoom_texture = canvas_2d.current_zoom
  342. canvas_2d.zoom_camera(camera_zoom_icon)
  343. canvas_2d.camera.position = camera_position_icon
  344. canvas_2d.set_background(Vector2(64, 64))
  345. update_canvas()
  346. func _on_palette_param_panel_action(index, action):
  347. match action:
  348. "UP":
  349. var palette_param = get_current_palette_param_list()
  350. var t = palette_param[index - 1]
  351. palette_param[index - 1] = palette_param[index]
  352. palette_param[index] = t
  353. update_palette_param()
  354. "DOWN":
  355. var palette_param = get_current_palette_param_list()
  356. var t = palette_param[index + 1]
  357. palette_param[index + 1] = palette_param[index]
  358. palette_param[index] = t
  359. update_palette_param()
  360. "REMOVE":
  361. var msg_box = MessageBox.warning(self, "警告", "确定删除吗?", MessageBox.StandardButton.YES | MessageBox.StandardButton.NO)
  362. msg_box.accepted.connect(func():
  363. var palette_param = get_current_palette_param_list()
  364. palette_param.remove_at(index)
  365. update_palette_param()
  366. )
  367. func _on_palette_param_add_button_preessed():
  368. if not AvatarDollDataMgr.initialed or palette_param_count >= MAX_PALETTE_PARAM_PANEL:
  369. return
  370. var panel = palette_param_panels[palette_param_count]
  371. var palette_param = get_current_palette_param_list()
  372. palette_param.append(panel.get_paramters())
  373. panel.reset_parameters()
  374. palette_param_count += 1
  375. for i in range(MAX_PALETTE_PARAM_PANEL):
  376. panel = palette_param_panels[i]
  377. if i < palette_param_count:
  378. panel.visible = true
  379. else:
  380. panel.visible = false
  381. palette_param_panels[palette_param_count - 1].set_selected(true)
  382. func _on_palette_param_panel_value_change(index: int, data):
  383. var palette_param = get_current_palette_param_list()
  384. palette_param[index] = data
  385. update_canvas()
  386. func _on_state_selected(state_code: String):
  387. _current_state_code = state_code
  388. update_palette_param()
  389. update_canvas()
  390. func _on_name_line_edit_text_submitted(new_text):
  391. if not AvatarDollDataMgr.initialed or _current_part == null:
  392. return
  393. var new_name = name_line_edit.text
  394. if _current_palette_index < 0:
  395. _current_part["Name"] = new_name
  396. avatar_part_listview.get_root().get_child(_current_avatar_index).set_text(1, new_name)
  397. else:
  398. _current_part["Palettes"][_current_palette_index]["Name"] = new_name
  399. palette_listview.get_root().get_child(_current_palette_index + 1).set_text(1, new_name)
  400. func _on_intro_text_edit_text_submitted():
  401. if not AvatarDollDataMgr.initialed or _current_part == null:
  402. return
  403. if _current_palette_index < 0:
  404. _current_part["Introduction"] = intro_text_edit.text
  405. else:
  406. _current_part["Palettes"][_current_palette_index]["Introduction"] = intro_text_edit.text