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.
194 lines
4.4 KiB
194 lines
4.4 KiB
6 months ago
|
@tool
|
||
|
extends Resource
|
||
|
class_name DialogicStyle
|
||
|
|
||
|
## A style represents a collection of layers and settings.
|
||
|
## A style can inherit from another style.
|
||
|
|
||
|
|
||
|
@export var name := "Style":
|
||
|
get:
|
||
|
if name.is_empty():
|
||
|
return "Unkown Style"
|
||
|
return name
|
||
|
|
||
|
@export var inherits: DialogicStyle = null
|
||
|
|
||
|
@export var base_scene: PackedScene = null
|
||
|
@export var base_overrides := {}
|
||
|
|
||
|
@export var layers: Array[DialogicStyleLayer] = []
|
||
|
|
||
|
|
||
|
|
||
|
func _init(_name:="") -> void:
|
||
|
if not _name.is_empty():
|
||
|
name = _name
|
||
|
|
||
|
|
||
|
## This always returns the inheritance root's scene!
|
||
|
func get_base_scene() -> PackedScene:
|
||
|
if base_scene == null:
|
||
|
return DialogicUtil.get_default_layout_base()
|
||
|
|
||
|
return get_inheritance_root().base_scene
|
||
|
|
||
|
|
||
|
## This always returns the full inherited roots layers!
|
||
|
func get_layer_list() -> PackedStringArray:
|
||
|
return PackedStringArray(get_inheritance_root().layers.map(func(x:DialogicStyleLayer): return x.scene.resource_path))
|
||
|
|
||
|
|
||
|
func get_layer_count() -> int:
|
||
|
return layers.size()
|
||
|
|
||
|
|
||
|
func get_layer_info(index:int) -> Dictionary:
|
||
|
if index == -1:
|
||
|
return {'path':get_base_scene().resource_path, 'overrides':base_overrides.duplicate()}
|
||
|
|
||
|
if index < layers.size():
|
||
|
if layers[index].scene != null:
|
||
|
return {'path':layers[index].scene.resource_path, 'overrides':layers[index].overrides.duplicate()}
|
||
|
else:
|
||
|
return {'path':'', 'overrides':layers[index].overrides.duplicate()}
|
||
|
|
||
|
return {'path':'', 'overrides':{}}
|
||
|
|
||
|
|
||
|
func get_layer_inherited_info(index:int, inherited_only:=false) -> Dictionary:
|
||
|
var style := self
|
||
|
var info := {'path':'', 'overrides':{}}
|
||
|
if not inherited_only:
|
||
|
info = get_layer_info(index)
|
||
|
|
||
|
while style.inherits != null:
|
||
|
style = style.inherits
|
||
|
info = merge_layer_infos(info, style.get_layer_info(index))
|
||
|
|
||
|
return info
|
||
|
|
||
|
|
||
|
func add_layer(scene:String, overrides:Dictionary = {}) -> void:
|
||
|
layers.append(DialogicStyleLayer.new(scene, overrides))
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
func delete_layer(layer_index:int) -> void:
|
||
|
if not has_layer(layer_index):
|
||
|
return
|
||
|
|
||
|
layers.remove_at(layer_index)
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
func move_layer(from_index:int, to_index:int) -> void:
|
||
|
if not has_layer(from_index) or not has_layer(to_index-1):
|
||
|
return
|
||
|
|
||
|
var info: Resource = layers.pop_at(from_index)
|
||
|
layers.insert(to_index, info)
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
func set_layer_scene(layer_index:int, scene:String) -> void:
|
||
|
if not has_layer(layer_index):
|
||
|
return
|
||
|
|
||
|
if layer_index == -1:
|
||
|
base_scene = load(scene)
|
||
|
else:
|
||
|
layers[layer_index].scene = load(scene)
|
||
|
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
func set_layer_setting(layer:int, setting:String, value:Variant) -> void:
|
||
|
if not has_layer(layer):
|
||
|
return
|
||
|
|
||
|
if layer == -1:
|
||
|
base_overrides[setting] = value
|
||
|
else:
|
||
|
layers[layer].overrides[setting] = value
|
||
|
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
func remove_layer_setting(layer:int, setting:String) -> void:
|
||
|
if not has_layer(layer):
|
||
|
return
|
||
|
|
||
|
if layer == -1:
|
||
|
base_overrides.erase(setting)
|
||
|
else:
|
||
|
layers[layer].overrides.erase(setting)
|
||
|
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
## This merges two layers (mainly their overrides). Layer a has priority!
|
||
|
func merge_layer_infos(layer_a:Dictionary, layer_b:Dictionary) -> Dictionary:
|
||
|
var combined := layer_a.duplicate(true)
|
||
|
|
||
|
combined.path = layer_b.path
|
||
|
combined.overrides.merge(layer_b.overrides)
|
||
|
|
||
|
return combined
|
||
|
|
||
|
|
||
|
func has_layer(index:int) -> bool:
|
||
|
return index < layers.size()
|
||
|
|
||
|
|
||
|
func inherits_anything() -> bool:
|
||
|
return inherits != null
|
||
|
|
||
|
|
||
|
func get_inheritance_root() -> DialogicStyle:
|
||
|
if inherits == null:
|
||
|
return self
|
||
|
|
||
|
var style: DialogicStyle = self
|
||
|
while style.inherits != null:
|
||
|
style = style.inherits
|
||
|
|
||
|
return style
|
||
|
|
||
|
|
||
|
func realize_inheritance() -> void:
|
||
|
base_scene = get_base_scene()
|
||
|
base_overrides = get_layer_inherited_info(-1)
|
||
|
|
||
|
var _layers: Array[DialogicStyleLayer] = []
|
||
|
for i in range(get_layer_count()):
|
||
|
var info := get_layer_inherited_info(i)
|
||
|
_layers.append(DialogicStyleLayer.new(info.get("path", ""), info.get("overrides", {})))
|
||
|
|
||
|
layers = _layers
|
||
|
inherits = null
|
||
|
changed.emit()
|
||
|
|
||
|
|
||
|
func clone() -> DialogicStyle:
|
||
|
var style := DialogicStyle.new()
|
||
|
style.name = name
|
||
|
if base_scene != null:
|
||
|
style.base_scene = base_scene
|
||
|
style.inherits = inherits
|
||
|
style.base_overrides = base_overrides
|
||
|
for layer_idx in range(get_layer_count()):
|
||
|
var info := get_layer_info(layer_idx)
|
||
|
style.add_layer(info.path, info.overrides)
|
||
|
|
||
|
return style
|
||
|
|
||
|
|
||
|
func prepare() -> void:
|
||
|
if base_scene:
|
||
|
ResourceLoader.load_threaded_request(base_scene.resource_path)
|
||
|
|
||
|
for layer in layers:
|
||
|
if layer.scene:
|
||
|
ResourceLoader.load_threaded_request(layer.scene.resource_path)
|