feat: Full UI internationalization, pool hashrate stats, and layout caching
- Replace all hardcoded English strings with TR() translation keys across every tab, dialog, and component (~20 UI files) - Expand all 8 language files (de, es, fr, ja, ko, pt, ru, zh) with complete translations (~37k lines added) - Improve i18n loader with exe-relative path fallback and English base fallback for missing keys - Add pool-side hashrate polling via pool stats API in xmrig_manager - Introduce Layout::beginFrame() per-frame caching and refresh balance layout config only on schema generation change - Offload daemon output parsing to worker thread - Add CJK subset fallback font for Chinese/Japanese/Korean glyphs
This commit is contained in:
@@ -351,18 +351,24 @@ inline void DrawGlassPanel(ImDrawList* dl, const ImVec2& pMin,
|
||||
|
||||
// Noise grain overlay — drawn OVER the surface overlay so card
|
||||
// opacity doesn't hide it. Gives cards a tactile paper feel.
|
||||
// Noise tint is cached per-generation, opacity checked each panel.
|
||||
{
|
||||
float noiseMul = dragonx::ui::effects::ImGuiAcrylic::GetNoiseOpacity();
|
||||
if (noiseMul > 0.0f) {
|
||||
uint8_t origAlpha = (s_glassNoiseTint >> IM_COL32_A_SHIFT) & 0xFF;
|
||||
uint8_t scaledAlpha = static_cast<uint8_t>(std::min(255.0f, origAlpha * noiseMul));
|
||||
// Tint base color changes only on theme reload; opacity slider may change per-frame
|
||||
static uint32_t s_noiseGen = 0;
|
||||
static uint8_t s_baseAlpha = 0;
|
||||
if (curGen != s_noiseGen) {
|
||||
s_noiseGen = curGen;
|
||||
s_baseAlpha = (s_glassNoiseTint >> IM_COL32_A_SHIFT) & 0xFF;
|
||||
}
|
||||
uint8_t scaledAlpha = static_cast<uint8_t>(std::min(255.0f, s_baseAlpha * noiseMul));
|
||||
ImU32 noiseTint = (s_glassNoiseTint & ~(0xFFu << IM_COL32_A_SHIFT)) | (scaledAlpha << IM_COL32_A_SHIFT);
|
||||
float inset = spec.rounding * 0.3f;
|
||||
ImVec2 clipMin(pMin.x + inset, pMin.y + inset);
|
||||
ImVec2 clipMax(pMax.x - inset, pMax.y - inset);
|
||||
dl->PushClipRect(clipMin, clipMax, true);
|
||||
dragonx::util::DrawTiledNoiseRect(dl, clipMin, clipMax, noiseTint);
|
||||
dl->PopClipRect();
|
||||
ImVec2 noiseMin(pMin.x + inset, pMin.y + inset);
|
||||
ImVec2 noiseMax(pMax.x - inset, pMax.y - inset);
|
||||
// Image rect matches clip bounds exactly — no PushClipRect needed
|
||||
dragonx::util::DrawTiledNoiseRect(dl, noiseMin, noiseMax, noiseTint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,18 +381,20 @@ inline void DrawGlassPanel(ImDrawList* dl, const ImVec2& pMin,
|
||||
// Theme visual effects drawn on ForegroundDrawList so they
|
||||
// render above card content (text, values, etc.), not below.
|
||||
auto& fx = effects::ThemeEffects::instance();
|
||||
ImDrawList* fxDl = ImGui::GetForegroundDrawList();
|
||||
if (fx.hasRainbowBorder()) {
|
||||
fx.drawRainbowBorder(fxDl, pMin, pMax, spec.rounding, spec.borderWidth);
|
||||
if (fx.hasAnyPanelEffect()) {
|
||||
ImDrawList* fxDl = ImGui::GetForegroundDrawList();
|
||||
if (fx.hasRainbowBorder()) {
|
||||
fx.drawRainbowBorder(fxDl, pMin, pMax, spec.rounding, spec.borderWidth);
|
||||
}
|
||||
if (fx.hasShimmer()) {
|
||||
fx.drawShimmer(fxDl, pMin, pMax, spec.rounding);
|
||||
}
|
||||
if (fx.hasSpecularGlare()) {
|
||||
fx.drawSpecularGlare(fxDl, pMin, pMax, spec.rounding);
|
||||
}
|
||||
// Per-panel theme effects: edge trace + ember rise
|
||||
fx.drawPanelEffects(fxDl, pMin, pMax, spec.rounding);
|
||||
}
|
||||
if (fx.hasShimmer()) {
|
||||
fx.drawShimmer(fxDl, pMin, pMax, spec.rounding);
|
||||
}
|
||||
if (fx.hasSpecularGlare()) {
|
||||
fx.drawSpecularGlare(fxDl, pMin, pMax, spec.rounding);
|
||||
}
|
||||
// Per-panel theme effects: edge trace + ember rise
|
||||
fx.drawPanelEffects(fxDl, pMin, pMax, spec.rounding);
|
||||
} else {
|
||||
// Low-spec opaque fallback
|
||||
dl->AddRectFilled(pMin, pMax,
|
||||
@@ -749,8 +757,10 @@ inline void ApplySmoothScroll(float speed = 12.0f)
|
||||
s.current = actualY;
|
||||
}
|
||||
|
||||
// Capture mouse wheel when hovered
|
||||
if (ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) {
|
||||
// Capture mouse wheel when hovered, but not when a popup (combo dropdown
|
||||
// etc.) is open — let the popup handle its own scrolling exclusively.
|
||||
bool popupOpen = ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel);
|
||||
if (!popupOpen && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) {
|
||||
float wheel = ImGui::GetIO().MouseWheel;
|
||||
if (wheel != 0.0f) {
|
||||
float step = ImGui::GetTextLineHeightWithSpacing() * 3.0f;
|
||||
|
||||
Reference in New Issue
Block a user