#pragma once // Akıllı seçim ÖNERİ ÇİPİ (DM ruhu: buton değil bağlam). Tek yüz/kenar seçince viewport // altında "⊘ Bu çaptaki 6 deliği seç" çipi belirir; tıkla → akilliSecimUygula. Menü // açmayı bile bırakır. Öneri seçim tipinden türetilir (akilliSecimOner) — motor + peek // ZATEN hazır, bu yalnız görsel + tıklama köprüsü. #include "fiko/core/temel.hpp" #include "fiko/sahne/sahne.hpp" #include "fiko/ui/simge.hpp" #include "fiko/ui/tema.hpp" #include "akilli_secim.hpp" #include "dogrudan_ayar.hpp" #include "imgui.h" #include namespace fiko { struct AkilliOneriDurum { bool var = false; // bu kare öneri gösterilecek mi AkilliSecim tur{}; int adet = 0; // Seçim imzası: değişmedikçe peek (O(N) brep taraması) tekrarlanmaz. u32 imzaGovde = 0, imzaAlt = 0; size_t imzaSayi = 0; int imzaKip = -1; bool cozuldu = false; // bu imza için öneri hesaplandı mı }; // Her kare çağrılır. Seçim değiştiyse öneriyi (yeniden) hesaplar; çipi çizer; tıklanırsa // akıllı seçimi uygular. Dönüş: çip tıklandı mı (çağıran bilgi mesajı verebilir). // vpMin/vpBoy: viewport sol-üst + boyut (ekran px). guiUstunde: başka panel imleci // kaptıysa çip tıklaması yenmesin. inline bool akilliOneriCipCizVeIsle(AkilliOneriDurum& s, Sahne& sahne, ImDrawList* dl, ImVec2 vpMin, ImVec2 vpBoy) { if (!dogrudanAyar().oneriCipi) { s.var = false; return false; } // ---- Seçim imzası → değiştiyse öneriyi yeniden çöz ---- const size_t say = sahne.secililer().size(); const SecimOge son = say ? sahne.secililer().back() : SecimOge{}; const int kip = (int)sahne.kip(); if (son.govde != s.imzaGovde || son.alt != s.imzaAlt || say != s.imzaSayi || kip != s.imzaKip) { s.imzaGovde = son.govde; s.imzaAlt = son.alt; s.imzaSayi = say; s.imzaKip = kip; s.cozuldu = false; } if (!s.cozuldu) { s.cozuldu = true; s.var = akilliSecimOner(sahne, s.tur, s.adet); } if (!s.var) return false; // ---- Metin: "⊘ Bu çaptaki 6 deliği de seç" ---- const char* etiket = akilliSecimAd(s.tur); // "aynı ölçüdeki yüz" gibi const std::string yazi = "+ " + std::to_string(s.adet) + " " + etiket + " seç"; // ---- Konum: viewport alt-orta, seçim aracı bandının üstünde ---- const ui::Tema& t = ui::tema(); const float pad = 10.0f; const ImVec2 ts = ImGui::CalcTextSize(yazi.c_str()); const float g = ts.x + pad * 2.0f, y = 30.0f; const ImVec2 mrk{vpMin.x + vpBoy.x * 0.5f, vpMin.y + vpBoy.y - 46.0f}; const ImVec2 p0{mrk.x - g * 0.5f, mrk.y - y * 0.5f}; // ---- Gerçek ImGui butonu (görünmez): WantCaptureMouse'u basıştan RELEASE'e kadar // tutar → arkadaki 3B seçim otomatik bastırılır (fk.guiUstunde io.WantCaptureMouse'a // bakıyor). Ham hit-test yapıp pusulaUstunde ile bastırmak YETMEZDİ: basış karesinde // bastırılır ama release bir sonraki karede sızardı (arkadaki nesne seçilirdi). ---- ImGui::SetCursorScreenPos(p0); ImGui::InvisibleButton("##akilliOneriCip", {g, y}); const bool ust = ImGui::IsItemHovered(); const bool tikla = ImGui::IsItemClicked(); const ImVec2 p1{p0.x + g, p0.y + y}; // ---- Çizim: neon çip (hover'da parlar) ---- const ImU32 dolgu = ui::u32(t.vurgu, ust ? 0.30f : 0.16f); const ImU32 cerceve = ui::u32(t.vurgu, ust ? 1.0f : 0.65f); dl->AddRectFilled(p0, p1, dolgu, y * 0.5f); dl->AddRect(p0, p1, cerceve, y * 0.5f, 0, ust ? 2.0f : 1.2f); dl->AddText({p0.x + pad, p0.y + (y - ts.y) * 0.5f}, ui::u32(t.metin), yazi.c_str()); if (tikla) { akilliSecimUygula(sahne, s.tur); s.cozuldu = false; // seçim büyüdü → öneri yeniden çözülsün (belki başka öneri kalmaz) return true; } return false; } } // namespace fiko