130 lines
3.7 KiB
GDScript
130 lines
3.7 KiB
GDScript
class_name LogbookPortrait
|
|
extends TextureRect
|
|
|
|
const ENTRY_FRAME_SIZE := Vector2(86.0, 40.0)
|
|
const DETAIL_FRAME_SIZE := Vector2(240.0, 132.0)
|
|
const UNIFORM_FOOTPRINT_AREA_RATIO: float = 0.6
|
|
|
|
static var _normalized_textures: Dictionary[String, Texture2D] = {}
|
|
|
|
var source_texture: Texture2D
|
|
|
|
|
|
func _init() -> void:
|
|
expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
|
stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
focus_mode = Control.FOCUS_NONE
|
|
size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
|
size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
|
|
|
|
func configure(
|
|
portrait_texture: Texture2D,
|
|
frame_size: Vector2,
|
|
portrait_material: Material = null,
|
|
) -> void:
|
|
source_texture = portrait_texture
|
|
custom_minimum_size = frame_size
|
|
material = portrait_material
|
|
texture = _normalize_visible_bounds(portrait_texture)
|
|
|
|
|
|
func configure_fitted(
|
|
portrait_texture: Texture2D,
|
|
maximum_size: Vector2,
|
|
portrait_material: Material = null,
|
|
) -> void:
|
|
source_texture = portrait_texture
|
|
material = portrait_material
|
|
texture = _normalize_visible_bounds(portrait_texture)
|
|
if texture == null:
|
|
custom_minimum_size = Vector2.ZERO
|
|
return
|
|
var texture_size: Vector2 = texture.get_size()
|
|
if texture_size.x <= 0.0 or texture_size.y <= 0.0:
|
|
custom_minimum_size = Vector2.ZERO
|
|
return
|
|
var fit_scale: float = minf(
|
|
maximum_size.x / texture_size.x,
|
|
maximum_size.y / texture_size.y,
|
|
)
|
|
custom_minimum_size = texture_size * fit_scale
|
|
|
|
|
|
func configure_uniform_footprint(
|
|
portrait_texture: Texture2D,
|
|
maximum_size: Vector2,
|
|
portrait_material: Material = null,
|
|
) -> void:
|
|
source_texture = portrait_texture
|
|
material = portrait_material
|
|
texture = _normalize_visible_bounds(portrait_texture)
|
|
if texture == null:
|
|
custom_minimum_size = Vector2.ZERO
|
|
return
|
|
custom_minimum_size = uniform_footprint_size(
|
|
texture.get_size(),
|
|
maximum_size,
|
|
)
|
|
|
|
|
|
static func uniform_footprint_size(
|
|
visible_size: Vector2,
|
|
maximum_size: Vector2,
|
|
) -> Vector2:
|
|
if (
|
|
visible_size.x <= 0.0
|
|
or visible_size.y <= 0.0
|
|
or maximum_size.x <= 0.0
|
|
or maximum_size.y <= 0.0
|
|
):
|
|
return Vector2.ZERO
|
|
var target_area: float = (
|
|
maximum_size.x
|
|
* maximum_size.y
|
|
* UNIFORM_FOOTPRINT_AREA_RATIO
|
|
)
|
|
var area_scale: float = sqrt(
|
|
target_area / (visible_size.x * visible_size.y)
|
|
)
|
|
var fit_scale: float = minf(
|
|
maximum_size.x / visible_size.x,
|
|
maximum_size.y / visible_size.y,
|
|
)
|
|
var scale: float = minf(area_scale, fit_scale)
|
|
return Vector2(
|
|
minf(maximum_size.x, maxf(1.0, roundf(visible_size.x * scale))),
|
|
minf(maximum_size.y, maxf(1.0, roundf(visible_size.y * scale))),
|
|
)
|
|
|
|
|
|
static func _normalize_visible_bounds(
|
|
portrait_texture: Texture2D,
|
|
) -> Texture2D:
|
|
if portrait_texture == null:
|
|
return null
|
|
var cache_key: String = portrait_texture.resource_path
|
|
if cache_key.is_empty():
|
|
cache_key = "instance_%d" % portrait_texture.get_instance_id()
|
|
var cached: Texture2D = _normalized_textures.get(cache_key) as Texture2D
|
|
if cached != null:
|
|
return cached
|
|
var image: Image = portrait_texture.get_image()
|
|
if image == null or image.is_empty():
|
|
_normalized_textures[cache_key] = portrait_texture
|
|
return portrait_texture
|
|
if image.is_compressed() and image.decompress() != OK:
|
|
_normalized_textures[cache_key] = portrait_texture
|
|
return portrait_texture
|
|
var full_rect := Rect2i(Vector2i.ZERO, image.get_size())
|
|
var visible_rect: Rect2i = image.get_used_rect()
|
|
if visible_rect.size == Vector2i.ZERO or visible_rect == full_rect:
|
|
_normalized_textures[cache_key] = portrait_texture
|
|
return portrait_texture
|
|
var normalized := AtlasTexture.new()
|
|
normalized.atlas = portrait_texture
|
|
normalized.region = Rect2(visible_rect)
|
|
_normalized_textures[cache_key] = normalized
|
|
return normalized
|