feat: blockchain rescan via daemon restart + status bar progress
- Fix z_importwallet to use full path instead of filename only - Add rescanBlockchain() method that restarts daemon with -rescan flag - Track rescan progress via daemon output parsing and getrescaninfo RPC - Display rescan progress in status bar with animated indicator when starting - Improve dark theme card contrast: lighter surface-variant, tinted borders, stronger rim-light
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../theme.h"
|
||||
#include "../../util/noise_texture.h"
|
||||
#include "../../embedded/IconsMaterialDesign.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include <algorithm>
|
||||
@@ -774,6 +775,171 @@ inline void ApplySmoothScroll(float speed = 12.0f)
|
||||
ImGui::SetScrollY(s.current);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Dialog Title Bar with Close Button
|
||||
// ============================================================================
|
||||
// Draws a custom title bar for modal popups with a title and close button.
|
||||
// Returns true if the close button was clicked.
|
||||
|
||||
inline bool DrawDialogTitleBar(const char* title, bool* p_open, ImU32 accent_col = 0)
|
||||
{
|
||||
bool closeClicked = false;
|
||||
ImDrawList* dl = ImGui::GetWindowDrawList();
|
||||
ImVec2 winPos = ImGui::GetWindowPos();
|
||||
float winWidth = ImGui::GetWindowWidth();
|
||||
float barHeight = 36.0f;
|
||||
|
||||
// Get accent color from theme if not provided
|
||||
if (!accent_col) {
|
||||
accent_col = schema::UI().resolveColor("var(--primary)", IM_COL32(76, 175, 80, 255));
|
||||
}
|
||||
|
||||
// Draw title bar background with subtle gradient
|
||||
ImVec2 barMin = winPos;
|
||||
ImVec2 barMax(winPos.x + winWidth, winPos.y + barHeight);
|
||||
|
||||
// Slightly darker top edge
|
||||
ImU32 barTop = IM_COL32(0, 0, 0, 40);
|
||||
ImU32 barBot = IM_COL32(0, 0, 0, 20);
|
||||
dl->AddRectFilledMultiColor(barMin, barMax, barTop, barTop, barBot, barBot);
|
||||
|
||||
// Accent line at bottom of title bar
|
||||
dl->AddLine(ImVec2(barMin.x, barMax.y), ImVec2(barMax.x, barMax.y),
|
||||
ScaleAlpha(accent_col, 0.6f), 1.0f);
|
||||
|
||||
// Title text
|
||||
ImFont* titleFont = Type().subtitle1();
|
||||
ImGui::PushFont(titleFont);
|
||||
ImVec2 titleSize = ImGui::CalcTextSize(title);
|
||||
float titleX = barMin.x + 16.0f;
|
||||
float titleY = barMin.y + (barHeight - titleSize.y) * 0.5f;
|
||||
DrawTextShadow(dl, ImVec2(titleX, titleY), OnSurface(), title);
|
||||
ImGui::PopFont();
|
||||
|
||||
// Close button (X) on right side
|
||||
if (p_open) {
|
||||
float btnSize = 24.0f;
|
||||
float btnX = barMax.x - btnSize - 12.0f;
|
||||
float btnY = barMin.y + (barHeight - btnSize) * 0.5f;
|
||||
ImVec2 btnMin(btnX, btnY);
|
||||
ImVec2 btnMax(btnX + btnSize, btnY + btnSize);
|
||||
|
||||
bool hovered = ImGui::IsMouseHoveringRect(btnMin, btnMax);
|
||||
bool held = false;
|
||||
if (hovered && ImGui::IsMouseClicked(0)) {
|
||||
held = true;
|
||||
}
|
||||
|
||||
// Button background on hover
|
||||
if (hovered) {
|
||||
dl->AddRectFilled(btnMin, btnMax, IM_COL32(255, 255, 255, held ? 40 : 25), 4.0f);
|
||||
}
|
||||
|
||||
// Draw X icon
|
||||
ImGui::PushFont(Type().iconSmall());
|
||||
ImVec2 iconSize = ImGui::CalcTextSize(ICON_MD_CLOSE);
|
||||
float iconX = btnX + (btnSize - iconSize.x) * 0.5f;
|
||||
float iconY = btnY + (btnSize - iconSize.y) * 0.5f;
|
||||
dl->AddText(ImVec2(iconX, iconY),
|
||||
hovered ? IM_COL32(255, 255, 255, 255) : OnSurfaceMedium(),
|
||||
ICON_MD_CLOSE);
|
||||
ImGui::PopFont();
|
||||
|
||||
// Handle click
|
||||
if (hovered && ImGui::IsMouseReleased(0)) {
|
||||
*p_open = false;
|
||||
closeClicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve space for title bar so content starts below it
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + barHeight + 8.0f);
|
||||
|
||||
return closeClicked;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Fullscreen Overlay Dialog
|
||||
// ============================================================================
|
||||
// Creates a fullscreen semi-transparent overlay with a centered card dialog.
|
||||
// Similar to the shutdown screen pattern but for interactive dialogs.
|
||||
|
||||
inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth = 460.0f, float scrimOpacity = 0.92f)
|
||||
{
|
||||
ImGuiViewport* vp = ImGui::GetMainViewport();
|
||||
ImVec2 vp_pos = vp->Pos;
|
||||
ImVec2 vp_size = vp->Size;
|
||||
|
||||
// Fullscreen scrim overlay
|
||||
ImGui::SetNextWindowPos(vp_pos);
|
||||
ImGui::SetNextWindowSize(vp_size);
|
||||
ImGui::SetNextWindowFocus();
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.04f, 0.04f, 0.06f, scrimOpacity));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
|
||||
bool opened = ImGui::Begin("##OverlayScrim", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_NoSavedSettings);
|
||||
|
||||
if (!opened) {
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor();
|
||||
return false;
|
||||
}
|
||||
|
||||
ImDrawList* dl = ImGui::GetWindowDrawList();
|
||||
|
||||
// Calculate card position (centered)
|
||||
float cardX = vp_pos.x + (vp_size.x - cardWidth) * 0.5f;
|
||||
float cardY = vp_pos.y + vp_size.y * 0.15f;
|
||||
|
||||
// Draw glass card background
|
||||
ImVec2 cardMin(cardX, cardY);
|
||||
ImVec2 cardMax(cardX + cardWidth, vp_pos.y + vp_size.y * 0.85f);
|
||||
|
||||
// Card background with glass effect
|
||||
GlassPanelSpec cardGlass;
|
||||
cardGlass.rounding = 16.0f;
|
||||
cardGlass.fillAlpha = 35;
|
||||
cardGlass.borderAlpha = 50;
|
||||
cardGlass.borderWidth = 1.0f;
|
||||
DrawGlassPanel(dl, cardMin, cardMax, cardGlass);
|
||||
|
||||
// Set up child region for card content
|
||||
ImGui::SetCursorScreenPos(ImVec2(cardX, cardY));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 16.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(28, 24));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0)); // Transparent - glass already drawn
|
||||
|
||||
bool childVisible = ImGui::BeginChild("##OverlayDialogContent",
|
||||
ImVec2(cardWidth, 0), // 0 height = auto-size
|
||||
ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysUseWindowPadding,
|
||||
ImGuiWindowFlags_NoScrollbar);
|
||||
|
||||
// Draw title bar with close button
|
||||
if (childVisible && title) {
|
||||
DrawDialogTitleBar(title, p_open);
|
||||
}
|
||||
|
||||
return childVisible;
|
||||
}
|
||||
|
||||
inline void EndOverlayDialog()
|
||||
{
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor(); // ChildBg
|
||||
ImGui::PopStyleVar(2); // ChildRounding, WindowPadding (for child)
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar(3); // WindowRounding, WindowBorderSize, WindowPadding (for scrim)
|
||||
ImGui::PopStyleColor(); // WindowBg scrim
|
||||
}
|
||||
|
||||
} // namespace material
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
|
||||
@@ -108,6 +108,7 @@ static bool sp_stop_external_daemon = false;
|
||||
static std::set<std::string> sp_debug_categories;
|
||||
static bool sp_debug_cats_dirty = false; // true when changed but daemon not yet restarted
|
||||
static bool sp_debug_expanded = false; // collapsible card state
|
||||
static bool sp_confirm_clear_ztx = false; // confirmation dialog for clearing z-tx history
|
||||
|
||||
// (APPEARANCE card now uses ChannelsSplit like all other cards)
|
||||
|
||||
@@ -969,46 +970,41 @@ void RenderSettingsPage(App* app) {
|
||||
ImGui::Indent(pad);
|
||||
|
||||
float contentW = availWidth - pad * 2;
|
||||
bool wideBtns = availWidth >= S.drawElement("components.settings-page", "compact-breakpoint").size;
|
||||
|
||||
// Content-aware button sizing: uniform per-row width based on widest label
|
||||
float minBtnW = S.drawElement("components.settings-page", "wallet-btn-min-width").sizeOr(130.0f);
|
||||
float btnSpacing = Layout::spacingMd();
|
||||
float btnPad = S.drawElement("components.settings-page", "wallet-btn-padding").sizeOr(24.0f);
|
||||
auto rowBtnW = [&](std::initializer_list<const char*> labels) -> float {
|
||||
float maxTextW = 0;
|
||||
for (auto* l : labels) maxTextW = std::max(maxTextW, ImGui::CalcTextSize(l).x);
|
||||
return std::max(minBtnW, maxTextW + btnPad * 2);
|
||||
};
|
||||
|
||||
// Calculate button width that fits available space
|
||||
// 6 buttons total: on wide screens 3+3, on narrow screens 2+2+2
|
||||
int btnsPerRow = (contentW >= 600.0f) ? 3 : 2;
|
||||
float bw = (contentW - btnSpacing * (btnsPerRow - 1)) / btnsPerRow;
|
||||
// Clamp to reasonable size
|
||||
float minBtnW = S.drawElement("components.settings-page", "wallet-btn-min-width").sizeOr(100.0f);
|
||||
bw = std::max(minBtnW, bw);
|
||||
|
||||
// Row 1 — Tools & Actions
|
||||
{
|
||||
float bw = rowBtnW({"Address Book...", "Validate Address...", "Request Payment...", "Shield Mining...", "Merge to Address...", "Clear Z-Tx History"});
|
||||
if (TactileButton("Address Book...", ImVec2(bw, 0), S.resolveFont("button")))
|
||||
AddressBookDialog::show();
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Manage saved addresses for quick sending");
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
ImGui::SameLine(0, btnSpacing);
|
||||
if (TactileButton("Validate Address...", ImVec2(bw, 0), S.resolveFont("button")))
|
||||
ValidateAddressDialog::show();
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Check if a DragonX address is valid");
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
if (btnsPerRow >= 3) { ImGui::SameLine(0, btnSpacing); } else { ImGui::Dummy(ImVec2(0, Layout::spacingXs())); }
|
||||
if (TactileButton("Request Payment...", ImVec2(bw, 0), S.resolveFont("button")))
|
||||
RequestPaymentDialog::show();
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Generate a payment request with QR code");
|
||||
if (wideBtns) ImGui::SameLine(0, Layout::spacingMd()); else ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
if (btnsPerRow >= 3) { ImGui::Dummy(ImVec2(0, Layout::spacingXs())); } else { ImGui::SameLine(0, btnSpacing); }
|
||||
if (TactileButton("Shield Mining...", ImVec2(bw, 0), S.resolveFont("button")))
|
||||
ShieldDialog::show(ShieldDialog::Mode::ShieldCoinbase);
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Move transparent mining rewards to a shielded address");
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
ImGui::SameLine(0, btnSpacing);
|
||||
if (TactileButton("Merge to Address...", ImVec2(bw, 0), S.resolveFont("button")))
|
||||
ShieldDialog::show(ShieldDialog::Mode::MergeToAddress);
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Consolidate multiple UTXOs into one address");
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
if (btnsPerRow >= 3) { ImGui::SameLine(0, btnSpacing); } else { ImGui::Dummy(ImVec2(0, Layout::spacingXs())); }
|
||||
if (TactileButton("Clear Z-Tx History", ImVec2(bw, 0), S.resolveFont("button"))) {
|
||||
std::string ztx_file = util::Platform::getDragonXDataDir() + "ztx_history.json";
|
||||
if (util::Platform::deleteFile(ztx_file))
|
||||
Notifications::instance().success("Z-transaction history cleared");
|
||||
else
|
||||
Notifications::instance().info("No history file found");
|
||||
sp_confirm_clear_ztx = true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Delete locally cached z-transaction history");
|
||||
}
|
||||
@@ -1348,24 +1344,7 @@ void RenderSettingsPage(App* app) {
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("Verify the RPC connection to the daemon");
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
if (TactileButton("Rescan Blockchain", ImVec2(nodeBtnW, 0), btnFont)) {
|
||||
if (app->rpc() && app->rpc()->isConnected() && app->worker()) {
|
||||
Notifications::instance().info("Starting blockchain rescan...");
|
||||
app->worker()->post([rpc = app->rpc()]() -> rpc::RPCWorker::MainCb {
|
||||
try {
|
||||
rpc->call("rescanblockchain", {0});
|
||||
return []() {
|
||||
Notifications::instance().success("Blockchain rescan started");
|
||||
};
|
||||
} catch (const std::exception& e) {
|
||||
std::string err = e.what();
|
||||
return [err]() {
|
||||
Notifications::instance().error("Failed to start rescan: " + err);
|
||||
};
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Notifications::instance().warning("Not connected to daemon");
|
||||
}
|
||||
app->rescanBlockchain();
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) ImGui::SetTooltip("Rescan the blockchain for missing transactions");
|
||||
ImGui::EndDisabled();
|
||||
@@ -1839,6 +1818,48 @@ void RenderSettingsPage(App* app) {
|
||||
|
||||
ImGui::EndChild(); // ##SettingsPageScroll
|
||||
|
||||
// Confirmation dialog for clearing z-tx history
|
||||
if (sp_confirm_clear_ztx) {
|
||||
if (BeginOverlayDialog("Confirm Clear Z-Tx History", &sp_confirm_clear_ztx, 480.0f, 0.94f)) {
|
||||
ImGui::PushFont(Type().iconLarge());
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), ICON_MD_WARNING);
|
||||
ImGui::PopFont();
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "Warning");
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped(
|
||||
"Clearing z-transaction history may cause your shielded balance to show as 0 "
|
||||
"until a wallet rescan is performed.");
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped(
|
||||
"If this happens, you will need to re-import your z-address private keys with "
|
||||
"rescan enabled to recover your balance.");
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
float btnW = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x) * 0.5f;
|
||||
if (ImGui::Button("Cancel", ImVec2(btnW, 40))) {
|
||||
sp_confirm_clear_ztx = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.2f, 0.2f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.3f, 0.3f, 1.0f));
|
||||
if (ImGui::Button("Clear Anyway", ImVec2(btnW, 40))) {
|
||||
std::string ztx_file = util::Platform::getDragonXDataDir() + "ztx_history.json";
|
||||
if (util::Platform::deleteFile(ztx_file)) {
|
||||
Notifications::instance().success("Z-transaction history cleared");
|
||||
} else {
|
||||
Notifications::instance().info("No history file found");
|
||||
}
|
||||
sp_confirm_clear_ztx = false;
|
||||
}
|
||||
ImGui::PopStyleColor(2);
|
||||
EndOverlayDialog();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "about_dialog.h"
|
||||
#include "../../app.h"
|
||||
#include "../../config/version.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/type.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
@@ -25,16 +23,7 @@ void RenderAboutDialog(App* app, bool* p_open)
|
||||
auto versionLbl = S.label("dialogs.about", "version-label");
|
||||
auto editionLbl = S.label("dialogs.about", "edition-label");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
// Use acrylic modal popup from current theme
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("About ObsidianDragon");
|
||||
if (!effects::ImGuiAcrylic::BeginAcrylicPopupModal("About ObsidianDragon", p_open,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
if (!material::BeginOverlayDialog("About ObsidianDragon", p_open, win.width, 0.94f)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -173,7 +162,7 @@ void RenderAboutDialog(App* app, bool* p_open)
|
||||
}
|
||||
|
||||
ImGui::PopFont(); // Body2
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "../../app.h"
|
||||
#include "../../data/address_book.h"
|
||||
#include "../notifications.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "imgui.h"
|
||||
@@ -67,14 +65,7 @@ void AddressBookDialog::render(App* app)
|
||||
auto notesInput = S.input("dialogs.address-book", "notes-input");
|
||||
auto actionBtn = S.button("dialogs.address-book", "action-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Address Book");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Address Book", &s_open,
|
||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Address Book", &s_open, win.width, 0.94f)) {
|
||||
auto& book = getAddressBook();
|
||||
|
||||
// Toolbar
|
||||
@@ -192,15 +183,16 @@ void AddressBookDialog::render(App* app)
|
||||
|
||||
// Status line
|
||||
ImGui::TextDisabled("%zu addresses saved", book.size());
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
|
||||
// Add dialog
|
||||
if (s_show_add_dialog) {
|
||||
ImGui::OpenPopup("Add Address");
|
||||
}
|
||||
|
||||
// Re-use center from above (already defined at start of render)
|
||||
// Re-use center for sub-dialogs
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (ImGui::BeginPopupModal("Add Address", &s_show_add_dialog, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <string>
|
||||
@@ -62,14 +61,7 @@ void BackupWalletDialog::render(App* app)
|
||||
auto backupBtn = S.button("dialogs.backup-wallet", "backup-button");
|
||||
auto closeBtn = S.button("dialogs.backup-wallet", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Backup Wallet");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Backup Wallet", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Backup Wallet", &s_open, win.width, 0.94f)) {
|
||||
ImGui::TextWrapped(
|
||||
"Create a backup of your wallet.dat file. This file contains all your "
|
||||
"private keys and transaction history. Store the backup in a secure location."
|
||||
@@ -191,8 +183,8 @@ void BackupWalletDialog::render(App* app)
|
||||
ImGui::BulletText("Store backups on external drives or cloud storage");
|
||||
ImGui::BulletText("Create multiple backups in different locations");
|
||||
ImGui::BulletText("Test restoring from backup periodically");
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "../notifications.h"
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -101,14 +99,7 @@ void BlockInfoDialog::render(App* app)
|
||||
auto hashBackLbl = S.label("dialogs.block-info", "hash-back-label");
|
||||
auto closeBtn = S.button("dialogs.block-info", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Block Information");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Block Information", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Block Information", &s_open, win.width, 0.94f)) {
|
||||
auto* rpc = app->rpc();
|
||||
const auto& state = app->getWalletState();
|
||||
|
||||
@@ -307,8 +298,8 @@ void BlockInfoDialog::render(App* app)
|
||||
if (material::StyledButton("Close", ImVec2(closeBtn.width, 0), S.resolveFont(closeBtn.font))) {
|
||||
s_open = false;
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -347,12 +347,8 @@ void ConsoleTab::render(daemon::EmbeddedDaemon* daemon, rpc::RPCClient* rpc, rpc
|
||||
void ConsoleTab::renderCommandsPopupModal()
|
||||
{
|
||||
if (!show_commands_popup_) {
|
||||
renderCommandsPopup();
|
||||
return;
|
||||
}
|
||||
// Called at top-level window scope so the modal blocks all input.
|
||||
ImGui::OpenPopup("RPC Command Reference");
|
||||
show_commands_popup_ = false;
|
||||
renderCommandsPopup();
|
||||
}
|
||||
|
||||
@@ -1287,18 +1283,8 @@ void ConsoleTab::renderCommandsPopup()
|
||||
{
|
||||
using namespace material;
|
||||
|
||||
// Center the modal
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
float popW = std::min(schema::UI().drawElement("tabs.console", "popup-max-width").size, ImGui::GetMainViewport()->Size.x * schema::UI().drawElement("tabs.console", "popup-width-ratio").size);
|
||||
float popH = std::min(schema::UI().drawElement("tabs.console", "popup-max-height").size, ImGui::GetMainViewport()->Size.y * schema::UI().drawElement("tabs.console", "popup-height-ratio").size);
|
||||
ImGui::SetNextWindowSize(ImVec2(popW, popH), ImGuiCond_Appearing);
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(Layout::spacingXl(), Layout::spacingLg()));
|
||||
if (!effects::ImGuiAcrylic::BeginAcrylicPopupModal("RPC Command Reference", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
ImGui::PopStyleVar();
|
||||
if (!material::BeginOverlayDialog("RPC Command Reference", &show_commands_popup_, popW, 0.94f)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1591,11 +1577,10 @@ void ConsoleTab::renderCommandsPopup()
|
||||
// Close button
|
||||
if (ImGui::Button("Close", ImVec2(-1, 0))) {
|
||||
cmdFilter[0] = '\0';
|
||||
ImGui::CloseCurrentPopup();
|
||||
show_commands_popup_ = false;
|
||||
}
|
||||
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
ImGui::PopStyleVar();
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
|
||||
void ConsoleTab::executeCommand(const std::string& cmd, rpc::RPCClient* rpc, rpc::RPCWorker* worker)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../material/type.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../../embedded/IconsMaterialDesign.h"
|
||||
#include "imgui.h"
|
||||
|
||||
@@ -70,14 +69,7 @@ void ExportAllKeysDialog::render(App* app)
|
||||
auto exportBtn = S.button("dialogs.export-all-keys", "export-button");
|
||||
auto closeBtn = S.button("dialogs.export-all-keys", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Export All Private Keys");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Export All Private Keys", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Export All Private Keys", &s_open, win.width, 0.94f)) {
|
||||
// Warning
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.4f, 0.4f, 1.0f));
|
||||
ImGui::PushFont(material::Type().iconSmall());
|
||||
@@ -250,8 +242,8 @@ void ExportAllKeysDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped("%s", s_status.c_str());
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <string>
|
||||
@@ -73,14 +72,7 @@ void ExportTransactionsDialog::render(App* app)
|
||||
auto exportBtn = S.button("dialogs.export-transactions", "export-button");
|
||||
auto closeBtn = S.button("dialogs.export-transactions", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Export Transactions to CSV");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Export Transactions to CSV", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Export Transactions to CSV", &s_open, win.width, 0.94f)) {
|
||||
const auto& state = app->getWalletState();
|
||||
|
||||
ImGui::Text("Export %zu transactions to CSV file.", state.transactions.size());
|
||||
@@ -165,8 +157,8 @@ void ExportTransactionsDialog::render(App* app)
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped("%s", s_status.c_str());
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../material/type.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../../embedded/IconsMaterialDesign.h"
|
||||
#include "imgui.h"
|
||||
|
||||
@@ -115,14 +113,7 @@ void ImportKeyDialog::render(App* app)
|
||||
auto importBtn = S.button("dialogs.import-key", "import-button");
|
||||
auto closeBtn = S.button("dialogs.import-key", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Import Private Key");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Import Private Key", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Import Private Key", &s_open, win.width, 0.94f)) {
|
||||
// Warning
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
|
||||
ImGui::PushFont(material::Type().iconSmall());
|
||||
@@ -283,8 +274,8 @@ void ImportKeyDialog::render(App* app)
|
||||
ImGui::TextDisabled("Supported key formats:");
|
||||
ImGui::BulletText("Z-address spending keys (secret-extended-key-...)");
|
||||
ImGui::BulletText("T-address WIF private keys");
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "../../rpc/rpc_client.h"
|
||||
#include "../../rpc/rpc_worker.h"
|
||||
#include "../../util/i18n.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "imgui.h"
|
||||
@@ -58,15 +56,7 @@ void KeyExportDialog::render(App* app)
|
||||
auto copyBtn = S.button("dialogs.key-export", "copy-button");
|
||||
auto closeBtn = S.button("dialogs.key-export", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImGui::OpenPopup(title);
|
||||
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal(title, &s_open,
|
||||
ImGuiWindowFlags_NoResize, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog(title, &s_open, win.width, 0.94f)) {
|
||||
ImGui::Spacing();
|
||||
|
||||
// Warning section with colored background
|
||||
@@ -239,7 +229,7 @@ void KeyExportDialog::render(App* app)
|
||||
s_show_key = false;
|
||||
}
|
||||
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace dragonx {
|
||||
@@ -64,14 +63,7 @@ void QRPopupDialog::render(App* app)
|
||||
auto addrInput = S.input("dialogs.qr-popup", "address-input");
|
||||
auto actionBtn = S.button("dialogs.qr-popup", "action-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("QR Code");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("QR Code", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("QR Code", &s_open, win.width, 0.94f)) {
|
||||
|
||||
// Label if present
|
||||
if (!s_label.empty()) {
|
||||
@@ -137,8 +129,8 @@ void QRPopupDialog::render(App* app)
|
||||
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(actionBtn.font))) {
|
||||
close();
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
|
||||
// Handle window close button
|
||||
if (!s_open && s_qr_texture != 0) {
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../widgets/qr_code.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <string>
|
||||
@@ -130,14 +128,7 @@ void RequestPaymentDialog::render(App* app)
|
||||
auto qr = S.drawElement("dialogs.request-payment", "qr-code");
|
||||
auto actionBtn = S.button("dialogs.request-payment", "action-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Request Payment");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Request Payment", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Request Payment", &s_open, win.width, 0.94f)) {
|
||||
const auto& state = app->getWalletState();
|
||||
|
||||
ImGui::TextWrapped(
|
||||
@@ -284,8 +275,8 @@ void RequestPaymentDialog::render(App* app)
|
||||
if (material::StyledButton("Close", ImVec2(actionBtn.width, 0), S.resolveFont(actionBtn.font))) {
|
||||
s_open = false;
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
|
||||
// Cleanup on close
|
||||
if (!s_open && s_qr_texture != 0) {
|
||||
|
||||
@@ -668,20 +668,13 @@ void RenderSendConfirmPopup(App* app) {
|
||||
|
||||
double total = s_amount + s_fee;
|
||||
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
float popupAvailW = ImGui::GetMainViewport()->Size.x * S.drawElement("tabs.send", "confirm-popup-width-ratio").size;
|
||||
float popupW = std::min(schema::UI().drawElement("tabs.send", "confirm-popup-max-width").size, popupAvailW);
|
||||
float popVs = Layout::vScale();
|
||||
ImGui::SetNextWindowSize(ImVec2(popupW, 0), ImGuiCond_Always);
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(Layout::spacingXl(), Layout::spacingLg()));
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal(TR("confirm_send"), nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog(TR("confirm_send"), nullptr, popupW, 0.94f)) {
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape) && !s_sending) {
|
||||
s_show_confirm = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
float popW = ImGui::GetContentRegionAvail().x;
|
||||
@@ -825,21 +818,15 @@ void RenderSendConfirmPopup(App* app) {
|
||||
}
|
||||
);
|
||||
s_show_confirm = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (TactileButton("Cancel", ImVec2(S.button("tabs.send", "cancel-button").width, std::max(schema::UI().drawElement("tabs.send", "confirm-btn-min-height").size, schema::UI().drawElement("tabs.send", "confirm-btn-base-height").size * popVs)), S.resolveFont(S.button("tabs.send", "cancel-button").font))) {
|
||||
s_show_confirm = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
} else {
|
||||
// BeginPopupModal returned false — popup was closed externally
|
||||
s_show_confirm = false;
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -140,15 +140,8 @@ void RenderSettingsWindow(App* app, bool* p_open)
|
||||
auto walletBtn = S.button("dialogs.settings", "wallet-button");
|
||||
auto saveBtn = S.button("dialogs.settings", "save-button");
|
||||
auto cancelBtn = S.button("dialogs.settings", "cancel-button");
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
// Use acrylic modal popup
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Settings");
|
||||
if (!effects::ImGuiAcrylic::BeginAcrylicPopupModal("Settings", p_open, ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
if (!material::BeginOverlayDialog("Settings", p_open, win.width, 0.94f)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -476,16 +469,53 @@ void RenderSettingsWindow(App* app, bool* p_open)
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
static bool s_confirm_clear_ztx = false;
|
||||
if (material::StyledButton("Clear Saved Z-Transaction History", ImVec2(walletBtn.width, 0), S.resolveFont(walletBtn.font))) {
|
||||
// Clear z-transaction history file
|
||||
std::string ztx_file = util::Platform::getDragonXDataDir() + "ztx_history.json";
|
||||
if (util::Platform::deleteFile(ztx_file)) {
|
||||
Notifications::instance().success("Z-transaction history cleared");
|
||||
} else {
|
||||
Notifications::instance().info("No history file found");
|
||||
}
|
||||
s_confirm_clear_ztx = true;
|
||||
}
|
||||
ImGui::TextDisabled(" Delete locally stored shielded transaction data");
|
||||
|
||||
// Confirmation dialog
|
||||
if (s_confirm_clear_ztx) {
|
||||
if (material::BeginOverlayDialog("Confirm Clear Z-Tx History", &s_confirm_clear_ztx, 480.0f, 0.94f)) {
|
||||
ImGui::PushFont(material::Type().iconLarge());
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), ICON_MD_WARNING);
|
||||
ImGui::PopFont();
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "Warning");
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped(
|
||||
"Clearing z-transaction history may cause your shielded balance to show as 0 "
|
||||
"until a wallet rescan is performed.");
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped(
|
||||
"If this happens, you will need to re-import your z-address private keys with "
|
||||
"rescan enabled to recover your balance.");
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
float btnW = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x) * 0.5f;
|
||||
if (ImGui::Button("Cancel", ImVec2(btnW, 40))) {
|
||||
s_confirm_clear_ztx = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.2f, 0.2f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.3f, 0.3f, 1.0f));
|
||||
if (ImGui::Button("Clear Anyway", ImVec2(btnW, 40))) {
|
||||
std::string ztx_file = util::Platform::getDragonXDataDir() + "ztx_history.json";
|
||||
if (util::Platform::deleteFile(ztx_file)) {
|
||||
Notifications::instance().success("Z-transaction history cleared");
|
||||
} else {
|
||||
Notifications::instance().info("No history file found");
|
||||
}
|
||||
s_confirm_clear_ztx = false;
|
||||
}
|
||||
ImGui::PopStyleColor(2);
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
@@ -560,7 +590,7 @@ void RenderSettingsWindow(App* app, bool* p_open)
|
||||
*p_open = false;
|
||||
}
|
||||
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "../notifications.h"
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -81,14 +79,7 @@ void ShieldDialog::render(App* app)
|
||||
? "Shield Coinbase Rewards"
|
||||
: "Merge to Address";
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup(title);
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal(title, &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog(title, &s_open, win.width, 0.94f)) {
|
||||
const auto& state = app->getWalletState();
|
||||
|
||||
// Description
|
||||
@@ -304,8 +295,8 @@ void ShieldDialog::render(App* app)
|
||||
}
|
||||
}
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "../../config/settings.h"
|
||||
#include "../../util/i18n.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "imgui.h"
|
||||
@@ -45,14 +44,7 @@ void TransactionDetailsDialog::render(App* app)
|
||||
auto memoInput = S.input("dialogs.transaction-details", "memo-input");
|
||||
auto bottomBtn = S.button("dialogs.transaction-details", "bottom-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Transaction Details");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Transaction Details", &s_open,
|
||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Transaction Details", &s_open, win.width, 0.94f)) {
|
||||
const auto& tx = s_transaction;
|
||||
|
||||
// Type indicator with color
|
||||
@@ -200,8 +192,8 @@ void TransactionDetailsDialog::render(App* app)
|
||||
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(bottomBtn.font))) {
|
||||
s_open = false;
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "../schema/ui_schema.h"
|
||||
#include "../material/draw_helpers.h"
|
||||
#include "../theme.h"
|
||||
#include "../effects/imgui_acrylic.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace dragonx {
|
||||
@@ -53,14 +52,7 @@ void ValidateAddressDialog::render(App* app)
|
||||
auto lbl = S.label("dialogs.validate-address", "label");
|
||||
auto closeBtn = S.button("dialogs.validate-address", "close-button");
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(win.width, win.height), ImGuiCond_FirstUseEver);
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowFocus();
|
||||
|
||||
const auto& acrylicTheme = GetCurrentAcrylicTheme();
|
||||
ImGui::OpenPopup("Validate Address");
|
||||
if (effects::ImGuiAcrylic::BeginAcrylicPopupModal("Validate Address", &s_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar, acrylicTheme.popup)) {
|
||||
if (material::BeginOverlayDialog("Validate Address", &s_open, win.width, 0.94f)) {
|
||||
ImGui::TextWrapped("Enter a DragonX address to check if it's valid and whether it belongs to this wallet.");
|
||||
|
||||
ImGui::Spacing();
|
||||
@@ -216,8 +208,8 @@ void ValidateAddressDialog::render(App* app)
|
||||
if (material::StyledButton("Close", ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
|
||||
s_open = false;
|
||||
}
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
effects::ImGuiAcrylic::EndAcrylicPopup();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
||||
Reference in New Issue
Block a user