No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CharacterEditor.gd 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. tool
  2. extends ScrollContainer
  3. var editor_reference
  4. onready var master_tree = get_node('../MasterTreeContainer/MasterTree')
  5. var opened_character_data
  6. var portrait_entry = load("res://addons/dialogic/Editor/CharacterEditor/PortraitEntry.tscn")
  7. onready var nodes = {
  8. 'editor': $HBoxContainer/Container,
  9. 'name': $HBoxContainer/Container/Name/LineEdit,
  10. 'description': $HBoxContainer/Container/Description/TextEdit,
  11. 'file': $HBoxContainer/Container/FileName/LineEdit,
  12. 'color': $HBoxContainer/Container/Color/ColorPickerButton,
  13. 'default_speaker': $HBoxContainer/Container/Actions/DefaultSpeaker,
  14. 'display_name_checkbox': $HBoxContainer/Container/Name/CheckBox,
  15. 'display_name': $HBoxContainer/Container/DisplayName/LineEdit,
  16. 'new_portrait_button': $HBoxContainer/Container/ScrollContainer/VBoxContainer/HBoxContainer/Button,
  17. 'portrait_preview': $HBoxContainer/VBoxContainer/Control/TextureRect,
  18. 'scale': $HBoxContainer/VBoxContainer/HBoxContainer/Scale,
  19. 'offset_x': $HBoxContainer/VBoxContainer/HBoxContainer/OffsetX,
  20. 'offset_y': $HBoxContainer/VBoxContainer/HBoxContainer/OffsetY,
  21. }
  22. func _ready():
  23. nodes['new_portrait_button'].connect('pressed', self, '_on_New_Portrait_Button_pressed')
  24. nodes['display_name_checkbox'].connect('toggled', self, '_on_display_name_toggled')
  25. nodes['name'].connect('text_changed', self, '_on_name_changed')
  26. nodes['color'].connect('color_changed', self, '_on_color_changed')
  27. var style = get('custom_styles/bg')
  28. style.set('bg_color', get_color("base_color", "Editor"))
  29. func is_selected(file: String):
  30. return nodes['file'].text == file
  31. func _on_display_name_toggled(button_pressed):
  32. $HBoxContainer/Container/DisplayName.visible = button_pressed
  33. func _on_name_changed(value):
  34. var item = master_tree.get_selected()
  35. item.set_text(0, value)
  36. save_character()
  37. master_tree.build_characters(nodes['file'].text)
  38. func _on_color_changed(color):
  39. var item = master_tree.get_selected()
  40. item.set_icon_modulate(0, color)
  41. func clear_character_editor():
  42. nodes['file'].text = ''
  43. nodes['name'].text = ''
  44. nodes['description'].text = ''
  45. nodes['color'].color = Color('#ffffff')
  46. nodes['default_speaker'].pressed = false
  47. nodes['display_name_checkbox'].pressed = false
  48. nodes['display_name'].text = ''
  49. nodes['portraits'] = []
  50. nodes['scale'].value = 100
  51. nodes['offset_x'].value = 0
  52. nodes['offset_y'].value = 0
  53. # Clearing portraits
  54. for p in $HBoxContainer/Container/ScrollContainer/VBoxContainer/PortraitList.get_children():
  55. p.queue_free()
  56. nodes['portrait_preview'].texture = null
  57. # Character Creation
  58. func create_character():
  59. var character_file = 'character-' + str(OS.get_unix_time()) + '.json'
  60. var character = {
  61. 'color': '#ffffff',
  62. 'id': character_file,
  63. 'default_speaker': false,
  64. 'portraits': []
  65. }
  66. DialogicResources.set_character(character)
  67. character['metadata'] = {'file': character_file}
  68. return character
  69. func new_character():
  70. # This event creates and selects the new character
  71. master_tree.build_characters(create_character()['metadata']['file'])
  72. # Saving and Loading
  73. func generate_character_data_to_save():
  74. var default_speaker: bool = nodes['default_speaker'].pressed
  75. var portraits = []
  76. for p in $HBoxContainer/Container/ScrollContainer/VBoxContainer/PortraitList.get_children():
  77. var entry = {}
  78. entry['name'] = p.get_node("NameEdit").text
  79. entry['path'] = p.get_node("PathEdit").text
  80. portraits.append(entry)
  81. var info_to_save = {
  82. 'id': nodes['file'].text,
  83. 'description': nodes['description'].text,
  84. 'color': '#' + nodes['color'].color.to_html(),
  85. 'default_speaker': default_speaker,
  86. 'portraits': portraits,
  87. 'display_name_bool': nodes['display_name_checkbox'].pressed,
  88. 'display_name': nodes['display_name'].text,
  89. 'scale': nodes['scale'].value,
  90. 'offset_x': nodes['offset_x'].value,
  91. 'offset_y': nodes['offset_y'].value,
  92. }
  93. # Adding name later for cases when no name is provided
  94. if nodes['name'].text != '':
  95. info_to_save['name'] = nodes['name'].text
  96. return info_to_save
  97. func save_character():
  98. var info_to_save = generate_character_data_to_save()
  99. if info_to_save['id']:
  100. DialogicResources.set_character(info_to_save)
  101. opened_character_data = info_to_save
  102. func load_character(filename: String):
  103. clear_character_editor()
  104. var data = DialogicResources.get_character_json(filename)
  105. opened_character_data = data
  106. nodes['file'].text = data['id']
  107. nodes['default_speaker'].pressed = false
  108. if data.has('name'):
  109. nodes['name'].text = data['name']
  110. if data.has('description'):
  111. nodes['description'].text = data['description']
  112. if data.has('color'):
  113. nodes['color'].color = Color(data['color'])
  114. if data.has('default_speaker'):
  115. if data['default_speaker']:
  116. nodes['default_speaker'].pressed = true
  117. if data.has('display_name_bool'):
  118. nodes['display_name_checkbox'].pressed = data['display_name_bool']
  119. if data.has('display_name'):
  120. nodes['display_name'].text = data['display_name']
  121. if data.has('scale'):
  122. nodes['scale'].value = float(data['scale'])
  123. if data.has('offset_x'):
  124. nodes['offset_x'].value = data['offset_x']
  125. nodes['offset_y'].value = data['offset_y']
  126. # Portraits
  127. var default_portrait = create_portrait_entry()
  128. default_portrait.get_node('NameEdit').text = 'Default'
  129. default_portrait.get_node('NameEdit').editable = false
  130. if data.has('portraits'):
  131. for p in data['portraits']:
  132. if p['name'] == 'Default':
  133. default_portrait.get_node('PathEdit').text = p['path']
  134. default_portrait.update_preview(p['path'])
  135. else:
  136. create_portrait_entry(p['name'], p['path'])
  137. # Portraits
  138. func _on_New_Portrait_Button_pressed():
  139. create_portrait_entry('', '', true)
  140. func create_portrait_entry(p_name = '', path = '', grab_focus = false):
  141. var p = portrait_entry.instance()
  142. p.editor_reference = editor_reference
  143. p.image_node = nodes['portrait_preview']
  144. var p_list = $HBoxContainer/Container/ScrollContainer/VBoxContainer/PortraitList
  145. p_list.add_child(p)
  146. if p_name != '':
  147. p.get_node("NameEdit").text = p_name
  148. if path != '':
  149. p.get_node("PathEdit").text = path
  150. if grab_focus:
  151. p.get_node("NameEdit").grab_focus()
  152. p._on_ButtonSelect_pressed()
  153. return p