470 lines
No EOL
16 KiB
GDScript
470 lines
No EOL
16 KiB
GDScript
extends MarginContainer
|
|
|
|
export(bool) var is_movable = true
|
|
export(bool) var is_resizable = true
|
|
export(bool) var is_borderless = false
|
|
export(String) var title = "Window"
|
|
export(Color) var background_color = Color( 1.0, 1.0, 1.0, 1.0 )
|
|
|
|
export(String) var background_texture = "res://assets/GUI/images/background_test.png"
|
|
|
|
signal window_clicked( window )
|
|
|
|
onready var header_box = $parts/header_box
|
|
onready var content_box = $parts/content_box
|
|
onready var footer_box = $parts/footer_box
|
|
|
|
var current_rect_size = Vector2( 0, 0 )
|
|
var current_rect_position = Vector2( -1, -1 )
|
|
var is_resizing = false
|
|
var is_moving = false
|
|
|
|
func add_child( node):
|
|
if self.get_content():
|
|
self.get_content().add_child(node)
|
|
# else:
|
|
# .add_child( node )
|
|
# prints(self.get_name()+" just fathered", node.get_name())
|
|
|
|
func add_window_part( node ):
|
|
.add_child( node )
|
|
|
|
func set_mouse_pass_to_children( node ):
|
|
for child in node.get_children():
|
|
set_mouse_pass_to_children( child )
|
|
if node is Control:
|
|
node.mouse_filter = MOUSE_FILTER_PASS
|
|
|
|
#func _ready():
|
|
func _enter_tree():
|
|
########
|
|
#### Window's part création.
|
|
# The interal elements structure is:
|
|
# self - MarginContainer
|
|
# background - NinePatchRect
|
|
# parts - VBoxContainer
|
|
# header_box - MarginContainer
|
|
# header - HBoxContainer
|
|
# quit - TextureButton
|
|
# close - TextureButton
|
|
# open - TextureButton
|
|
# label - Label
|
|
# content_box - MarginContainer
|
|
# scroll_container - Scrollcontainer
|
|
# content - VBoxContainer
|
|
# footer_box - MarginContainer
|
|
# footer - HBoxContainer
|
|
# contextual_help - Label
|
|
# resize - TextureButton
|
|
|
|
###
|
|
# self
|
|
self.size_flags_horizontal = SIZE_EXPAND
|
|
self.size_flags_vertical = SIZE_EXPAND
|
|
|
|
self.set( "custom_constants/margin_right", 0)
|
|
self.set( "custom_constants/margin_top", 0)
|
|
self.set( "custom_constants/margin_left", 0)
|
|
self.set( "custom_constants/margin_bottom", 0)
|
|
|
|
|
|
self.connect ( "gui_input", self, "_on_window_gui_input" )
|
|
###
|
|
###
|
|
# background
|
|
var background
|
|
if not self.has_node( "background" ):
|
|
background = NinePatchRect.new()
|
|
background.name = "background"
|
|
var background_image = Image.new()
|
|
if not background_image.load( background_texture ):
|
|
print("Erreur lors du chargement de l'image: "+background_texture )
|
|
background.texture = ImageTexture.new()
|
|
background.texture.create_from_image( background_image )
|
|
background.texture.flags = Texture.FLAG_FILTER | Texture.FLAG_REPEAT
|
|
background.axis_stretch_horizontal = NinePatchRect.AXIS_STRETCH_MODE_TILE
|
|
background.axis_stretch_vertical = NinePatchRect.AXIS_STRETCH_MODE_TILE
|
|
|
|
background.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
background.size_flags_vertical = SIZE_EXPAND_FILL
|
|
|
|
background.region_rect = Rect2( 0, 0, 0, 0 )
|
|
background.patch_margin_left = 4
|
|
background.patch_margin_top = 32
|
|
background.patch_margin_right = 4
|
|
background.patch_margin_bottom = 4
|
|
|
|
background.self_modulate = background_color
|
|
|
|
self.add_window_part( background )
|
|
background.set_owner( self )
|
|
###
|
|
###
|
|
# parts
|
|
var parts
|
|
if not self.has_node( "parts" ):
|
|
parts = VBoxContainer.new()
|
|
parts.name = "parts"
|
|
parts.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
parts.size_flags_vertical = SIZE_EXPAND_FILL
|
|
self.add_window_part( parts )
|
|
parts.set_owner( self )
|
|
###
|
|
###
|
|
# header_box
|
|
var header_box
|
|
if not parts.has_node( "header_box" ):
|
|
header_box = MarginContainer.new()
|
|
header_box.name = "header_box"
|
|
header_box.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
header_box.size_flags_vertical = SIZE_SHRINK_CENTER
|
|
|
|
header_box.set( "custom_constants/margin_right", 0)
|
|
header_box.set( "custom_constants/margin_top", 4)
|
|
header_box.set( "custom_constants/margin_left", 4)
|
|
header_box.set( "custom_constants/margin_bottom", 4)
|
|
|
|
if is_movable:
|
|
header_box.mouse_default_cursor_shape = CURSOR_MOVE
|
|
parts.add_child( header_box )
|
|
header_box.set_owner( parts )
|
|
header_box.connect ( "gui_input", self, "_on_Header_gui_input" )
|
|
###
|
|
###
|
|
# header
|
|
var header
|
|
if not header_box.has_node( "header" ):
|
|
header = HBoxContainer.new()
|
|
header.name = "header"
|
|
header.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
header.size_flags_vertical = SIZE_EXPAND | SIZE_SHRINK_CENTER
|
|
if is_movable:
|
|
header.mouse_default_cursor_shape = CURSOR_MOVE
|
|
header_box.add_child( header )
|
|
header.set_owner( header )
|
|
###
|
|
###
|
|
# quit
|
|
var quit_button
|
|
if not header.has_node( "quit" ):
|
|
quit_button = TextureButton.new()
|
|
quit_button.name = "quit"
|
|
quit_button.size_flags_horizontal = SIZE_SHRINK_END
|
|
quit_button.size_flags_vertical = SIZE_SHRINK_CENTER
|
|
|
|
var tex_quit = ImageTexture.new()
|
|
var img_quit = Image.new()
|
|
img_quit.load( "res://assets/GUI/images/button_quit.png" )
|
|
tex_quit.create_from_image( img_quit )
|
|
quit_button.texture_normal = tex_quit
|
|
|
|
header.add_child( quit_button )
|
|
quit_button.set_owner( header )
|
|
quit_button.connect ( "pressed", self, "_on_Quit_pressed" )
|
|
###
|
|
# close
|
|
var close_button = TextureButton.new()
|
|
if not header.has_node( "close" ):
|
|
close_button = TextureButton.new()
|
|
close_button.name = "close"
|
|
close_button.size_flags_horizontal = SIZE_SHRINK_END
|
|
close_button.size_flags_vertical = SIZE_SHRINK_CENTER
|
|
|
|
var tex_close = ImageTexture.new()
|
|
var img_close = Image.new()
|
|
img_close.load( "res://assets/GUI/images/button_close.png" )
|
|
tex_close.create_from_image( img_close )
|
|
close_button.texture_normal = tex_close
|
|
|
|
header.add_child( close_button )
|
|
close_button.set_owner( header )
|
|
close_button.connect ( "pressed", self, "_on_Close_pressed" )
|
|
###
|
|
# open
|
|
var open_button
|
|
if not header.has_node( "open" ):
|
|
open_button = TextureButton.new()
|
|
open_button.name = "open"
|
|
open_button.size_flags_horizontal = SIZE_SHRINK_END
|
|
open_button.size_flags_vertical = SIZE_SHRINK_CENTER
|
|
|
|
var tex_open = ImageTexture.new()
|
|
var img_open = Image.new()
|
|
img_open.load( "res://assets/GUI/images/button_open.png" )
|
|
tex_open.create_from_image( img_open )
|
|
open_button.texture_normal = tex_open
|
|
open_button.visible = false
|
|
header.add_child( open_button )
|
|
open_button.set_owner( header )
|
|
open_button.connect ( "pressed", self, "_on_Open_pressed" )
|
|
###
|
|
###
|
|
# Title Label
|
|
var title_label
|
|
if not header.has_node( "label" ):
|
|
title_label = Label.new()
|
|
title_label.name = "label"
|
|
title_label.text = title
|
|
title_label.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
title_label.size_flags_vertical = SIZE_SHRINK_CENTER
|
|
if is_movable:
|
|
title_label.mouse_default_cursor_shape = CURSOR_MOVE
|
|
header.add_child( title_label )
|
|
title_label.set_owner( header )
|
|
###
|
|
###
|
|
# Content
|
|
var content_box
|
|
if not parts.has_node( "content_box" ):
|
|
content_box = MarginContainer.new()
|
|
content_box.name = "content_box"
|
|
content_box.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
content_box.size_flags_vertical = SIZE_EXPAND_FILL
|
|
content_box.set( "custom_constants/margin_right", 8)
|
|
content_box.set( "custom_constants/margin_top", 8)
|
|
content_box.set( "custom_constants/margin_left", 8)
|
|
content_box.set( "custom_constants/margin_bottom", 8)
|
|
parts.add_child( content_box )
|
|
content_box.set_owner( parts )
|
|
###
|
|
###
|
|
# content_box/scroll_container
|
|
var content_scroll_container
|
|
if not content_box.has_node( "scroll_container" ):
|
|
content_scroll_container = ScrollContainer.new()
|
|
content_scroll_container.name = "scroll_container"
|
|
content_scroll_container.size_flags_horizontal = SIZE_FILL
|
|
content_scroll_container.size_flags_vertical = SIZE_FILL
|
|
content_box.add_child( content_scroll_container )
|
|
content_scroll_container.set_owner( content_box )
|
|
###
|
|
###
|
|
# content
|
|
var content
|
|
if not content_scroll_container.has_node( "content" ):
|
|
content = VBoxContainer.new()
|
|
content.name = "content"
|
|
content.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
content.size_flags_vertical = SIZE_EXPAND_FILL
|
|
content_scroll_container.add_child( content )
|
|
content.set_owner( content_scroll_container )
|
|
###
|
|
|
|
|
|
###
|
|
# Footer
|
|
var footer_box
|
|
if not parts.has_node( "footer_box" ):
|
|
footer_box = MarginContainer.new()
|
|
footer_box.name = "footer_box"
|
|
footer_box.size_flags_horizontal = SIZE_FILL
|
|
footer_box.size_flags_vertical = SIZE_FILL
|
|
footer_box.set( "custom_constants/margin_right", 6)
|
|
footer_box.set( "custom_constants/margin_top", 2)
|
|
footer_box.set( "custom_constants/margin_left", 6)
|
|
footer_box.set( "custom_constants/margin_bottom", 6)
|
|
parts.add_child( footer_box )
|
|
footer_box.set_owner( parts )
|
|
###
|
|
###
|
|
# footer_box/footer
|
|
var footer
|
|
if not footer_box.has_node( "footer" ):
|
|
footer = HBoxContainer.new()
|
|
footer.name = "footer"
|
|
footer.size_flags_horizontal = SIZE_EXPAND_FILL
|
|
footer.size_flags_vertical = SIZE_EXPAND_FILL
|
|
footer_box.add_child( footer )
|
|
footer.set_owner( footer_box )
|
|
###
|
|
###
|
|
# footer_label
|
|
var footer_label
|
|
if not footer.has_node( "footer_label" ):
|
|
footer_label = Label.new()
|
|
footer_label.name = "footer_label"
|
|
footer_label.size_flags_horizontal = SIZE_EXPAND
|
|
footer_label.size_flags_vertical = SIZE_EXPAND
|
|
|
|
footer.add_child( footer_label )
|
|
|
|
###
|
|
# resize
|
|
var resize_button
|
|
if not footer.has_node( "resize" ):
|
|
resize_button = TextureButton.new()
|
|
resize_button.name = "resize"
|
|
resize_button.size_flags_horizontal = SIZE_FILL | SIZE_SHRINK_END
|
|
resize_button.size_flags_vertical = SIZE_SHRINK_END
|
|
|
|
var tex_resize = ImageTexture.new()
|
|
var img_resize = Image.new()
|
|
img_resize.load( "res://assets/GUI/images/button_resize.png" )
|
|
tex_resize.create_from_image( img_resize )
|
|
resize_button.texture_normal = tex_resize
|
|
resize_button.mouse_default_cursor_shape = CURSOR_FDIAGSIZE
|
|
resize_button.action_mode = Button.ACTION_MODE_BUTTON_PRESS
|
|
footer.add_child( resize_button )
|
|
resize_button.set_owner( footer )
|
|
resize_button.connect ( "pressed", self, "_on_Resize_pressed" )
|
|
###er_label.set_owner( footer )
|
|
###
|
|
|
|
current_rect_size = self.rect_min_size
|
|
|
|
if is_borderless:
|
|
$background.region_rect = Rect2( $background.patch_margin_left-1
|
|
, $background.patch_margin_top-1
|
|
, 256-($background.patch_margin_left+$background.patch_margin_right)+2
|
|
, 256-($background.patch_margin_top+$background.patch_margin_bottom)+2 )
|
|
$background.patch_margin_left = 1
|
|
$background.patch_margin_top = 1
|
|
$background.patch_margin_right = 1
|
|
$background.patch_margin_bottom = 1
|
|
close_button.visible = false
|
|
open_button.visible = false
|
|
quit_button.visible = false
|
|
title_label.visible = false
|
|
|
|
|
|
|
|
|
|
if not is_resizable:
|
|
$v_box_container/Footer/HBoxContainer/Resize.visible = false
|
|
|
|
func _ready():
|
|
# On déplace les enfants ajouter via l'editeur sous content.
|
|
for child in self.get_children():
|
|
if not child.name =="parts" and not child.name =="background":
|
|
if child.name.begins_with( "footer_" ):
|
|
if footer_box.get_node("footer").has_node("footer_label"):
|
|
footer_box.get_node("footer").remove_child( footer_box.get_node("footer").get_node("footer_label") )
|
|
|
|
self.remove_child( child )
|
|
get_footer().add_child( child )
|
|
get_footer().move_child( child, 0 )
|
|
else:
|
|
self.remove_child( child )
|
|
get_content().add_child( child )
|
|
|
|
set_mouse_pass_to_children( self )
|
|
|
|
|
|
|
|
func _on_Window_mouse_entered():
|
|
print("mouse_entered")
|
|
|
|
|
|
func _on_Window_focus_entered():
|
|
print("focus_entered")
|
|
|
|
|
|
func _on_Quit_pressed():
|
|
self.visible = false
|
|
|
|
func get_content():
|
|
return content_box.get_node( "scroll_container/content" )
|
|
|
|
func get_footer():
|
|
return footer_box.get_node( "footer" )
|
|
|
|
|
|
func close():
|
|
if not is_borderless:
|
|
header_box.get_node( "header/close" ).visible = false
|
|
header_box.get_node( "header/open" ).visible = true
|
|
content_box.visible = false
|
|
footer_box.visible = false
|
|
current_rect_size = self.rect_size
|
|
self.rect_size = Vector2( 0, 0 )
|
|
else:
|
|
header_box.get_node( "header/close" ).visible = false
|
|
header_box.get_node( "header/open" ).visible = false
|
|
content_box.visible = false
|
|
footer_box.visible = false
|
|
current_rect_size = self.rect_size
|
|
self.rect_size = Vector2( 0, 0 )
|
|
|
|
|
|
func _on_Close_pressed():
|
|
close()
|
|
|
|
func open():
|
|
if not is_borderless:
|
|
header_box.get_node( "header/close" ).visible = true
|
|
header_box.get_node( "header/open" ).visible = false
|
|
content_box.visible = true
|
|
footer_box.visible = true
|
|
self.rect_size = current_rect_size
|
|
else:
|
|
header_box.get_node( "header/close" ).visible = false
|
|
header_box.get_node( "header/open" ).visible = false
|
|
content_box.visible = true
|
|
footer_box.visible = true
|
|
self.rect_size = current_rect_size
|
|
|
|
func _on_Open_pressed():
|
|
open()
|
|
|
|
func _on_Resize_pressed():
|
|
is_resizing = true
|
|
|
|
func _input( event ):
|
|
if is_resizable:
|
|
if is_resizing and event is InputEventMouseButton and not event.pressed:
|
|
is_resizing = false
|
|
if event is InputEventMouseMotion and is_resizing:
|
|
var delta = event.relative
|
|
self.rect_size += delta
|
|
|
|
func check_if_clicked( event ):
|
|
if not is_moving and event is InputEventMouseButton and event.is_pressed() and not event.is_echo() and event.button_index == 1 :
|
|
emit_signal( "window_clicked", self )
|
|
|
|
func _on_Header_gui_input( event ):
|
|
|
|
check_if_clicked( event )
|
|
|
|
if is_movable:
|
|
if is_moving and event is InputEventMouseButton and not event.pressed:
|
|
is_moving = false
|
|
elif not is_moving and event is InputEventMouseButton and event.pressed:
|
|
is_moving = true
|
|
if event is InputEventMouseMotion and is_moving:
|
|
var delta = event.relative
|
|
self.rect_position += delta
|
|
|
|
func _on_window_gui_input( event ):
|
|
check_if_clicked( event )
|
|
|
|
func load_from_file( config_file ):
|
|
if config_file.has_section( self.name ):
|
|
self.rect_position = config_file.get_value( self.name, "position" )
|
|
self.rect_size = config_file.get_value( self.name, "size" )
|
|
self.is_borderless = config_file.get_value( self.name, "borderless" )
|
|
current_rect_position = self.rect_position
|
|
current_rect_size = self.rect_size
|
|
if config_file.get_value( self.name, "opened" ):
|
|
open()
|
|
else:
|
|
close()
|
|
|
|
|
|
func save_to_file( config_file ):
|
|
|
|
var is_open = content_box.visible
|
|
|
|
config_file.set_value(self.name, "position", self.rect_position)
|
|
|
|
if not is_open:
|
|
config_file.set_value(self.name, "size", current_rect_size)
|
|
else:
|
|
config_file.set_value(self.name, "size", self.rect_size)
|
|
|
|
if is_open:
|
|
config_file.set_value(self.name, "opened", true)
|
|
else:
|
|
config_file.set_value(self.name, "opened", false)
|
|
|
|
config_file.set_value(self.name, "borderless", is_borderless)
|
|
|