YouDunIt/modules/you_done_it/pinned_photo.cpp

138 lines
4.1 KiB
C++

#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<RichTextLabel>(get_node(NodePath("%HoverLabel"))))) {
set_clue(get_clue());
}
}
void PinnedPhoto::on_child_entered_tree(Node *node) {
if (MeshInstance2D * meshinst{ cast_to<MeshInstance2D>(node) }) {
this->photo_mesh = meshinst;
set_clue(get_clue()); // force reset clue to update image
} else if (PanelContainer * container{ cast_to<PanelContainer>(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<InputEvent> event, int shape) {
Ref<InputEventMouseButton> 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<InputEvent> const &event) {
Ref<InputEventMouseButton> 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<Texture2D> 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;
}