TerrainEntry.gd 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. @tool
  2. extends PanelContainer
  3. signal select(index)
  4. @onready var color_panel := %Color
  5. @onready var terrain_icon_slot := %TerrainIcon
  6. @onready var type_icon_slot := %TypeIcon
  7. @onready var type_icon_panel := %TerrainIconPanel
  8. @onready var name_label := %Name
  9. @onready var layout_container := %Layout
  10. @onready var icon_layout_container := %IconLayout
  11. var selected := false
  12. var tileset:TileSet
  13. var terrain:Dictionary
  14. var grid_mode := false
  15. var color_style_list:StyleBoxFlat
  16. var color_style_grid:StyleBoxFlat
  17. var color_style_decoration:StyleBoxFlat
  18. var _terrain_texture:Texture2D
  19. var _terrain_texture_rect:Rect2i
  20. var _icon_draw_connected := false
  21. func _ready():
  22. update()
  23. func update():
  24. if !terrain or !terrain.valid:
  25. return
  26. if !tileset:
  27. return
  28. name_label.text = terrain.name
  29. tooltip_text = "%s (%d)" % [terrain.name, terrain.id]
  30. color_style_list = color_panel.get_theme_stylebox("panel").duplicate()
  31. color_style_grid = color_panel.get_theme_stylebox("panel").duplicate()
  32. color_style_decoration = color_panel.get_theme_stylebox("panel").duplicate()
  33. color_style_list.bg_color = terrain.color
  34. color_style_list.corner_radius_top_left = 8
  35. color_style_list.corner_radius_bottom_left = 8
  36. color_style_list.corner_radius_top_right = 0
  37. color_style_list.corner_radius_bottom_right = 0
  38. color_style_list.content_margin_left = -1
  39. color_style_list.content_margin_right = -1
  40. color_style_list.border_width_left = 0
  41. color_style_list.border_width_right = 0
  42. color_style_list.border_width_top = 0
  43. color_style_list.border_width_bottom = 0
  44. color_style_grid.bg_color = terrain.color
  45. color_style_grid.corner_radius_top_left = 6
  46. color_style_grid.corner_radius_bottom_left = 6
  47. color_style_grid.corner_radius_top_right = 6
  48. color_style_grid.corner_radius_bottom_right = 6
  49. color_style_grid.content_margin_left = -1
  50. color_style_grid.content_margin_right = -1
  51. color_style_grid.border_width_left = 0
  52. color_style_grid.border_width_right = 0
  53. color_style_grid.border_width_top = 0
  54. color_style_grid.border_width_bottom = 0
  55. color_style_decoration.bg_color = terrain.color
  56. color_style_decoration.corner_radius_top_left = 8
  57. color_style_decoration.corner_radius_bottom_left = 8
  58. color_style_decoration.corner_radius_top_right = 8
  59. color_style_decoration.corner_radius_bottom_right = 8
  60. color_style_decoration.content_margin_left = -1
  61. color_style_decoration.content_margin_right = -1
  62. color_style_decoration.border_width_left = 4
  63. color_style_decoration.border_width_right = 4
  64. color_style_decoration.border_width_top = 4
  65. color_style_decoration.border_width_bottom = 4
  66. match terrain.type:
  67. BetterTerrain.TerrainType.MATCH_TILES:
  68. type_icon_slot.texture = load("res://addons/better-terrain/icons/MatchTiles.svg")
  69. BetterTerrain.TerrainType.MATCH_VERTICES:
  70. type_icon_slot.texture = load("res://addons/better-terrain/icons/MatchVertices.svg")
  71. BetterTerrain.TerrainType.CATEGORY:
  72. type_icon_slot.texture = load("res://addons/better-terrain/icons/NonModifying.svg")
  73. BetterTerrain.TerrainType.DECORATION:
  74. type_icon_slot.texture = load("res://addons/better-terrain/icons/Decoration.svg")
  75. var has_icon = false
  76. if terrain.has("icon"):
  77. if terrain.icon.has("path") and not terrain.icon.path.is_empty():
  78. terrain_icon_slot.texture = load(terrain.icon.path)
  79. _terrain_texture = null
  80. terrain_icon_slot.queue_redraw()
  81. has_icon = true
  82. elif terrain.icon.has("source_id") and tileset.has_source(terrain.icon.source_id):
  83. var source := tileset.get_source(terrain.icon.source_id) as TileSetAtlasSource
  84. var coord := terrain.icon.coord as Vector2i
  85. var rect := source.get_tile_texture_region(coord, 0)
  86. _terrain_texture = source.texture
  87. _terrain_texture_rect = rect
  88. terrain_icon_slot.queue_redraw()
  89. has_icon = true
  90. if not has_icon:
  91. var tiles = BetterTerrain.get_tile_sources_in_terrain(tileset, get_index())
  92. if tiles.size() > 0:
  93. var source := tiles[0].source as TileSetAtlasSource
  94. var coord := tiles[0].coord as Vector2i
  95. var rect := source.get_tile_texture_region(coord, 0)
  96. _terrain_texture = source.texture
  97. _terrain_texture_rect = rect
  98. terrain_icon_slot.queue_redraw()
  99. if _terrain_texture:
  100. terrain_icon_slot.texture = null
  101. if not _icon_draw_connected:
  102. terrain_icon_slot.connect("draw", func():
  103. if _terrain_texture:
  104. terrain_icon_slot.draw_texture_rect_region(_terrain_texture, Rect2i(0,0, 44, 44), _terrain_texture_rect)
  105. )
  106. _icon_draw_connected = true
  107. update_style()
  108. func update_style():
  109. if terrain.type == BetterTerrain.TerrainType.DECORATION:
  110. type_icon_panel.visible = false
  111. color_panel.custom_minimum_size = Vector2i(52,52)
  112. else:
  113. type_icon_panel.visible = true
  114. color_panel.custom_minimum_size = Vector2i(24,24)
  115. if grid_mode:
  116. if terrain.type == BetterTerrain.TerrainType.DECORATION:
  117. color_panel.add_theme_stylebox_override("panel", color_style_decoration)
  118. color_panel.size_flags_vertical = Control.SIZE_FILL
  119. icon_layout_container.size_flags_vertical = Control.SIZE_EXPAND_FILL
  120. else:
  121. color_panel.add_theme_stylebox_override("panel", color_style_grid)
  122. color_panel.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
  123. icon_layout_container.size_flags_vertical = Control.SIZE_FILL
  124. custom_minimum_size = Vector2(0, 60)
  125. size_flags_horizontal = Control.SIZE_FILL
  126. layout_container.vertical = true
  127. name_label.visible = false
  128. icon_layout_container.add_theme_constant_override("separation", -24)
  129. else:
  130. if terrain.type == BetterTerrain.TerrainType.DECORATION:
  131. color_panel.add_theme_stylebox_override("panel", color_style_decoration)
  132. else:
  133. color_panel.add_theme_stylebox_override("panel", color_style_list)
  134. icon_layout_container.size_flags_vertical = Control.SIZE_FILL
  135. custom_minimum_size = Vector2(2000, 60)
  136. size_flags_horizontal = Control.SIZE_EXPAND_FILL
  137. layout_container.vertical = false
  138. name_label.visible = true
  139. color_panel.size_flags_vertical = Control.SIZE_FILL
  140. icon_layout_container.add_theme_constant_override("separation", 4)
  141. func set_selected(value:bool = true):
  142. selected = value
  143. if value:
  144. select.emit(get_index())
  145. queue_redraw()
  146. func _draw():
  147. if selected:
  148. draw_rect(Rect2(Vector2.ZERO, get_rect().size), Color(0.15, 0.70, 1, 0.3))
  149. func _on_focus_entered():
  150. queue_redraw()
  151. selected = true
  152. select.emit(get_index())
  153. func _on_focus_exited():
  154. queue_redraw()