diff --git a/src/ui/pages/settings_page.cpp b/src/ui/pages/settings_page.cpp index b21ab6e..8bc7fb4 100644 --- a/src/ui/pages/settings_page.cpp +++ b/src/ui/pages/settings_page.cpp @@ -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); } diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index f3721e7..87cb7fe 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -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";