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 ) var current_rect_size = Vector2( 0, 0 ) var current_rect_position = Vector2( -1, -1 ) var is_resizing = false var is_moving = false 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(): ### # 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.rect_clip_content = true # 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_child( background ) background.set_owner( self ) ### ### var v_box_container # VBoxContainer if not self.has_node( "VBoxContainer" ): v_box_container = VBoxContainer.new() v_box_container.name = "VBoxContainer" v_box_container.size_flags_horizontal = SIZE_EXPAND_FILL v_box_container.size_flags_vertical = SIZE_EXPAND_FILL self.add_child( v_box_container ) v_box_container.set_owner( self ) ### ### # Header var header if not v_box_container.has_node( "Header" ): header = MarginContainer.new() header.name = "Header" header.size_flags_horizontal = SIZE_EXPAND_FILL header.size_flags_vertical = SIZE_SHRINK_CENTER header.set( "custom_constants/margin_right", 0) header.set( "custom_constants/margin_top", 4) header.set( "custom_constants/margin_left", 4) header.set( "custom_constants/margin_bottom", 4) if is_movable: header.mouse_default_cursor_shape = CURSOR_MOVE v_box_container.add_child( header ) header.set_owner( v_box_container ) header.connect ( "gui_input", self, "_on_Header_gui_input" ) ### ### var header_box # Header/HBoxContainer if not header.has_node( "HBoxContainer" ): header_box = HBoxContainer.new() header_box.name = "HBoxContainer" header_box.size_flags_horizontal = SIZE_EXPAND_FILL header_box.size_flags_vertical = SIZE_EXPAND | SIZE_SHRINK_CENTER if is_movable: header.mouse_default_cursor_shape = CURSOR_MOVE header.add_child( header_box ) header_box.set_owner( header ) ### ### # Quit var quit_button if not header_box.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_box.add_child( quit_button ) quit_button.set_owner( header_box ) quit_button.connect ( "pressed", self, "_on_Quit_pressed" ) ### # Close var close_button = TextureButton.new() if not header_box.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_box.add_child( close_button ) close_button.set_owner( header_box ) close_button.connect ( "pressed", self, "_on_Close_pressed" ) ### # Open var open_button if not header_box.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_box.add_child( open_button ) open_button.set_owner( header_box ) open_button.connect ( "pressed", self, "_on_Open_pressed" ) ### ### # Title Label var title_label if not header_box.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_box.add_child( title_label ) title_label.set_owner( header_box ) ### ### # Content var content if not v_box_container.has_node( "Content" ): content = MarginContainer.new() content.name = "Content" content.size_flags_horizontal = SIZE_EXPAND_FILL content.size_flags_vertical = SIZE_EXPAND_FILL content.set( "custom_constants/margin_right", 8) content.set( "custom_constants/margin_top", 8) content.set( "custom_constants/margin_left", 8) content.set( "custom_constants/margin_bottom", 8) v_box_container.add_child( content ) content.set_owner( v_box_container ) ### ### # Footer var footer if not v_box_container.has_node( "Footer" ): footer = MarginContainer.new() footer.name = "Footer" footer.size_flags_horizontal = SIZE_FILL footer.size_flags_vertical = SIZE_FILL footer.set( "custom_constants/margin_right", 6) footer.set( "custom_constants/margin_top", 2) footer.set( "custom_constants/margin_left", 6) footer.set( "custom_constants/margin_bottom", 6) v_box_container.add_child( footer ) footer.set_owner( v_box_container ) ### ### # Header/HBoxContainer var footer_box if not footer.has_node( "HBoxContainer" ): footer_box = HBoxContainer.new() footer_box.name = "HBoxContainer" footer_box.size_flags_horizontal = SIZE_FILL footer_box.size_flags_vertical = SIZE_FILL footer.add_child( footer_box ) footer_box.set_owner( footer ) ### ### # Open var resize_button if not footer_box.has_node( "Resize" ): resize_button = TextureButton.new() resize_button.name = "Resize" resize_button.size_flags_horizontal = SIZE_EXPAND | SIZE_SHRINK_END resize_button.size_flags_vertical = SIZE_EXPAND 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_box.add_child( resize_button ) resize_button.set_owner( footer_box ) resize_button.connect ( "pressed", self, "_on_Resize_pressed" ) ### current_rect_size = self.rect_min_size if is_borderless: $Background.region_rect = Rect2( 3, 28+3, 512-6, 512-28-6 ) $VBoxContainer/Header/HBoxContainer/Close.visible = false $VBoxContainer/Header/HBoxContainer/Open.visible = false $VBoxContainer/Header/HBoxContainer/Quit.visible = false $VBoxContainer/Header/HBoxContainer/Label.visible = false # else: # $Background.region_rect = Rect2( 0, 0, 512, 512 ) # $VBoxContainer/Header/HBoxContainer/Close.visible = true # $VBoxContainer/Header/HBoxContainer/Open.visible = false # $VBoxContainer/Header/HBoxContainer/Quit.visible = true # $VBoxContainer/Header/HBoxContainer/Label.visible = true if not is_resizable: $VBoxContainer/Footer/HBoxContainer/Resize.visible = false func _ready(): 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 $VBoxContainer/Content func close(): if not is_borderless: $VBoxContainer/Header/HBoxContainer/Close.visible = false $VBoxContainer/Header/HBoxContainer/Open.visible = true $VBoxContainer/Content.visible = false $VBoxContainer/Footer.visible = false current_rect_size = self.rect_size self.rect_size = Vector2( 0, 0 ) else: $VBoxContainer/Header/HBoxContainer/Close.visible = false $VBoxContainer/Header/HBoxContainer/Open.visible = false $VBoxContainer/Content.visible = false $VBoxContainer/Footer.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: $VBoxContainer/Header/HBoxContainer/Close.visible = true $VBoxContainer/Header/HBoxContainer/Open.visible = false $VBoxContainer/Content.visible = true $VBoxContainer/Footer.visible = true self.rect_size = current_rect_size else: $VBoxContainer/Header/HBoxContainer/Close.visible = false $VBoxContainer/Header/HBoxContainer/Open.visible = false $VBoxContainer/Content.visible = true $VBoxContainer/Footer.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 # # var mouse_position = get_viewport().get_mouse_position() # var size_modulo = Vector2( int(self.rect_size.x) % 2, int(self.rect_size.y) % 2 ) # self.rect_size -= size_modulo # get_viewport().warp_mouse( mouse_position - size_modulo ) 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 # self.rect_position -= Vector2( int(self.rect_size.x) % 2, int(self.rect_size.y) % 2 ) # get_viewport().warp_mouse( get_viewport().get_mouse_position() - Vector2( int(get_viewport().get_mouse_position().x) % 2, int(get_viewport().get_mouse_position().y) % 2 ) ) 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 = $VBoxContainer/Content.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)