#include "fiko/girdi/fare_jest.hpp" #include namespace fiko::girdi { namespace { f32 uzaklik(const Vec2f& a, const Vec2f& b) { const f32 dx = a.x - b.x, dy = a.y - b.y; return std::sqrt(dx * dx + dy * dy); } } // namespace FareJestSistemi::DugmeDurum& FareJestSistemi::durum(Dugme d) { return durumlar_[static_cast(d)]; } Dugme FareJestSistemi::diger(Dugme d) const { // Akor esi: aktif akor ciftinin karsi tarafini dondur (yoksa Yok). if (akorAktif1_ != Dugme::Yok && akorAktif2_ != Dugme::Yok) { if (d == akorAktif1_) return akorAktif2_; if (d == akorAktif2_) return akorAktif1_; } return Dugme::Yok; } void FareJestSistemi::guncelle(const FareKare& k) { sonHover_ = k.hover; const f32 dt = k.dt > 0.0f ? k.dt : 0.0f; sonTikGecen_ += dt; // O an basili olan dugmeleri dizele (Sol/Orta/Sag). const bool basiliYeni[3] = {k.sol, k.orta, k.sag}; const Dugme kimlik[3] = {Dugme::Sol, Dugme::Orta, Dugme::Sag}; // ---- 1) Basma kenarlari tespit + akor penceresi baslat ---- for (int i = 0; i < 3; ++i) { DugmeDurum& d = durum(kimlik[i]); if (basiliYeni[i] && !d.basili) { // BAS kenari. d.basili = true; d.basKonum = k.konum; d.basSure = 0.0f; d.suruklendi = false; d.uzunYayildi = false; d.akordaTuketildi = false; d.cokluTus = false; d.basHover = k.hover; // Coklu-tus baglami (akordan bagimsiz — sure penceresi YOK): bu dugme // basildiginda zaten baska dugme basiliysa, kombinasyon kamera jestidir. // Hem yeni basilani hem mevcut basili olan(lar)i isaretle → hicbiri Tik // yaymaz (sag-tik kamerayla birlikte kullanilinca menu acilmasin). for (int o = 0; o < 3; ++o) { if (o == i) continue; if (durum(kimlik[o]).basili) { d.cokluTus = true; durum(kimlik[o]).cokluTus = true; } } // Akor penceresi: onceki basli-bekleyen varsa AKOR olustur. if (akorBekleyen_ != Dugme::Yok && akorBekleyen_ != kimlik[i] && akorBekSure_ <= ayar.akorPencere) { akorAktif1_ = akorBekleyen_; akorAktif2_ = kimlik[i]; akorSure_ = 0.0f; akorUzunYayildi_ = false; durum(akorAktif1_).akordaTuketildi = true; durum(akorAktif2_).akordaTuketildi = true; akorBekleyen_ = Dugme::Yok; } else { akorBekleyen_ = kimlik[i]; akorBekSure_ = 0.0f; } } } if (akorBekleyen_ != Dugme::Yok) akorBekSure_ += dt; if (akorBekSure_ > ayar.akorPencere) akorBekleyen_ = Dugme::Yok; // ---- 2) Basili dugmeler: sure/surukleme/uzun-bas ---- // guiUstunde ise sahne jestlerini bastir (menu/panel etkilesimi) — ama durum // guncellenir ki birakmada temiz reset olsun. for (int i = 0; i < 3; ++i) { DugmeDurum& d = durum(kimlik[i]); if (!d.basili) continue; d.basSure += dt; const f32 kayma = uzaklik(k.konum, d.basKonum); // Akorun parcasiysa tekil surukleme/uzun-bas yayma (akor kolu isler). if (d.akordaTuketildi) continue; if (k.guiUstunde) continue; // Surukleme esigi. if (!d.suruklendi && kayma >= ayar.suruklemeEsik) { d.suruklendi = true; FareJesti j; j.tur = JestTur::SurukleBasla; j.dugme = kimlik[i]; j.ekranNokta = k.konum; j.hedef = d.basHover; j.guiUstunde = false; jestYay(j); } // Uzun-bas (henuz surukleme yok + esik alti kaldi + coklu-tus degil → kamera // kombinasyonu "Hizli 3D"/menu tetiklemesin). if (!d.suruklendi && !d.uzunYayildi && !d.cokluTus && d.basSure >= ayar.uzunBasSure && kayma < ayar.suruklemeEsik) { d.uzunYayildi = true; FareJesti j; j.tur = JestTur::UzunBas; j.dugme = kimlik[i]; j.ekranNokta = k.konum; j.hedef = d.basHover; j.guiUstunde = false; jestYay(j); } } // ---- 3) Aktif akor: sure/uzun-bas ---- if (akorAktif1_ != Dugme::Yok && akorAktif2_ != Dugme::Yok) { const bool ikisiBasili = durum(akorAktif1_).basili && durum(akorAktif2_).basili; if (ikisiBasili) { akorSure_ += dt; if (!akorUzunYayildi_ && akorSure_ >= ayar.uzunBasSure && !k.guiUstunde) { akorUzunYayildi_ = true; FareJesti j; j.tur = JestTur::AkorUzunBas; j.dugme = akorAktif1_; j.akorDugme = akorAktif2_; j.ekranNokta = k.konum; j.hedef = durum(akorAktif1_).basHover; j.guiUstunde = k.guiUstunde; jestYay(j); } } } // ---- 4) Birakma kenarlari ---- for (int i = 0; i < 3; ++i) { DugmeDurum& d = durum(kimlik[i]); if (!basiliYeni[i] && d.basili) { // BIRAK kenari. d.basili = false; const f32 kayma = uzaklik(k.konum, d.basKonum); // Akor birakmasi: iki dugmeden biri kalkinca akoru sonlandir. if (d.akordaTuketildi && (kimlik[i] == akorAktif1_ || kimlik[i] == akorAktif2_)) { if (!akorUzunYayildi_ && akorSure_ < ayar.uzunBasSure && !k.guiUstunde) { FareJesti j; j.tur = JestTur::AkorTik; j.dugme = akorAktif1_; j.akorDugme = akorAktif2_; j.ekranNokta = k.konum; j.hedef = d.basHover; j.guiUstunde = k.guiUstunde; jestYay(j); } // Diger dugme hala basili olsa da akoru kapat (yeni akor icin temiz). durum(akorAktif1_).akordaTuketildi = false; durum(akorAktif2_).akordaTuketildi = false; akorAktif1_ = akorAktif2_ = Dugme::Yok; akorSure_ = 0.0f; akorUzunYayildi_ = false; continue; } if (k.guiUstunde) continue; if (d.suruklendi) { FareJesti j; j.tur = JestTur::SurukleBitti; j.dugme = kimlik[i]; j.ekranNokta = k.konum; j.hedef = d.basHover; jestYay(j); } else if (!d.uzunYayildi && !d.cokluTus && kayma < ayar.suruklemeEsik) { // Tik. Cift-tik penceresi kontrolu. (cokluTus: kamera kombinasyonu → // tekil Tik/menu YOK.) const bool ciftMi = sonTikDugme_ == kimlik[i] && sonTikGecen_ <= ayar.ciftTikSure && uzaklik(k.konum, sonTikKonum_) < ayar.ciftTikEsik; FareJesti j; j.dugme = kimlik[i]; j.ekranNokta = k.konum; j.hedef = d.basHover; if (ciftMi) { j.tur = JestTur::CiftTik; sonTikDugme_ = Dugme::Yok; // uclu tiki cift saymamak icin sifirla sonTikGecen_ = 1e9f; } else { j.tur = JestTur::Tik; sonTikDugme_ = kimlik[i]; sonTikKonum_ = k.konum; sonTikGecen_ = 0.0f; } jestYay(j); } // uzunYayildi ise birakma sessiz (UzunBas zaten yayildi). } } // ---- 5) Tekerlek ---- if (k.tekerlek != 0.0f && !k.guiUstunde) { FareJesti j; j.tur = JestTur::Tekerlek; j.dugme = Dugme::Tekerlek; j.ekranNokta = k.konum; j.tekerlek = k.tekerlek; j.hedef = k.hover; jestYay(j); } } } // namespace fiko::girdi