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.

ThemeEditor.gd 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. tool
  2. extends Control
  3. var editor_reference
  4. onready var master_tree = get_node('../MasterTree')
  5. onready var settings_editor = get_node('../SettingsEditor')
  6. var current_theme = ''
  7. # The amazing and revolutionary path system that magically works and you can't
  8. # complain because "that is not how you are supposed to work". If there was only
  9. # a way to set an id and then access that node via id...
  10. # Here you have paths in all its glory. Praise the paths (っ´ω`c)♡
  11. onready var n = {
  12. # Text
  13. 'theme_text_shadow': $VBoxContainer/HBoxContainer2/Text/GridContainer/HBoxContainer2/CheckBoxShadow,
  14. 'theme_text_shadow_color': $VBoxContainer/HBoxContainer2/Text/GridContainer/HBoxContainer2/ColorPickerButtonShadow,
  15. 'theme_text_color': $VBoxContainer/HBoxContainer2/Text/GridContainer/ColorPickerButton,
  16. 'theme_font': $VBoxContainer/HBoxContainer2/Text/GridContainer/FontButton,
  17. 'theme_shadow_offset_x': $VBoxContainer/HBoxContainer2/Text/GridContainer/HBoxContainer/ShadowOffsetX,
  18. 'theme_shadow_offset_y': $VBoxContainer/HBoxContainer2/Text/GridContainer/HBoxContainer/ShadowOffsetY,
  19. 'theme_text_speed': $VBoxContainer/HBoxContainer2/Text/GridContainer/TextSpeed,
  20. 'alignment': $VBoxContainer/HBoxContainer2/Text/GridContainer/HBoxContainer3/Alignment,
  21. # Dialog box
  22. 'background_texture_button_visible': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer3/CheckBox,
  23. 'theme_background_image': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer3/BackgroundTextureButton,
  24. 'theme_next_image': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/NextIndicatorButton,
  25. 'next_animation': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/NextAnimation,
  26. 'theme_action_key': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/BoxContainer/ActionOptionButton,
  27. 'theme_background_color_visible': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer2/CheckBox,
  28. 'theme_background_color': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer2/ColorPickerButton,
  29. 'theme_text_margin': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer/TextOffsetV,
  30. 'theme_text_margin_h': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer/TextOffsetH,
  31. 'size_w': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer4/BoxSizeW,
  32. 'size_h': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer4/BoxSizeH,
  33. 'bottom_gap': $VBoxContainer/HBoxContainer2/DialogBox/GridContainer/HBoxContainer5/BottomGap,
  34. # Buttons
  35. 'button_text_color_enabled': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer4/CheckBox2,
  36. 'button_text_color': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer4/ButtonTextColor,
  37. 'button_background': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer2/ColorPickerButton,
  38. 'button_background_visible': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer2/CheckBox,
  39. 'button_image': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer3/BackgroundTextureButton,
  40. 'button_image_visible': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer3/CheckBox,
  41. 'button_offset_x': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer/TextOffsetH,
  42. 'button_offset_y': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/HBoxContainer/TextOffsetV,
  43. 'button_separation': $VBoxContainer/HBoxContainer2/ButtonStyle/GridContainer/VerticalSeparation,
  44. # Definitions
  45. 'glossary_font': $VBoxContainer/HBoxContainer2/Glossary/GridContainer/FontButton,
  46. 'glossary_color': $VBoxContainer/HBoxContainer2/Glossary/GridContainer/ColorPickerButton,
  47. # Text preview
  48. 'preview_panel': $VBoxContainer/Panel,
  49. 'text_preview': $VBoxContainer/HBoxContainer3/TextEdit,
  50. # Character Names
  51. 'name_auto_color': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/CheckBox,
  52. 'name_background_visible': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer2/CheckBox,
  53. 'name_background': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer2/ColorPickerButton,
  54. 'name_image': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer3/BackgroundTextureButton,
  55. 'name_image_visible': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer3/CheckBox,
  56. 'name_shadow': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer4/ColorPickerButtonShadow,
  57. 'name_shadow_visible': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer4/CheckBoxShadow,
  58. 'name_shadow_offset_x': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer/ShadowOffsetX,
  59. 'name_shadow_offset_y': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer/ShadowOffsetY,
  60. 'name_bottom_gap': $VBoxContainer/HBoxContainer2/Glossary/GridContainer2/HBoxContainer5/BottomGap,
  61. }
  62. func _ready():
  63. # Signal connection to free up some memory
  64. connect("visibility_changed", self, "_on_visibility_changed")
  65. if get_constant("dark_theme", "Editor"):
  66. $VBoxContainer/HBoxContainer3/PreviewButton.icon = load("res://addons/dialogic/Images/Plugin/plugin-editor-icon-dark-theme.svg")
  67. else:
  68. $VBoxContainer/HBoxContainer3/PreviewButton.icon = load("res://addons/dialogic/Images/Plugin/plugin-editor-icon-light-theme.svg")
  69. # Force preview update
  70. _on_visibility_changed()
  71. func load_theme(filename):
  72. current_theme = filename
  73. var theme = DialogicResources.get_theme_config(filename)
  74. # Settings
  75. n['theme_action_key'].text = theme.get_value('settings', 'action_key', 'ui_accept')
  76. # Background
  77. n['theme_background_image'].text = DialogicResources.get_filename_from_path(theme.get_value('background', 'image', 'res://addons/dialogic/Images/background/background-2.png'))
  78. n['background_texture_button_visible'].pressed = theme.get_value('background', 'use_image', true)
  79. n['theme_background_color'].color = Color(theme.get_value('background', 'color', '#ff000000'))
  80. n['theme_background_color_visible'].pressed = theme.get_value('background', 'use_color', false)
  81. n['theme_next_image'].text = DialogicResources.get_filename_from_path(theme.get_value('next_indicator', 'image', 'res://addons/dialogic/Images/next-indicator.png'))
  82. var size_value = theme.get_value('box', 'size', Vector2(910, 167))
  83. n['size_w'].value = size_value.x
  84. n['size_h'].value = size_value.y
  85. n['bottom_gap'].value = theme.get_value('box', 'bottom_gap', 40)
  86. # Buttons
  87. n['button_text_color_enabled'].pressed = theme.get_value('buttons', 'text_color_enabled', true)
  88. n['button_text_color'].color = Color(theme.get_value('buttons', 'text_color', "#ffffffff"))
  89. n['button_background'].color = Color(theme.get_value('buttons', 'background_color', "#ff000000"))
  90. n['button_background_visible'].pressed = theme.get_value('buttons', 'use_background_color', false)
  91. n['button_image'].text = DialogicResources.get_filename_from_path(theme.get_value('buttons', 'image', 'res://addons/dialogic/Images/background/background-2.png'))
  92. n['button_image_visible'].pressed = theme.get_value('buttons', 'use_image', true)
  93. n['button_offset_x'].value = theme.get_value('buttons', 'padding', Vector2(5,5)).x
  94. n['button_offset_y'].value = theme.get_value('buttons', 'padding', Vector2(5,5)).y
  95. n['button_separation'].value = theme.get_value('buttons', 'gap', 5)
  96. # Definitions
  97. n['glossary_color'].color = Color(theme.get_value('definitions', 'color', "#ffffffff"))
  98. n['glossary_font'].text = DialogicResources.get_filename_from_path(theme.get_value('definitions', 'font', "res://addons/dialogic/Fonts/GlossaryFont.tres"))
  99. # Text
  100. n['theme_text_speed'].value = theme.get_value('text','speed', 2)
  101. n['theme_font'].text = DialogicResources.get_filename_from_path(theme.get_value('text', 'font', 'res://addons/dialogic/Fonts/DefaultFont.tres'))
  102. n['theme_text_color'].color = Color(theme.get_value('text', 'color', '#ffffffff'))
  103. n['theme_text_shadow'].pressed = theme.get_value('text', 'shadow', false)
  104. n['theme_text_shadow_color'].color = Color(theme.get_value('text', 'shadow_color', '#9e000000'))
  105. n['theme_shadow_offset_x'].value = theme.get_value('text', 'shadow_offset', Vector2(2,2)).x
  106. n['theme_shadow_offset_y'].value = theme.get_value('text', 'shadow_offset', Vector2(2,2)).y
  107. n['theme_text_margin'].value = theme.get_value('text', 'margin', Vector2(20, 10)).x
  108. n['theme_text_margin_h'].value = theme.get_value('text', 'margin', Vector2(20, 10)).y
  109. n['alignment'].text = theme.get_value('text', 'alignment', 'Left')
  110. match n['alignment'].text:
  111. 'Left':
  112. n['alignment'].select(0)
  113. 'Center':
  114. n['alignment'].select(1)
  115. 'Right':
  116. n['alignment'].select(2)
  117. # Name
  118. n['name_auto_color'].pressed = theme.get_value('name', 'auto_color', true)
  119. n['name_background_visible'].pressed = theme.get_value('name', 'background_visible', false)
  120. n['name_background'].color = Color(theme.get_value('name', 'background', "#ff000000"))
  121. n['name_image_visible'].pressed = theme.get_value('name', 'image_visible', false)
  122. n['name_image'].text = DialogicResources.get_filename_from_path(theme.get_value('name', 'image', 'res://addons/dialogic/Images/background/background-2.png'))
  123. n['name_shadow'].color = Color(theme.get_value('name', 'shadow', "#9e000000"))
  124. n['name_shadow_visible'].pressed = theme.get_value('name', 'shadow_visible', true)
  125. n['name_shadow_offset_x'].value = theme.get_value('name', 'shadow_offset', Vector2(2,2)).x
  126. n['name_shadow_offset_y'].value = theme.get_value('name', 'shadow_offset', Vector2(2,2)).y
  127. n['name_bottom_gap'].value = theme.get_value('name', 'bottom_gap', 48)
  128. # Next indicator animations
  129. var animations = ['Up and down', 'Pulse', 'Static'] # TODO: dynamically get all the animations from the Dialog.tscn NextIndicator
  130. n['next_animation'].clear()
  131. var next_animation_selected = theme.get_value('next_indicator', 'animation', 'Up and down')
  132. var nix = 0
  133. for a in animations:
  134. n['next_animation'].add_item(a)
  135. if a == next_animation_selected:
  136. n['next_animation'].select(nix)
  137. nix += 1
  138. # Preview text
  139. n['text_preview'].text = theme.get_value('text', 'preview', 'This is preview text. You can use [color=#A5EFAC]BBCode[/color] to style it.\n[wave amp=50 freq=2]You can even use effects![/wave]')
  140. # Updating the preview
  141. _on_PreviewButton_pressed()
  142. func new_theme():
  143. var theme_file = 'theme-' + str(OS.get_unix_time()) + '.cfg'
  144. DialogicResources.add_theme(theme_file)
  145. master_tree.build_themes(theme_file)
  146. load_theme(theme_file)
  147. # Check if it is the only theme to set as default
  148. if DialogicUtil.get_theme_list().size() == 1:
  149. print('only theme, setting as default')
  150. settings_editor.set_value('theme', 'default', theme_file)
  151. func _on_BackgroundTextureButton_pressed():
  152. editor_reference.godot_dialog("*.png")
  153. editor_reference.godot_dialog_connect(self, "_on_background_selected")
  154. func _on_background_selected(path, target):
  155. DialogicResources.set_theme_value(current_theme, 'background','image', path)
  156. n['theme_background_image'].text = DialogicResources.get_filename_from_path(path)
  157. func _on_NextIndicatorButton_pressed():
  158. editor_reference.godot_dialog("*.png")
  159. editor_reference.godot_dialog_connect(self, "_on_indicator_selected")
  160. func _on_indicator_selected(path, target):
  161. DialogicResources.set_theme_value(current_theme, 'next_indicator','image', path)
  162. n['theme_next_image'].text = DialogicResources.get_filename_from_path(path)
  163. func _on_NextAnimation_item_selected(index):
  164. DialogicResources.set_theme_value(current_theme, 'next_indicator', 'animation', n['next_animation'].get_item_text(index))
  165. func _on_ColorPickerButton_color_changed(color):
  166. DialogicResources.set_theme_value(current_theme, 'text','color', '#' + color.to_html())
  167. func _on_ColorPickerButtonShadow_color_changed(color):
  168. DialogicResources.set_theme_value(current_theme, 'text','shadow_color', '#' + color.to_html())
  169. func _on_CheckBoxShadow_toggled(button_pressed):
  170. DialogicResources.set_theme_value(current_theme, 'text','shadow', button_pressed)
  171. func _on_ShadowOffset_value_changed(_value):
  172. DialogicResources.set_theme_value(current_theme, 'text','shadow_offset', Vector2(n['theme_shadow_offset_x'].value,n['theme_shadow_offset_y'].value))
  173. func _on_PreviewButton_pressed():
  174. for i in n['preview_panel'].get_children():
  175. i.free()
  176. var dialogic_node = load("res://addons/dialogic/Dialog.tscn")
  177. var preview_dialog = dialogic_node.instance()
  178. preview_dialog.preview = true
  179. preview_dialog.get_node('DefinitionInfo').in_theme_editor = true
  180. # Random character preview if there are any
  181. var characters = DialogicUtil.get_character_list()
  182. var character_file = ''
  183. if characters.size():
  184. characters.shuffle()
  185. character_file = characters[0]['file']
  186. # Creating the one event timeline for the dialog
  187. preview_dialog.dialog_script['events'] = [{
  188. "character": character_file,
  189. "portrait":'',
  190. "text": preview_dialog.parse_definitions(n['text_preview'].text)
  191. }]
  192. preview_dialog.parse_characters(preview_dialog.dialog_script)
  193. preview_dialog.settings = DialogicResources.get_settings_config()
  194. # Alignment
  195. n['preview_panel'].add_child(preview_dialog)
  196. preview_dialog.load_dialog()
  197. preview_dialog.current_theme = preview_dialog.load_theme(current_theme)
  198. # When not performing this step, the dialog name doesn't update the color for some reason
  199. # I should probably refactor the preview dialog to stop making everything manually.
  200. if n['name_auto_color'].pressed:
  201. if characters.size():
  202. preview_dialog.get_node('TextBubble/NameLabel').set('custom_colors/font_color', characters[0]['color'])
  203. # maintaining the preview panel big enough for the dialog box
  204. n['preview_panel'].rect_min_size.y = preview_dialog.current_theme.get_value('box', 'size', Vector2(910, 167)).y + 90 + preview_dialog.current_theme.get_value('box', 'bottom_gap', 40)
  205. n['preview_panel'].rect_size.y = 0
  206. func _on_ActionOptionButton_item_selected(index):
  207. DialogicResources.set_theme_value(current_theme, 'settings','action_key', n['theme_action_key'].text)
  208. func _on_ActionOptionButton_pressed():
  209. n['theme_action_key'].clear()
  210. n['theme_action_key'].add_item('[Select Action]')
  211. InputMap.load_from_globals()
  212. for a in InputMap.get_actions():
  213. n['theme_action_key'].add_item(a)
  214. func _on_FontButton_pressed():
  215. editor_reference.godot_dialog("*.tres")
  216. editor_reference.godot_dialog_connect(self, "_on_Font_selected")
  217. func _on_Font_selected(path, target):
  218. DialogicResources.set_theme_value(current_theme, 'text','font', path)
  219. n['theme_font'].text = DialogicResources.get_filename_from_path(path)
  220. func _on_textSpeed_value_changed(value):
  221. DialogicResources.set_theme_value(current_theme, 'text','speed', value)
  222. func _on_TextMargin_value_changed(value):
  223. var final_vector = Vector2(
  224. n['theme_text_margin'].value,
  225. n['theme_text_margin_h'].value
  226. )
  227. DialogicResources.set_theme_value(current_theme, 'text', 'margin', final_vector)
  228. func _on_BackgroundColor_CheckBox_toggled(button_pressed):
  229. DialogicResources.set_theme_value(current_theme, 'background', 'use_color', button_pressed)
  230. func _on_BackgroundColor_ColorPickerButton_color_changed(color):
  231. DialogicResources.set_theme_value(current_theme, 'background', 'color', '#' + color.to_html())
  232. func _on_BackgroundTexture_CheckBox_toggled(button_pressed):
  233. DialogicResources.set_theme_value(current_theme, 'background', 'use_image', button_pressed)
  234. func _on_button_background_visible_toggled(button_pressed):
  235. DialogicResources.set_theme_value(current_theme, 'buttons', 'use_background_color', button_pressed)
  236. func _on_button_background_color_color_changed(color):
  237. DialogicResources.set_theme_value(current_theme, 'buttons', 'background_color', '#' + color.to_html())
  238. func _on_ButtonOffset_value_changed(value):
  239. var final_vector = Vector2(
  240. n['button_offset_x'].value,
  241. n['button_offset_y'].value
  242. )
  243. DialogicResources.set_theme_value(current_theme, 'buttons', 'padding', final_vector)
  244. func _on_VerticalSeparation_value_changed(value):
  245. DialogicResources.set_theme_value(current_theme, 'buttons', 'gap', n['button_separation'].value)
  246. func _on_button_texture_toggled(button_pressed):
  247. DialogicResources.set_theme_value(current_theme, 'buttons', 'use_image', button_pressed)
  248. func _on_ButtonTextureButton_pressed():
  249. editor_reference.godot_dialog("*.png")
  250. editor_reference.godot_dialog_connect(self, "_on_button_texture_selected")
  251. func _on_button_texture_selected(path, target):
  252. DialogicResources.set_theme_value(current_theme, 'buttons', 'image', path)
  253. n['button_image'].text = DialogicResources.get_filename_from_path(path)
  254. func _on_ButtonTextColor_color_changed(color):
  255. DialogicResources.set_theme_value(current_theme, 'buttons', 'text_color', '#' + color.to_html())
  256. func _on_Custom_Button_Color_toggled(button_pressed):
  257. DialogicResources.set_theme_value(current_theme, 'buttons', 'text_color_enabled', button_pressed)
  258. func _on_GlossaryColorPicker_color_changed(color):
  259. DialogicResources.set_theme_value(current_theme, 'definitions', 'color', '#' + color.to_html())
  260. func _on_GlossaryFontButton_pressed():
  261. editor_reference.godot_dialog("*.tres")
  262. editor_reference.godot_dialog_connect(self, "_on_Glossary_Font_selected")
  263. func _on_Glossary_Font_selected(path, target):
  264. DialogicResources.set_theme_value(current_theme, 'definitions', 'font', path)
  265. n['glossary_font'].text = DialogicResources.get_filename_from_path(path)
  266. func _on_visibility_changed():
  267. if visible:
  268. # Refreshing the dialog
  269. _on_PreviewButton_pressed()
  270. else:
  271. # Erasing all previews since them keeps working
  272. # on background
  273. for i in n['preview_panel'].get_children():
  274. i.queue_free()
  275. func _on_BoxSize_value_changed(value):
  276. var size_value = Vector2(n['size_w'].value, n['size_h'].value)
  277. DialogicResources.set_theme_value(current_theme, 'box', 'size', size_value)
  278. func _on_BottomGap_value_changed(value):
  279. DialogicResources.set_theme_value(current_theme, 'box', 'bottom_gap', value)
  280. func _on_Alignment_item_selected(index):
  281. if index == 0:
  282. DialogicResources.set_theme_value(current_theme, 'text', 'alignment', 'Left')
  283. elif index == 1:
  284. DialogicResources.set_theme_value(current_theme, 'text', 'alignment', 'Center')
  285. elif index == 2:
  286. DialogicResources.set_theme_value(current_theme, 'text', 'alignment', 'Right')
  287. func _on_Preview_text_changed():
  288. DialogicResources.set_theme_value(current_theme, 'text', 'preview', n['text_preview'].text)
  289. func _on_name_auto_color_toggled(button_pressed):
  290. DialogicResources.set_theme_value(current_theme, 'name', 'auto_color', button_pressed)
  291. func _on_name_background_visible_toggled(button_pressed):
  292. DialogicResources.set_theme_value(current_theme, 'name', 'background_visible', button_pressed)
  293. func _on_name_background_color_changed(color):
  294. DialogicResources.set_theme_value(current_theme, 'name', 'background', '#' + color.to_html())
  295. func _on_name_image_visible_toggled(button_pressed):
  296. DialogicResources.set_theme_value(current_theme, 'name', 'image_visible', button_pressed)
  297. func _on_name_image_pressed():
  298. editor_reference.godot_dialog("*.png")
  299. editor_reference.godot_dialog_connect(self, "_on_name_texture_selected")
  300. func _on_name_texture_selected(path, target):
  301. DialogicResources.set_theme_value(current_theme, 'name', 'image', path)
  302. n['name_image'].text = DialogicResources.get_filename_from_path(path)
  303. func _on_shadow_visible_toggled(button_pressed):
  304. DialogicResources.set_theme_value(current_theme, 'name', 'shadow_visible', button_pressed)
  305. func _on_name_shadow_color_changed(color):
  306. DialogicResources.set_theme_value(current_theme, 'name', 'shadow', '#' + color.to_html())
  307. func _on_name_ShadowOffset_value_changed(_value):
  308. DialogicResources.set_theme_value(current_theme, 'name','shadow_offset',
  309. Vector2(n['name_shadow_offset_x'].value,n['name_shadow_offset_y'].value))
  310. func _on_name_BottomGap_value_changed(value):
  311. DialogicResources.set_theme_value(current_theme, 'name', 'bottom_gap', value)