feat(settings): add "Open app folder" button next to "Open data folder"

Add a button to the left of "Open data folder" that opens the ObsidianDragon
config folder (util::Platform::getObsidianDragonDir() — ~/.config/ObsidianDragon
etc.: settings, themes, logs), distinct from the daemon data/blockchain folder.
The two buttons render as a right-aligned group on the data-dir row, each an
explicit button-font width so the group's right edge lands exactly on the card
edge (no overflow). New i18n: settings_open_app_dir / tt_open_app_dir.

Full-node build clean; hygiene clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-02 02:44:43 -05:00
parent 96e05b4ba6
commit 51667b5a27
2 changed files with 20 additions and 8 deletions

View File

@@ -2029,11 +2029,15 @@ void RenderSettingsPage(App* app) {
// overflowed the card's right edge, worse at high DPI.
float openBtnW = nodeBtnFont->CalcTextSizeA(nodeBtnFont->LegacySize, FLT_MAX, 0,
TR("settings_open_data_dir")).x + ImGui::GetStyle().FramePadding.x * 2.0f;
// "Open app folder" (the ObsidianDragon config folder), left of the data button.
float appBtnW = nodeBtnFont->CalcTextSizeA(nodeBtnFont->LegacySize, FLT_MAX, 0,
TR("settings_open_app_dir")).x + ImGui::GetStyle().FramePadding.x * 2.0f;
float openGroupW = appBtnW + spMd + openBtnW;
float dataDirLabelW = ImGui::CalcTextSize(TR("settings_data_dir")).x;
float sizeLabelW = ImGui::CalcTextSize(TR("settings_wallet_size_label")).x;
float sizeValueW = ImGui::CalcTextSize(size_str.c_str()).x;
// Space reserved to the right of the path for the size block + button.
float trailW = sizeLabelW + Layout::spacingXs() + sizeValueW + spMd + openBtnW;
// Space reserved to the right of the path for the size block + both buttons.
float trailW = sizeLabelW + Layout::spacingXs() + sizeValueW + spMd + openGroupW;
float availForPath = contentW - dataDirLabelW - Layout::spacingXs() - spMd - trailW;
if (availForPath < 60.0f) availForPath = contentW - dataDirLabelW - Layout::spacingXs();
@@ -2087,16 +2091,22 @@ void RenderSettingsPage(App* app) {
else
ImGui::TextDisabled("%s", TR("settings_not_found"));
// Open-data-folder button: right-aligned on the data-dir row (rowTopY), with
// an EXPLICIT width (openBtnW) so its right edge lands exactly on the card
// edge and never overflows, regardless of DPI / font-scale timing.
// Folder buttons: [Open app folder] [Open data folder], right-aligned as a
// group on the data-dir row (rowTopY), each an EXPLICIT width so the group's
// right edge lands exactly on the card edge (no overflow at any DPI).
float rowY = rowTopY;
float rightEdge = sectionOrigin.x + contentW;
float openX = rightEdge - openBtnW;
float groupX = rightEdge - openGroupW;
float afterSizeX = ImGui::GetItemRectMax().x + spMd;
ImGui::SameLine(0, spMd);
if (openX > afterSizeX)
ImGui::SetCursorScreenPos(ImVec2(openX, rowY));
if (groupX > afterSizeX)
ImGui::SetCursorScreenPos(ImVec2(groupX, rowY));
// App (ObsidianDragon config) folder — opens ~/.config/ObsidianDragon etc.
if (TactileButton(TR("settings_open_app_dir"), ImVec2(appBtnW, 0), nodeBtnFont)) {
util::Platform::openFolder(util::Platform::getObsidianDragonDir());
}
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_open_app_dir"));
ImGui::SameLine(0, spMd);
if (TactileButton(TR("settings_open_data_dir"), ImVec2(openBtnW, 0), nodeBtnFont)) {
util::Platform::openFolder(dirPath);
}

View File

@@ -404,6 +404,8 @@ void I18n::loadBuiltinEnglish()
strings_["tt_open_dir"] = "Click to open in file explorer";
strings_["settings_open_data_dir"] = "Open data folder";
strings_["tt_open_data_dir"] = "Open the folder with your wallet and blockchain data in the file manager";
strings_["settings_open_app_dir"] = "Open app folder";
strings_["tt_open_app_dir"] = "Open the ObsidianDragon folder (settings, themes, logs) in the file manager";
strings_["tt_rpc_host"] = "Hostname of the DragonX daemon";
strings_["tt_rpc_user"] = "RPC authentication username";
strings_["tt_rpc_port"] = "Port for daemon RPC connections";