refactor(audit): batch 3 — decompose App::update() + collapse acrylic fork
Three P1 structural refactors from the audit; no behavior change. 1. Extract the ~180-line daemon-stdout rescan/witness parser out of the ~790-line App::update() into a pure, static, unit-testable NetworkRefreshService::parseDaemonRescanOutput() returning a DaemonRescanScan result struct (sits next to the existing static parse* siblings). The scanning half moved verbatim; App::update() keeps the state-application half, now reading scan.* fields. Adds testParseDaemonRescanOutput() covering all six daemon signals + edge cases against fixture log snippets — previously untestable without a live daemon. 2. Extract the ~95-line global keyboard-shortcut block (Ctrl+, / theme cycle / F5 / low-spec / effects / gradient / wizard) out of App::update() into App::handleGlobalShortcuts(). 3. Collapse the ImGuiAcrylic frontend fork: the GLAD and DX11 namespaces were ~375 lines of semantically-identical code (the frontend makes zero direct GL/DX calls — all backend work delegates to AcrylicMaterial, which has a backend per API). Extended the single frontend's guard to #if defined(DRAGONX_HAS_GLAD) || defined(DRAGONX_USE_DX11) and deleted the DX11 duplicate, leaving the no-backend stub. Kills the Windows/DX11 drift hazard (acrylic frontend changes now made once). Verified: full-node + Lite build clean; ctest 1/1 (incl. the new parser tests); source-hygiene clean; and the collapsed acrylic path was compile-verified under DX11 via the mingw-w64 Windows cross-build (ObsidianDragon.exe links). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -107,7 +107,10 @@ int MatchPreset(AcrylicQuality q, float blur)
|
||||
|
||||
} } } } // namespace dragonx::ui::effects::ImGuiAcrylic
|
||||
|
||||
#ifdef DRAGONX_HAS_GLAD
|
||||
// Single ImGuiAcrylic frontend for BOTH GL (GLAD) and DX11: the frontend makes no
|
||||
// direct GL/DX calls — every backend op is delegated to AcrylicMaterial, which has a
|
||||
// backend for each API — so it must not fork per-backend.
|
||||
#if defined(DRAGONX_HAS_GLAD) || defined(DRAGONX_USE_DX11)
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
@@ -638,408 +641,6 @@ void ApplyBlurAmount(float blur)
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
|
||||
#endif // DRAGONX_HAS_GLAD
|
||||
|
||||
// ============================================================================
|
||||
// Stub Implementations (No GLAD)
|
||||
// ============================================================================
|
||||
|
||||
#ifndef DRAGONX_HAS_GLAD
|
||||
|
||||
#ifdef DRAGONX_USE_DX11
|
||||
|
||||
// ============================================================================
|
||||
// DX11 Implementation — mirrors the GLAD version above, delegating to
|
||||
// AcrylicMaterial which now has a full DX11 backend.
|
||||
// ============================================================================
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
namespace effects {
|
||||
|
||||
namespace ImGuiAcrylic {
|
||||
|
||||
static bool s_initialized = false;
|
||||
static int s_viewportWidth = 0;
|
||||
static int s_viewportHeight = 0;
|
||||
static bool s_backgroundCaptured = false;
|
||||
|
||||
struct AcrylicWindowState {
|
||||
ImVec2 windowPos;
|
||||
ImVec2 windowSize;
|
||||
AcrylicParams params;
|
||||
bool active;
|
||||
};
|
||||
static AcrylicWindowState s_currentWindow = {};
|
||||
|
||||
bool Init()
|
||||
{
|
||||
if (s_initialized) return true;
|
||||
|
||||
AcrylicMaterial& acrylic = getAcrylicMaterial();
|
||||
if (!acrylic.init()) {
|
||||
DEBUG_LOGF("ImGuiAcrylic DX11: Failed to initialize acrylic material\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_initialized = true;
|
||||
DEBUG_LOGF("ImGuiAcrylic DX11: Initialized successfully\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
if (!s_initialized) return;
|
||||
getAcrylicMaterial().shutdown();
|
||||
s_initialized = false;
|
||||
}
|
||||
|
||||
bool IsAvailable()
|
||||
{
|
||||
return s_initialized && getAcrylicMaterial().isInitialized();
|
||||
}
|
||||
|
||||
void BeginFrame(int width, int height)
|
||||
{
|
||||
if (!s_initialized) return;
|
||||
|
||||
if (width != s_viewportWidth || height != s_viewportHeight) {
|
||||
s_viewportWidth = width;
|
||||
s_viewportHeight = height;
|
||||
getAcrylicMaterial().resize(width, height);
|
||||
}
|
||||
|
||||
// Capture the first few frames to ensure a clean initial blur,
|
||||
// then stop. Resize / theme change already sets dirtyFrames_ via markBackgroundDirty().
|
||||
static int s_warmupFrames = 3;
|
||||
if (s_warmupFrames > 0) {
|
||||
getAcrylicMaterial().markBackgroundDirty();
|
||||
--s_warmupFrames;
|
||||
}
|
||||
|
||||
s_backgroundCaptured = false;
|
||||
}
|
||||
|
||||
void CaptureBackground()
|
||||
{
|
||||
if (!s_initialized || s_backgroundCaptured) return;
|
||||
getAcrylicMaterial().captureBackground();
|
||||
s_backgroundCaptured = true;
|
||||
}
|
||||
|
||||
void InvalidateCapture()
|
||||
{
|
||||
if (!s_initialized) return;
|
||||
getAcrylicMaterial().markBackgroundDirty();
|
||||
}
|
||||
|
||||
static void BackgroundCaptureCallback(const ImDrawList*, const ImDrawCmd*)
|
||||
{
|
||||
if (!s_initialized) return;
|
||||
getAcrylicMaterial().captureBackgroundDirect();
|
||||
s_backgroundCaptured = true;
|
||||
}
|
||||
|
||||
ImDrawCallback GetBackgroundCaptureCallback()
|
||||
{
|
||||
return BackgroundCaptureCallback;
|
||||
}
|
||||
|
||||
void DrawAcrylicRect(ImDrawList* drawList,
|
||||
const ImVec2& pMin, const ImVec2& pMax,
|
||||
const AcrylicParams& params,
|
||||
float rounding)
|
||||
{
|
||||
if (!drawList) return;
|
||||
|
||||
if (!IsAvailable() || !IsEnabled() || !params.enabled) {
|
||||
drawList->AddRectFilled(pMin, pMax,
|
||||
ImGui::ColorConvertFloat4ToU32(params.fallbackColor), rounding);
|
||||
return;
|
||||
}
|
||||
|
||||
getAcrylicMaterial().drawRect(drawList, pMin, pMax, params, rounding);
|
||||
}
|
||||
|
||||
void DrawAcrylicRect(ImDrawList* drawList,
|
||||
const ImVec2& pMin, const ImVec2& pMax,
|
||||
float rounding)
|
||||
{
|
||||
DrawAcrylicRect(drawList, pMin, pMax, AcrylicMaterial::getDarkPreset(), rounding);
|
||||
}
|
||||
|
||||
bool BeginAcrylicWindow(const char* name, bool* p_open,
|
||||
ImGuiWindowFlags flags,
|
||||
const AcrylicParams& params)
|
||||
{
|
||||
s_currentWindow.params = params;
|
||||
s_currentWindow.active = true;
|
||||
|
||||
if (!(flags & ImGuiWindowFlags_NoBringToFrontOnFocus))
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
|
||||
|
||||
bool result = ImGui::Begin(name, p_open, flags);
|
||||
|
||||
if (result) {
|
||||
s_currentWindow.windowPos = ImGui::GetWindowPos();
|
||||
s_currentWindow.windowSize = ImGui::GetWindowSize();
|
||||
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
ImVec2 pMin = s_currentWindow.windowPos;
|
||||
ImVec2 pMax = ImVec2(pMin.x + s_currentWindow.windowSize.x,
|
||||
pMin.y + s_currentWindow.windowSize.y);
|
||||
|
||||
float rounding = ImGui::GetStyle().WindowRounding;
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, rounding);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void EndAcrylicWindow()
|
||||
{
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor();
|
||||
s_currentWindow.active = false;
|
||||
}
|
||||
|
||||
bool BeginAcrylicChild(const char* str_id,
|
||||
const ImVec2& size,
|
||||
const AcrylicParams& params,
|
||||
ImGuiChildFlags child_flags,
|
||||
ImGuiWindowFlags window_flags)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
|
||||
bool result = ImGui::BeginChild(str_id, size, child_flags, window_flags);
|
||||
if (result) {
|
||||
ImVec2 childPos = ImGui::GetWindowPos();
|
||||
ImVec2 childSize = ImGui::GetWindowSize();
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
ImVec2 pMin = childPos;
|
||||
ImVec2 pMax = ImVec2(pMin.x + childSize.x, pMin.y + childSize.y);
|
||||
float rounding = ImGui::GetStyle().ChildRounding;
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, rounding);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void EndAcrylicChild()
|
||||
{
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
bool BeginAcrylicPopup(const char* str_id,
|
||||
ImGuiWindowFlags flags,
|
||||
const AcrylicParams& params)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0, 0, 0, 0));
|
||||
bool result = ImGui::BeginPopup(str_id, flags);
|
||||
if (result) {
|
||||
ImVec2 popupPos = ImGui::GetWindowPos();
|
||||
ImVec2 popupSize = ImGui::GetWindowSize();
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
ImVec2 pMin = popupPos;
|
||||
ImVec2 pMax = ImVec2(pMin.x + popupSize.x, pMin.y + popupSize.y);
|
||||
float rounding = ImGui::GetStyle().PopupRounding;
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, rounding);
|
||||
} else {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void EndAcrylicPopup()
|
||||
{
|
||||
ImGui::EndPopup();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
bool BeginAcrylicPopupModal(const char* name, bool* p_open,
|
||||
ImGuiWindowFlags flags,
|
||||
const AcrylicParams& params)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_ModalWindowDimBg, ImVec4(0, 0, 0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0, 0, 0, 0));
|
||||
bool result = ImGui::BeginPopupModal(name, p_open, flags);
|
||||
ImGui::PopStyleColor(); // ModalWindowDimBg
|
||||
|
||||
if (result) {
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
DrawFrostedScrim(drawList);
|
||||
ImVec2 popupPos = ImGui::GetWindowPos();
|
||||
ImVec2 popupSize = ImGui::GetWindowSize();
|
||||
ImVec2 pMin = popupPos;
|
||||
ImVec2 pMax = ImVec2(pMin.x + popupSize.x, pMin.y + popupSize.y);
|
||||
float rounding = ImGui::GetStyle().PopupRounding;
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, rounding);
|
||||
} else {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BeginAcrylicContextItem(const char* str_id,
|
||||
ImGuiPopupFlags popup_flags,
|
||||
const AcrylicParams& params)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0, 0, 0, 0));
|
||||
bool result = ImGui::BeginPopupContextItem(str_id, popup_flags);
|
||||
if (result) {
|
||||
ImVec2 popupPos = ImGui::GetWindowPos();
|
||||
ImVec2 popupSize = ImGui::GetWindowSize();
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
ImVec2 pMin = popupPos;
|
||||
ImVec2 pMax = ImVec2(pMin.x + popupSize.x, pMin.y + popupSize.y);
|
||||
float rounding = ImGui::GetStyle().PopupRounding;
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, rounding);
|
||||
} else {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BeginAcrylicContextWindow(const char* str_id,
|
||||
ImGuiPopupFlags popup_flags,
|
||||
const AcrylicParams& params)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0, 0, 0, 0));
|
||||
bool result = ImGui::BeginPopupContextWindow(str_id, popup_flags);
|
||||
if (result) {
|
||||
ImVec2 popupPos = ImGui::GetWindowPos();
|
||||
ImVec2 popupSize = ImGui::GetWindowSize();
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
ImVec2 pMin = popupPos;
|
||||
ImVec2 pMax = ImVec2(pMin.x + popupSize.x, pMin.y + popupSize.y);
|
||||
float rounding = ImGui::GetStyle().PopupRounding;
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, rounding);
|
||||
} else {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DrawSidebarBackground(float width, const AcrylicParams& params)
|
||||
{
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
float menuBarHeight = ImGui::GetFrameHeight();
|
||||
ImVec2 pMin = ImVec2(viewport->WorkPos.x, viewport->WorkPos.y + menuBarHeight);
|
||||
ImVec2 pMax = ImVec2(pMin.x + width, viewport->WorkPos.y + viewport->WorkSize.y);
|
||||
ImDrawList* drawList = ImGui::GetBackgroundDrawList();
|
||||
DrawAcrylicRect(drawList, pMin, pMax, params, 0.0f);
|
||||
}
|
||||
|
||||
void SetQuality(AcrylicQuality quality)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setQuality(quality);
|
||||
}
|
||||
|
||||
AcrylicQuality GetQuality()
|
||||
{
|
||||
if (s_initialized) return getAcrylicMaterial().getQuality();
|
||||
return AcrylicQuality::Off;
|
||||
}
|
||||
|
||||
void SetEnabled(bool enabled)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setEnabled(enabled);
|
||||
}
|
||||
|
||||
bool IsEnabled()
|
||||
{
|
||||
if (s_initialized) return getAcrylicMaterial().isEnabled();
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetBlurMultiplier(float multiplier)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setBlurMultiplier(multiplier);
|
||||
}
|
||||
|
||||
float GetBlurMultiplier()
|
||||
{
|
||||
if (s_initialized) return getAcrylicMaterial().getBlurMultiplier();
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void SetReducedTransparency(bool reduced)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setReducedTransparency(reduced);
|
||||
}
|
||||
|
||||
bool GetReducedTransparency()
|
||||
{
|
||||
if (s_initialized) return getAcrylicMaterial().getReducedTransparency();
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetUIOpacity(float opacity)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setUIOpacity(opacity);
|
||||
}
|
||||
|
||||
float GetUIOpacity()
|
||||
{
|
||||
if (s_initialized) return getAcrylicMaterial().getUIOpacity();
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void SetNoiseOpacity(float multiplier)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setNoiseOpacityMultiplier(multiplier);
|
||||
}
|
||||
|
||||
float GetNoiseOpacity()
|
||||
{
|
||||
if (s_initialized) return getAcrylicMaterial().getNoiseOpacityMultiplier();
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const AcrylicSettings& GetSettings()
|
||||
{
|
||||
return getAcrylicMaterial().getSettings();
|
||||
}
|
||||
|
||||
void SetSettings(const AcrylicSettings& settings)
|
||||
{
|
||||
if (s_initialized) getAcrylicMaterial().setSettings(settings);
|
||||
}
|
||||
|
||||
void SetPreset(int preset)
|
||||
{
|
||||
if (preset < 0 || preset >= kPresetCount) preset = 3;
|
||||
SetEnabled(preset != 0);
|
||||
SetQuality(PresetQuality(preset));
|
||||
SetBlurMultiplier(PresetBlur(preset));
|
||||
}
|
||||
|
||||
int GetPreset()
|
||||
{
|
||||
return MatchPreset(GetQuality(), GetBlurMultiplier());
|
||||
}
|
||||
|
||||
void ApplyBlurAmount(float blur)
|
||||
{
|
||||
if (blur < 0.001f) {
|
||||
SetEnabled(false);
|
||||
SetQuality(AcrylicQuality::Off);
|
||||
SetBlurMultiplier(0.0f);
|
||||
} else {
|
||||
SetEnabled(true);
|
||||
SetQuality(AcrylicQuality::Low);
|
||||
SetBlurMultiplier(blur);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ImGuiAcrylic
|
||||
|
||||
} // namespace effects
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
|
||||
#else // neither GLAD nor DX11
|
||||
|
||||
namespace dragonx {
|
||||
@@ -1173,6 +774,5 @@ void ApplyBlurAmount(float) {}
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
|
||||
#endif // DRAGONX_USE_DX11
|
||||
|
||||
#endif // !DRAGONX_HAS_GLAD
|
||||
#endif // DRAGONX_HAS_GLAD || DRAGONX_USE_DX11
|
||||
|
||||
Reference in New Issue
Block a user