#include "pinned_photo.h" #include "core/config/engine.h" #include "core/input/input_event.h" #include "macros.h" #include "scene/2d/mesh_instance_2d.h" #include "scene/gui/rich_text_label.h" #include "you_done_it/clue_db.h" #include "you_done_it/conclusion_field.h" #include "you_done_it/ydi_networking.h" bool PinnedPhoto::a_photo_is_held{}; String const PinnedPhoto::sig_grabbed{ "grabbed" }; String const PinnedPhoto::sig_released{ "released" }; void PinnedPhoto::_bind_methods() { ADD_SIGNAL(MethodInfo(sig_grabbed)); ADD_SIGNAL(MethodInfo(sig_released)); BIND_PROPERTY(Variant::BOOL, can_drop); BIND_HPROPERTY(Variant::INT, clue, PROPERTY_HINT_ENUM, NetworkData::ClueID_hint()); } void PinnedPhoto::enter_tree() { connect("input_event", callable_mp(this, &self_type::on_input_event)); connect("child_entered_tree", callable_mp(this, &self_type::on_child_entered_tree)); if ((this->popup_label = cast_to(get_node(NodePath("%HoverLabel"))))) { set_clue(get_clue()); } } void PinnedPhoto::on_child_entered_tree(Node *node) { if (MeshInstance2D * meshinst{ cast_to(node) }) { this->photo_mesh = meshinst; set_clue(get_clue()); // force reset clue to update image } else if (PanelContainer * container{ cast_to(node) }) { this->popup_container = container; container->set_visible(false); } } void PinnedPhoto::process(double delta) { if (this->is_held) { set_global_position(get_global_mouse_position()); } } void PinnedPhoto::on_input_event(Viewport *viewport, Ref event, int shape) { Ref button{ event }; if (!a_photo_is_held && !this->is_held && button.is_valid() && button->is_pressed()) { a_photo_is_held = this->is_held = true; viewport->set_input_as_handled(); if (this->conclusion_field) { this->conclusion_field->notify_photo_picked(this); this->conclusion_field = nullptr; } set_global_rotation(0); this->popup_container->set_visible(!this->popup_label->get_text().is_empty()); this->get_parent()->move_child(this, this->get_parent()->get_child_count() - 1); emit_signal(sig_grabbed); } } void PinnedPhoto::unhandled_input(Ref const &event) { Ref button{ event }; if (this->is_held && button.is_valid() && button->is_released()) { if (!this->near_fields.is_empty()) { a_photo_is_held = this->is_held = false; this->conclusion_field = this->near_fields[this->near_fields.size() - 1]; this->conclusion_field->notify_photo_dropped(this); get_viewport()->set_input_as_handled(); set_global_position(this->conclusion_field->get_global_position()); set_global_rotation(this->conclusion_field->get_global_rotation()); this->popup_container->set_visible(false); emit_signal(sig_released); } else if (this->can_drop) { a_photo_is_held = this->is_held = false; get_viewport()->set_input_as_handled(); set_global_rotation(0.0); this->popup_container->set_visible(false); emit_signal(sig_released); } } } void PinnedPhoto::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { default: return; case NOTIFICATION_ENTER_TREE: set_process(true); set_pickable(true); set_process_unhandled_input(true); enter_tree(); return; case NOTIFICATION_PROCESS: process(get_process_delta_time()); return; } } void PinnedPhoto::push_conclusion_slot(ConclusionField *field) { this->near_fields.push_back(field); } void PinnedPhoto::pull_conclusion_slot(ConclusionField *field) { this->near_fields.erase(field); } void PinnedPhoto::set_can_drop(bool value) { this->can_drop = value; } bool PinnedPhoto::get_can_drop() const { return this->can_drop; } void PinnedPhoto::set_clue(NetworkData::ClueID id) { this->clue = id; if (this->clue == NetworkData::CLUE_MAX) { return; } if (this->photo_mesh) { Ref texture{ ClueDB::get_singleton()->get_clue(id)->get_image() }; if (texture.is_valid()) { photo_mesh->set_texture(texture); } } if (this->popup_label) { this->popup_label->set_text(ClueDB::get_singleton()->get_clue(id)->get_popup_text()); } } NetworkData::ClueID PinnedPhoto::get_clue() const { return this->clue; }