#include "acilis_splash.hpp" #include #include // FikoUi "Koyu" tema paletiyle uyumlu, bağımsız GDI splash. Çift tamponlu boyama // (titremesiz), katmanlı pencere (alfa fade). Mesaj döngüsü gerekmez — akış // calistir() içinden sürülür; her ilerle() doğrudan boyar. namespace fiko { namespace { constexpr int GEN = 460; constexpr int YUK = 180; constexpr wchar_t SINIF[] = L"FikoAcilisSplash"; // FikoUi Koyu tema token'ları (yakın karşılıklar). const COLORREF ARKA = RGB(16, 18, 24); // panel arka const COLORREF CERCEVE = RGB(38, 44, 58); // ince kenar const COLORREF BASLIK = RGB(233, 238, 245); // ana metin const COLORREF ALTMETIN = RGB(150, 160, 176); // ikincil metin const COLORREF IZ = RGB(30, 34, 44); // progress track const COLORREF NEON1 = RGB(34, 211, 238); // neon camgöbeği (dolgu) const COLORREF NEON2 = RGB(129, 140, 248); // neon mor (gradyan ucu) std::wstring genislet(const std::string& s) { if (s.empty()) return {}; const int n = MultiByteToWideChar(CP_UTF8, 0, s.data(), (int)s.size(), nullptr, 0); std::wstring w(n, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), (int)s.size(), w.data(), n); return w; } } // namespace AcilisSplash::~AcilisSplash() { kapat(); } void AcilisSplash::goster() { static bool sinifKayitli = false; HINSTANCE inst = GetModuleHandleW(nullptr); if (!sinifKayitli) { WNDCLASSW wc{}; wc.lpfnWndProc = DefWindowProcW; wc.hInstance = inst; wc.lpszClassName = SINIF; wc.hCursor = LoadCursor(nullptr, IDC_ARROW); RegisterClassW(&wc); sinifKayitli = true; } const int ekranG = GetSystemMetrics(SM_CXSCREEN); const int ekranY = GetSystemMetrics(SM_CYSCREEN); HWND h = CreateWindowExW(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, SINIF, L"FikoCad", WS_POPUP, (ekranG - GEN) / 2, (ekranY - YUK) / 2, GEN, YUK, nullptr, nullptr, inst, nullptr); if (!h) return; hwnd_ = h; SetLayeredWindowAttributes(h, 0, 255, LWA_ALPHA); ShowWindow(h, SW_SHOWNOACTIVATE); boya(); } void AcilisSplash::mesajBosalt() { MSG msg; while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessageW(&msg); } } void AcilisSplash::ilerle(float oran, const std::string& adim) { if (!hwnd_ || kapali_) return; oran_ = std::clamp(oran, 0.0f, 1.0f); adim_ = adim; boya(); mesajBosalt(); } void AcilisSplash::boya() { if (!hwnd_) return; HWND h = (HWND)hwnd_; HDC ekran = GetDC(h); HDC dc = CreateCompatibleDC(ekran); HBITMAP bmp = CreateCompatibleBitmap(ekran, GEN, YUK); HBITMAP eski = (HBITMAP)SelectObject(dc, bmp); // Arka + ince çerçeve (yuvarlatılmış). RECT tam{0, 0, GEN, YUK}; HBRUSH arkaF = CreateSolidBrush(ARKA); FillRect(dc, &tam, arkaF); DeleteObject(arkaF); HPEN kenarP = CreatePen(PS_SOLID, 1, CERCEVE); HGDIOBJ eskiP = SelectObject(dc, kenarP); HGDIOBJ eskiB = SelectObject(dc, GetStockObject(NULL_BRUSH)); RoundRect(dc, 0, 0, GEN - 1, YUK - 1, 18, 18); SelectObject(dc, eskiB); SelectObject(dc, eskiP); DeleteObject(kenarP); SetBkMode(dc, TRANSPARENT); // Başlık "FikoCad" (neon). HFONT fBaslik = CreateFontW(34, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Segoe UI"); HGDIOBJ eskiF = SelectObject(dc, fBaslik); SetTextColor(dc, NEON1); RECT rB{28, 26, GEN - 28, 70}; DrawTextW(dc, L"FikoCad", -1, &rB, DT_LEFT | DT_SINGLELINE); SelectObject(dc, eskiF); DeleteObject(fBaslik); // Adım metni. HFONT fAlt = CreateFontW(16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Segoe UI"); eskiF = SelectObject(dc, fAlt); SetTextColor(dc, ALTMETIN); const std::wstring adimW = genislet(adim_.empty() ? "Başlatılıyor..." : adim_); RECT rA{28, 78, GEN - 28, 104}; DrawTextW(dc, adimW.c_str(), -1, &rA, DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS); // Yüzde (sağ üst). wchar_t yuzde[8]; wsprintfW(yuzde, L"%d%%", (int)(oran_ * 100.0f + 0.5f)); SetTextColor(dc, ALTMETIN); RECT rY{GEN - 90, 34, GEN - 28, 60}; DrawTextW(dc, yuzde, -1, &rY, DT_RIGHT | DT_SINGLELINE); SelectObject(dc, eskiF); DeleteObject(fAlt); // Progress bar: iz + neon dolgu (soldan sağa gradyan). const int barX = 28, barY = 126, barG = GEN - 56, barH = 10; HBRUSH izF = CreateSolidBrush(IZ); RECT rIz{barX, barY, barX + barG, barY + barH}; FillRect(dc, &rIz, izF); DeleteObject(izF); const int dolu = (int)(barG * oran_ + 0.5f); for (int x = 0; x < dolu; ++x) { // yatay gradyan camgöbeği→mor const float t = (float)x / (float)std::max(barG, 1); const int r = (int)(GetRValue(NEON1) + t * (GetRValue(NEON2) - GetRValue(NEON1))); const int g = (int)(GetGValue(NEON1) + t * (GetGValue(NEON2) - GetGValue(NEON1))); const int b = (int)(GetBValue(NEON1) + t * (GetBValue(NEON2) - GetBValue(NEON1))); HPEN pp = CreatePen(PS_SOLID, 1, RGB(r, g, b)); HGDIOBJ ep = SelectObject(dc, pp); MoveToEx(dc, barX + x, barY, nullptr); LineTo(dc, barX + x, barY + barH); SelectObject(dc, ep); DeleteObject(pp); } BitBlt(ekran, 0, 0, GEN, YUK, dc, 0, 0, SRCCOPY); SelectObject(dc, eski); DeleteObject(bmp); DeleteDC(dc); ReleaseDC(h, ekran); } void AcilisSplash::kapat() { if (!hwnd_ || kapali_) return; kapali_ = true; HWND h = (HWND)hwnd_; // Kısa fade-out (~120 ms) — yalnız kapanışta, açılışı yavaşlatmaz. for (int a = 255; a >= 0; a -= 40) { SetLayeredWindowAttributes(h, 0, (BYTE)std::max(a, 0), LWA_ALPHA); Sleep(16); } DestroyWindow(h); hwnd_ = nullptr; } } // namespace fiko