Trying to make a customizable box and struggling with UI

Godot Version

extends Control

@export var levelID = 1

@export var Border_Color : Color

@export var Song_Image : Texture


##OPTIONS


@onready var Song_Texture: TextureRect = $Imagepivot/PanelContainer/LevelImg


@onready var Border_Img: TextureRect = $PanelContainer/BorderImg

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	$Label.text = "Level" + str(levelID)
	
	Song_Texture.texture = Song_Image
	
	Border_Img.modulate = Border_Color

func _process(delta: float) -> void:
	if Engine.is_editor_hint():
		$Label.text = "Level" + str(levelID)

The code for my level Icon

Question

I have been trying to make customizable buttons for my game that I can easily customize the items within it. And my ideal was to make panel containers with the images inside but in a different scene I try putting it inside of a H box container but it causes all my sprites to squish and look disjointed.

Im not even sure if i should be putting it into a hbox container as I have code in the control node that allows me to select and icon with an array so I am not too sure on what to do. As I work on a big monitor and am working on godot with 1920 * 1080 and want to make sure re-scaling looks good

And the Icons are supposed to look something like this

I followed a tutorial that was pretty amazing when it came to Inventory. They used a TextureButton with a TextureRect. Then just put everything in a GridContainer.

extends TextureButton

class_name ItemIcon

signal interact(item)

const SPELL_SLOT_EMPTY = preload("res://assets/ui/icons/spell_slot_empty.png")
const ITEM_HOVER = preload("res://assets/ui/icons/ItemHover.png")

@onready var stat_label: Label = $MarginContainer/StatLabel
@onready var item_label: Label = $MarginContainer/ItemLabel


var focused = false


func _process(_delta: float) -> void:
	if focused == false and self.has_focus():
		focus()
	if focused == true and not self.has_focus():
		unfocus()


func _on_gui_input(event: InputEvent) -> void:
	if event.is_action_pressed("click"):
		interact.emit(self)


func focus() -> void:
	texture_normal = ITEM_HOVER
	focused = true


func unfocus() -> void:
	texture_normal = SPELL_SLOT_EMPTY
	focused = false

It worked pretty well. I had some issues getting it to work for a controller as well, but I believe I ironed them out. (The tutorial was mouse-only.)

1 Like

Control does not have a minimum size by default so it will shrink when added to a container as the container will force the minimum size of the Control.

You’ll need to give it a fixed Control.custom_minimum_size or implement Control._get_minimum_size() if you want it to be dynamic.

2 Likes

Sorry for the late reply, This looks super good will try it out and see if it works for a level select

1 Like

Oh I never knew this ill be sure to try it out and see what happens