feat(studio,stacking,animations,collections): M16 ModBison Studio, object stacking, model animations, and poly collections for MVP 2
checkpoint / checkpoint (push) Successful in 6m32s
checkpoint / checkpoint (push) Successful in 6m32s
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
class_name StudioStartScreen
|
||||
extends Control
|
||||
## Studio Start Screen offering starter templates and recent projects browser.
|
||||
|
||||
signal template_selected(template_name: String)
|
||||
signal project_opened(path: String)
|
||||
|
||||
const MBWorldProjectIOClass = preload("res://scripts/studio/mbworld_project_io.gd")
|
||||
|
||||
var _recent_list: ItemList
|
||||
var _templates_container: HBoxContainer
|
||||
var _btn_open_file: Button
|
||||
var _file_dialog: FileDialog
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_build_ui()
|
||||
_populate_recent_projects()
|
||||
|
||||
|
||||
func _build_ui() -> void:
|
||||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
|
||||
var bg := ColorRect.new()
|
||||
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
bg.color = Color(0.12, 0.13, 0.16)
|
||||
add_child(bg)
|
||||
|
||||
var margin := MarginContainer.new()
|
||||
margin.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
margin.add_theme_constant_override("margin_left", 60)
|
||||
margin.add_theme_constant_override("margin_top", 40)
|
||||
margin.add_theme_constant_override("margin_right", 60)
|
||||
margin.add_theme_constant_override("margin_bottom", 40)
|
||||
add_child(margin)
|
||||
|
||||
var root_vbox := VBoxContainer.new()
|
||||
root_vbox.add_theme_constant_override("separation", 24)
|
||||
margin.add_child(root_vbox)
|
||||
|
||||
# Header
|
||||
var title_row := HBoxContainer.new()
|
||||
var title := Label.new()
|
||||
title.text = "🦬 ModBison Studio"
|
||||
title.add_theme_font_size_override("font_size", 28)
|
||||
title.add_theme_color_override("font_color", Color(1.0, 0.9, 0.3))
|
||||
title_row.add_child(title)
|
||||
|
||||
var spacer := Control.new()
|
||||
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
title_row.add_child(spacer)
|
||||
|
||||
_btn_open_file = Button.new()
|
||||
_btn_open_file.text = "📂 Open from Disk..."
|
||||
_btn_open_file.pressed.connect(_on_open_file_pressed)
|
||||
title_row.add_child(_btn_open_file)
|
||||
|
||||
root_vbox.add_child(title_row)
|
||||
|
||||
# Starter Templates Section
|
||||
var tmpl_lbl := Label.new()
|
||||
tmpl_lbl.text = "Starter Templates"
|
||||
tmpl_lbl.add_theme_font_size_override("font_size", 16)
|
||||
tmpl_lbl.add_theme_color_override("font_color", Color(0.3, 0.85, 1.0))
|
||||
root_vbox.add_child(tmpl_lbl)
|
||||
|
||||
_templates_container = HBoxContainer.new()
|
||||
_templates_container.add_theme_constant_override("separation", 16)
|
||||
root_vbox.add_child(_templates_container)
|
||||
|
||||
_create_template_card("Baseplate", "Clean empty 32x32 world grid ready for custom building.", "baseplate")
|
||||
_create_template_card("Rolling Hills", "Natural outdoor terrain with pine trees and fauna.", "terrain")
|
||||
_create_template_card("Obby Parkour", "Action platformer obstacle course with moving elevators.", "obby")
|
||||
|
||||
# Recent Projects Section
|
||||
var rec_lbl := Label.new()
|
||||
rec_lbl.text = "Recent Worlds"
|
||||
rec_lbl.add_theme_font_size_override("font_size", 16)
|
||||
rec_lbl.add_theme_color_override("font_color", Color(0.4, 0.9, 0.5))
|
||||
root_vbox.add_child(rec_lbl)
|
||||
|
||||
_recent_list = ItemList.new()
|
||||
_recent_list.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
_recent_list.custom_minimum_size = Vector2(0, 160)
|
||||
_recent_list.item_activated.connect(_on_recent_item_activated)
|
||||
root_vbox.add_child(_recent_list)
|
||||
|
||||
# File Dialog
|
||||
_file_dialog = FileDialog.new()
|
||||
_file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
|
||||
_file_dialog.access = FileDialog.ACCESS_FILESYSTEM
|
||||
_file_dialog.filters = PackedStringArray(["*.mbworld ; ModBison World Files"])
|
||||
_file_dialog.file_selected.connect(_on_file_dialog_selected)
|
||||
add_child(_file_dialog)
|
||||
|
||||
|
||||
func _create_template_card(title: String, desc: String, template_id: String) -> void:
|
||||
var panel := PanelContainer.new()
|
||||
panel.custom_minimum_size = Vector2(220, 120)
|
||||
panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
||||
var vbox := VBoxContainer.new()
|
||||
vbox.add_theme_constant_override("separation", 8)
|
||||
panel.add_child(vbox)
|
||||
|
||||
var t_lbl := Label.new()
|
||||
t_lbl.text = title
|
||||
t_lbl.add_theme_font_size_override("font_size", 14)
|
||||
t_lbl.add_theme_color_override("font_color", Color(1.0, 0.95, 0.4))
|
||||
vbox.add_child(t_lbl)
|
||||
|
||||
var d_lbl := Label.new()
|
||||
d_lbl.text = desc
|
||||
d_lbl.add_theme_font_size_override("font_size", 10)
|
||||
d_lbl.add_theme_color_override("font_color", Color(0.7, 0.7, 0.7))
|
||||
d_lbl.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
d_lbl.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
vbox.add_child(d_lbl)
|
||||
|
||||
var btn := Button.new()
|
||||
btn.text = "Create World"
|
||||
btn.pressed.connect(func(): template_selected.emit(template_id))
|
||||
vbox.add_child(btn)
|
||||
|
||||
_templates_container.add_child(panel)
|
||||
|
||||
|
||||
func _populate_recent_projects() -> void:
|
||||
_recent_list.clear()
|
||||
var recents: Array = MBWorldProjectIOClass.get_recent_projects()
|
||||
if recents.is_empty():
|
||||
_recent_list.add_item("(No recent projects)")
|
||||
_recent_list.set_item_disabled(0, true)
|
||||
else:
|
||||
for path in recents:
|
||||
var fname = str(path).get_file()
|
||||
_recent_list.add_item("📄 %s (%s)" % [fname, path])
|
||||
|
||||
|
||||
func _on_recent_item_activated(index: int) -> void:
|
||||
var recents: Array = MBWorldProjectIOClass.get_recent_projects()
|
||||
if index >= 0 and index < recents.size():
|
||||
var path: String = str(recents[index])
|
||||
project_opened.emit(path)
|
||||
|
||||
|
||||
func _on_open_file_pressed() -> void:
|
||||
_file_dialog.popup_centered(Vector2i(700, 450))
|
||||
|
||||
|
||||
func _on_file_dialog_selected(path: String) -> void:
|
||||
project_opened.emit(path)
|
||||
Reference in New Issue
Block a user