diff --git a/design/youth-construction.blend b/design/youth-construction.blend index 404c621..870783d 100644 Binary files a/design/youth-construction.blend and b/design/youth-construction.blend differ diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index 916a669..2877ff8 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -6,7 +6,7 @@ extends PanelContainer # "post_its_in_list": [], # "post_it_panels": [] #} -enum ui_context {DROPZONE, POST_IT_LIST, ASSIGN_POST_IT} +enum {DROPZONE, POST_IT_LIST, DRAGGING, ASSIGN_POST_IT} var has_stage = false: set(focus): @@ -30,7 +30,17 @@ var dropzone_size: Vector2 @onready var postit_container = $HBoxContainer/ScrollContainer/VBoxContainer @onready var board_of_devs = $"board of devs" var base_postit_panel: Panel -@onready var active_context = ui_context.DROPZONE # 0 = dropzone, 1 = post it list +@onready var current_context = DROPZONE: + set(context): + match context: + DROPZONE: + pass + POST_IT_LIST: + pass + DRAGGING: + pass + ASSIGN_POST_IT: + pass @onready var instructions = $instructions_panel/HBoxContainer/cards_remaining var mementos_collected: int = 0: @@ -46,14 +56,19 @@ var mementos_collected: int = 0: 4: instructions.text = "Combine cards to order your thoughts." -var currently_selected_node: Area2D = null -var currently_selected_card_for_assigning: Area2D = null -var is_area_dragged: bool = false -var currently_dragged_area: Area2D +var currently_active_node: Area2D = null -var selected_dropzone_element: int = -1 -var selected_postit_list_element: int = 0 -var selected_card_for_assignment +@onready var current_dropzone_id: int = 0: + set(new_id): + if new_id > dropzone.get_child_count() - 1: current_dropzone_id = 0 + elif new_id < 0: current_dropzone_id = dropzone.get_child_count() - 1 + else: current_dropzone_id = new_id + +var current_postIt_id: int = 0: + set(new_id): + if new_id > postit_container.get_child_count() - 1: current_postIt_id = 0 + elif new_id < 0: current_postIt_id = postit_container.get_child_count() - 1 + else: current_postIt_id = new_id var cache: Array = [] @@ -69,20 +84,13 @@ func _ready(): if get_parent() == get_tree().root: populate_board(["c_void", 'c_joy', "p_wet", "p_thomas"]) populate_board(["c_fighting", 'c_hit', "p_girly", "p_vent"]) - - active_context = ui_context.DROPZONE - + has_stage = has_stage - -# Called every frame. 'delta' is the elapsed time since the previous frame. + func _process(delta): - # Reset information about Areas being dragged, if the mouse is not longer pressed. - # Needed because otherwise it can happen that the areas don't register it if you stop clicking on them. - if has_stage and !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and is_area_dragged: - currently_dragged_area.is_dragged = false - is_area_dragged = false - currently_dragged_area = null - + # drops dragged area when Mouse is no longer pressed. + if has_stage and !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and current_context == DRAGGING: + currently_active_node.is_dragged = false # Will be used later to spawn Cards and Post-Its and remember them in the dictionary func populate_board(card_names: Array): @@ -96,28 +104,20 @@ func populate_board(card_names: Array): # spawning the cards and adding them to the dictionary for new_card in all_new["cards"]: new_card.position = Vector2(randi_range(dropzone_padding, dropzone_size.x), randi_range(dropzone_padding, dropzone_size.y)) - new_card.reparent(dropzone, false) + insert_area(dropzone, new_card) new_card.set_owner(self) - #area_dict["dropzone_content"].push_back(new_card) - #area_dict["cards"].push_back(new_card) new_card.is_dragable = true for new_postit in all_new["postIts"]: # spawning a post-it var new_panel = base_postit_panel.duplicate() postit_container.add_child(new_panel) new_panel.set_owner(self) - #area_dict["post_it_panels"].append(new_panel) new_panel.add_child(new_postit) new_postit.set_owner(self) - #area_dict["post_its_in_list"].push_back(new_postit) new_postit.position = new_panel.get_child(0).position new_postit.is_dragable = true - #currently_selected_node = area_dict["dropzone_content"][0] # set first Card as currently selected node by default - currently_selected_node = dropzone.get_child(0) - - reorder_areas("dropzone_content") - reorder_areas("cards") - reorder_areas("post_its_in_list") + #currently_active_node = area_dict["dropzone_content"][0] # set first Card as currently selected node by default + currently_active_node = dropzone.get_child(0) # Checks if a Node is currently inside the dropzone func is_in_dropzone(to_check: Node) -> bool: @@ -129,30 +129,25 @@ func handle_mouse_button(to_handle: Area2D, input: InputEvent): # No two areas can be dragged at the same time. # Make sure that only the same area is dragged. # Otherwise overlapping areas are dragged at the same time. - if currently_dragged_area != null and to_handle != currently_dragged_area: + if current_context == DRAGGING: return - currently_selected_node = to_handle # update currently selected - currently_dragged_area = to_handle + currently_active_node = to_handle # update currently selected to_handle.is_dragged = input.pressed - is_area_dragged = input.pressed + if input.pressed: + current_context = DRAGGING # Check what is being dragged if to_handle is Card: - active_context = ui_context.DROPZONE - if input.is_pressed(): - reorder_areas("dropzone_content") - reorder_areas("cards") - else: - dropzone.move_child(currently_dragged_area, -1) - currently_dragged_area = null + current_context = DROPZONE + if !input.is_pressed(): + insert_area(dropzone, to_handle) + current_context = dropzone elif to_handle is PostIt: if input.is_action_pressed("mouse_left"): to_handle.reparent(dropzone) to_handle.on_board = true to_handle.set_owner(self) # needs to be here otherwise the owner disappears - #area_dict["post_its_in_list"].erase(to_handle) - #area_dict["dropzone_content"].push_back(to_handle) elif input.is_action_pressed("mouse_right"): _return_postit_to_panels(to_handle) to_handle.is_dragged = false @@ -169,7 +164,7 @@ func handle_mouse_button(to_handle: Area2D, input: InputEvent): to_handle.rotation = to_handle.base_rotation to_handle.scale = to_handle.base_scale else: - active_context = ui_context.POST_IT_LIST + current_context = POST_IT_LIST _return_postit_to_panels(to_handle) currently_dragged_area = null @@ -178,7 +173,7 @@ func handle_mouse_button(to_handle: Area2D, input: InputEvent): func attach_postit_to_card(postit: Area2D, card: Area2D, preview = false): if card.has_postit_attached(): - if active_context == ui_context.ASSIGN_POST_IT: + if current_context == ASSIGN_POST_IT: _return_postit_to_panels(postit) # don't attach if card has already a post-it attached return @@ -189,10 +184,6 @@ func attach_postit_to_card(postit: Area2D, card: Area2D, preview = false): # area_dict["post_its_in_list"].erase(postit) # area_dict["dropzone_content"].push_back(postit) - reorder_areas("dropzone_content") - reorder_areas("cards") - reorder_areas("post_its_in_list") - func is_board_complete() -> bool: if mementos_collected == 4: for card in dropzone.get_children(): @@ -210,35 +201,27 @@ func is_board_lore() -> bool: # Mark area that was hovered over as currently selected func handle_hover(to_handle: Area2D): - if to_handle != currently_selected_node: - currently_selected_node.highlighted = false - currently_selected_node = to_handle + if to_handle != currently_active_node: + currently_active_node.highlighted = false + currently_active_node = to_handle if is_in_dropzone(to_handle): - selected_dropzone_element = area_dict["dropzone_content"].find(to_handle) - active_context = ui_context.DROPZONE + current_dropzone_id = area_dict["dropzone_content"].find(to_handle) + current_context = DROPZONE else: - selected_postit_list_element = area_dict["post_its_in_list"].find(to_handle) - active_context = ui_context.POST_IT_LIST + current_postIt_id = area_dict["post_its_in_list"].find(to_handle) + current_context = POST_IT_LIST - -# Reorders the areas in any of the dictionaries entries -# Pass the entry's key in order to reorder it -func reorder_areas(reorder: String): - var old_order = area_dict[reorder] - var new_order = Array() +# Adds a child at the correct child indext in an area +func insert_area(parent: Control, node: Area2D): + var children = parent.get_children() + var i = 0 - for obj in old_order: - var i = 0 - if !new_order.is_empty(): - for obj_2 in new_order: - if obj_2.global_position.y < obj.global_position.y: - i += 1 - new_order.insert(i, obj) + if children != []: while children[i].global_position.y > node.global_position.y: i+=1 - area_dict[reorder] = new_order + if not node in get_children(): node.reparent(parent) + parent.move_child(node, i) - # Takes the inputs for control inputs func _input(event): @@ -246,136 +229,44 @@ func _input(event): State.leave_stage(self) # Return, if the input is a mouse event (mouse events are handled separately) - if event is InputEventMouse or !has_stage or not is_instance_valid(currently_selected_node): return + if event is InputEventMouse or !has_stage or not is_instance_valid(currently_active_node): return if event.is_action_pressed("ui_up"): # up to select an element above - match active_context: - ui_context.DROPZONE: - selected_dropzone_element -= 1 - ui_context.POST_IT_LIST: - selected_postit_list_element -= 1 - ui_context.ASSIGN_POST_IT: - selected_card_for_assignment -= 1 + if current_context == POST_IT_LIST: + current_postIt_id -= 1 + else: + current_dropzone_id -= 1 elif event.is_action_pressed("ui_down"): # down to select an element beneath - match active_context: - ui_context.DROPZONE: - selected_dropzone_element += 1 - ui_context.POST_IT_LIST: - selected_postit_list_element += 1 - ui_context.ASSIGN_POST_IT: - selected_card_for_assignment += 1 + if current_context == POST_IT_LIST: + current_postIt_id += 1 + else: + current_dropzone_id += 1 elif event.is_action_pressed("ui_left"): # left to switch context to the left - if active_context == ui_context.ASSIGN_POST_IT: - _return_postit_to_panels(currently_selected_node) - _leave_assignment_context() - - active_context -= 1 - if active_context <= -1: - active_context = ui_context.POST_IT_LIST + if current_context == POST_IT_LIST: + current_context = DROPZONE elif event.is_action_pressed("ui_right"): # right to switch context to the right - if active_context == ui_context.ASSIGN_POST_IT: - _return_postit_to_panels(currently_selected_node) - _leave_assignment_context() - - active_context += 1 - if active_context > 1: - active_context = ui_context.DROPZONE + current_context = POST_IT_LIST elif event.is_action_pressed("ui_accept"): # select the selected post it - if active_context == ui_context.ASSIGN_POST_IT: # to assign it to a card - attach_postit_to_card(currently_selected_node, - currently_selected_card_for_assigning, false) - _leave_assignment_context() + var card:Card = dropzone.get_child(current_dropzone_id) + if current_context == ASSIGN_POST_IT: # to assign it to a card + if card.has_postit_attached(): + currently_active_node = card.exchange_postIt_with(currently_active_node) + else: + card.attach_postit(currently_active_node) + current_context = DROPZONE else: - _enter_assignment_context() - - # do some adjustments to loop elements (after last element, select first one etc.) - if selected_dropzone_element < 0: - selected_dropzone_element = area_dict["dropzone_content"].size()-1 - elif selected_dropzone_element > area_dict["dropzone_content"].size()-1: - selected_dropzone_element = 0 - - if selected_postit_list_element < 0: - selected_postit_list_element = area_dict["post_its_in_list"].size()-1 - elif selected_postit_list_element > area_dict["post_its_in_list"].size()-1: - selected_postit_list_element = 0 - - if active_context == ui_context.ASSIGN_POST_IT: # skip this if we're not in assign post it context - if selected_card_for_assignment < 0: - selected_card_for_assignment = area_dict["cards"].size()-1 - elif selected_card_for_assignment > area_dict["cards"].size()-1: - selected_card_for_assignment = 0 - - # highlight the selected element - match active_context: - ui_context.DROPZONE: - currently_selected_node.highlighted = false - currently_selected_node = area_dict["dropzone_content"][selected_dropzone_element] - currently_selected_node.highlighted = true - ui_context.POST_IT_LIST: - currently_selected_node.highlighted = false - currently_selected_node = area_dict["post_its_in_list"][selected_postit_list_element] - currently_selected_node.highlighted = true - ui_context.ASSIGN_POST_IT: - currently_selected_card_for_assigning.highlighted = false - currently_selected_card_for_assigning = area_dict["cards"][selected_card_for_assignment] - currently_selected_card_for_assigning.highlighted = true - _select_card_for_assigning(currently_selected_node, currently_selected_card_for_assigning) - - # update dictiornary orders - reorder_areas("dropzone_content") - reorder_areas("post_its_in_list") - - -# Sets everything up to enter the context where postits can be assigned via button controls -func _enter_assignment_context(): - # cards are currently not moved, only post its. Exit function if a card should be moved. - if currently_selected_node == null or not currently_selected_node is PostIt : return - - # if the postit is already attached, remove it and return it to the post it panels - if currently_selected_node.is_postit_attached(): - _return_postit_to_panels(currently_selected_node) - active_context = ui_context.POST_IT_LIST - return - - # adjust everything for the post it to select its attach-target - active_context = ui_context.ASSIGN_POST_IT - selected_card_for_assignment = 0 - currently_selected_node.reparent(dropzone) # reparent to make it visible - currently_selected_node.set_owner(self) - area_dict["post_its_in_list"].erase(currently_selected_node) - area_dict["dropzone_content"].push_back(currently_selected_node) - currently_selected_card_for_assigning = area_dict["dropzone_content"][0] - currently_selected_card_for_assigning.highlighted = true + if card.has_postit_attached(): + currently_active_node = card.remove_postIt() + current_context == ASSIGN_POST_IT # move the post it so it floats next to the card where it should be attached func _select_card_for_assigning(post_it: Area2D, card: Area2D): post_it.tween_transform_to(card.get_child(3).global_position) -# leaves the context for assigning postit via button controls -func _leave_assignment_context(): - currently_selected_node.highlighted = false - active_context = ui_context.DROPZONE - currently_selected_node = currently_selected_card_for_assigning - -# handles everything to return a post it to the panels -func _return_postit_to_panels(post_it: Area2D): - for panel in area_dict["post_it_panels"]: - if panel.get_child_count() == 1: - area_dict["dropzone_content"].erase(post_it) - post_it.on_board = false - area_dict["post_its_in_list"].push_back(post_it) - post_it.reparent(panel) - post_it.transform = panel.get_child(0).transform - post_it.set_owner(self) - #post_it.position = Vector2(0,0) - reorder_areas("dropzone_content") - reorder_areas("post_its_in_list") - break - func on_scene_skipped(i: int): mementos_collected += i diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index 203f1a0..9453d76 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -5,10 +5,6 @@ class_name Card var compatible_postits: Array[PostIt] = [] var own_postits: Array[PostIt] = [] var current_post_it: PostIt = null -var is_in_preview: bool = false: - set(preview): - is_in_preview = preview - highlighted = preview var wiggle_pos: float = 0 var wiggle_intensity: float = 0 var noise: Noise = FastNoiseLite.new() @@ -57,7 +53,7 @@ var scale_tween @export var voice_line: AudioStream = null @export var is_dragable: bool = false @onready var diameter = $CollisionShape2D.shape.height -@onready var postit_anchor = get_child(3) +@onready var postit_anchor: Control = get_child(3) var is_dragged: bool = false: set(dragged): @@ -157,11 +153,13 @@ func _move_card(): position += (get_viewport().get_mouse_position() - position) - mouse_offset func has_postit_attached() -> bool: - return is_instance_valid(current_post_it) and not is_in_preview + return is_instance_valid(current_post_it) -func preview_postit(postit: PostIt) -> bool: - is_in_preview = attach_postit(postit) - return is_in_preview +func preview_postit(postit: PostIt): + if has_postit_attached(): + postit.tween_transform_to(postit_anchor.global_transform + postit.diameter) + else: + postit.tween_transform_to(postit_anchor.global_transform) func attach_postit(postit: PostIt) -> bool: if is_instance_valid(current_post_it): @@ -169,16 +167,21 @@ func attach_postit(postit: PostIt) -> bool: postit.reparent(get_child(3, true)) postit.position = Vector2(0,0) postit.on_board = false - if not is_in_preview: current_post_it = postit + current_post_it = postit return true func remove_postit() -> PostIt: + if not is_instance_valid(current_post_it): return null var former_child:PostIt = current_post_it current_post_it = null former_child.reparent(get_parent()) former_child.on_board = true - is_in_preview = false return former_child + +func exchange_postIt_with(new_post: PostIt) -> PostIt: + var tmp = remove_postit() + attach_postit(new_post) + return tmp func check_hover(): if is_mouse_entered: diff --git a/src/logic-scenes/board/empty_postIt_panel.gd b/src/logic-scenes/board/empty_postIt_panel.gd new file mode 100644 index 0000000..d16d8a0 --- /dev/null +++ b/src/logic-scenes/board/empty_postIt_panel.gd @@ -0,0 +1,40 @@ +class_name PostItPanel +extends Panel + +var stored_costum_minimum_size:Vector2 +var attatched_postIt: PostIt +@onready var ancor = $"post-it_anchor" + +func _ready(): + stored_costum_minimum_size = custom_minimum_size + ancor.position = Vector2(ancor.position.x, 0) + custom_minimum_size = Vector2(custom_minimum_size.x, 0) + +func attatch_postit(attatchment: PostIt, tween:bool = true): + attatchment.on_board = false + if tween: + var height_tween: Tween = create_tween() + height_tween.tween_property(self, "custom_minimum_size", stored_costum_minimum_size, 0.3) + height_tween.tween_property(ancor, "position", Vector2(ancor.position.x, stored_costum_minimum_size.y/2), 0.3) + attatchment.tween_transform_to(ancor.global_position) + await attatchment.transform_tween_finished + attatchment.reparent(self) + attatched_postIt = attatchment + attatchment.owner = self.owner + +func lend_postit() -> PostIt: + attatched_postIt.on_board = true + return attatched_postIt + +func return_postit(): + attatched_postIt.on_board = false + attatched_postIt.tween_transform_to(ancor.global_position) + await attatched_postIt.transform_tween_finished + attatched_postIt.reparent(self) + attatched_postIt.owner = self.owner + +func dissolve(): + var height_tween: Tween = create_tween() + height_tween.tween_property(self, "custom_minimum_size", Vector2.ZERO, 0.3) + await height_tween.finished + self.free() diff --git a/src/logic-scenes/board/empty_postIt_panel.tscn b/src/logic-scenes/board/empty_postIt_panel.tscn index cb47962..b5c5836 100644 --- a/src/logic-scenes/board/empty_postIt_panel.tscn +++ b/src/logic-scenes/board/empty_postIt_panel.tscn @@ -1,9 +1,14 @@ -[gd_scene format=3 uid="uid://chwf61qpn2sqw"] +[gd_scene load_steps=2 format=3 uid="uid://chwf61qpn2sqw"] + +[ext_resource type="Script" path="res://logic-scenes/board/empty_postIt_panel.gd" id="1_1dtc4"] [node name="Panel" type="Panel"] self_modulate = Color(1, 1, 1, 0) -custom_minimum_size = Vector2(400, 120) +custom_minimum_size = Vector2(400, 100) +offset_right = 400.0 +offset_bottom = 120.0 mouse_filter = 1 +script = ExtResource("1_1dtc4") -[node name="post-it_anchor1" type="Node2D" parent="."] +[node name="post-it_anchor" type="Node2D" parent="."] position = Vector2(105, 57) diff --git a/src/logic-scenes/board/post-it.gd b/src/logic-scenes/board/post-it.gd index d28d648..082df25 100644 --- a/src/logic-scenes/board/post-it.gd +++ b/src/logic-scenes/board/post-it.gd @@ -6,6 +6,8 @@ var sibling var shift_tween var modulate_tween +signal transform_tween_finished + @export var text: String = "" : set (value): if is_inside_tree() or Engine.is_editor_hint(): @@ -120,5 +122,7 @@ func is_postit_attached() -> bool: return self.get_parent().get_parent() is Card func tween_transform_to(target: Vector2): - var transform_tween = create_tween() + var transform_tween: Tween = create_tween() transform_tween.tween_property(self, "position", target, 0.25) + await transform_tween.finished + emit_signal("transform_tween_finished")