refactor(ui): delete dead button code (buttons.h + ApplyTactile)

UI-standardization audit found two dead, contradictory "how to draw a button"
surfaces with zero call sites:
- src/ui/material/components/buttons.h (353 lines: TextButton/Outlined/Contained/
  Button(spec)/IconButton/FAB) — included by 3 mining files but never used.
- ApplyTactile (draw_helpers.h) — a retrofit-tactile-onto-plain-button wrapper,
  never called.
Remove the file, the 3 dead includes, and ApplyTactile. TactileButton/StyledButton
remain the canonical button helpers. No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-04 18:34:12 -05:00
parent e84cea27d9
commit 07f6d2efc9
5 changed files with 0 additions and 367 deletions

View File

@@ -1,352 +0,0 @@
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#pragma once
#include "../colors.h"
#include "../typography.h"
#include "../layout.h"
#include "../tooltip_style.h"
#include "imgui.h"
#include "imgui_internal.h"
namespace dragonx {
namespace ui {
namespace material {
// ============================================================================
// Material Design Button Components
// ============================================================================
// Based on https://m2.material.io/components/buttons
//
// Three button variants:
// - Text Button: Low emphasis, no container
// - Outlined Button: Medium emphasis, border only
// - Contained Button: High emphasis, filled background
enum class ButtonStyle {
Text, // Low emphasis - text only
Outlined, // Medium emphasis - border
Contained // High emphasis - filled (default)
};
/**
* @brief Button configuration
*/
struct ButtonSpec {
ButtonStyle style = ButtonStyle::Contained;
bool enabled = true;
bool fullWidth = false;
const char* icon = nullptr; // Leading icon (text glyph)
ImU32 color = 0; // 0 = use primary color
};
/**
* @brief Render a Material Design button
*
* @param label Button text (will be uppercased per Material spec)
* @param spec Button configuration
* @return true if clicked
*/
bool Button(const char* label, const ButtonSpec& spec = ButtonSpec());
/**
* @brief Render a text-only button (low emphasis)
*/
inline bool TextButton(const char* label, bool enabled = true) {
ButtonSpec spec;
spec.style = ButtonStyle::Text;
spec.enabled = enabled;
return Button(label, spec);
}
/**
* @brief Render an outlined button (medium emphasis)
*/
inline bool OutlinedButton(const char* label, bool enabled = true) {
ButtonSpec spec;
spec.style = ButtonStyle::Outlined;
spec.enabled = enabled;
return Button(label, spec);
}
/**
* @brief Render a contained/filled button (high emphasis)
*/
inline bool ContainedButton(const char* label, bool enabled = true) {
ButtonSpec spec;
spec.style = ButtonStyle::Contained;
spec.enabled = enabled;
return Button(label, spec);
}
/**
* @brief Render an icon button (circular touch target)
*
* @param icon Icon glyph/character
* @param tooltip Hover tooltip text
* @param enabled Whether button is enabled
* @return true if clicked
*/
bool IconButton(const char* icon, const char* tooltip = nullptr, bool enabled = true);
/**
* @brief Render a Floating Action Button (FAB)
*
* @param icon Icon glyph
* @param label Optional label for extended FAB
* @param mini Use mini size (40dp instead of 56dp)
* @return true if clicked
*/
bool FAB(const char* icon, const char* label = nullptr, bool mini = false);
// ============================================================================
// Implementation
// ============================================================================
inline bool Button(const char* label, const ButtonSpec& spec) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
// Convert label to uppercase for Material Design
char upperLabel[256];
{
const char* src = label;
char* dst = upperLabel;
char* end = upperLabel + sizeof(upperLabel) - 1;
while (*src && dst < end) {
*dst++ = (char)toupper((unsigned char)*src++);
}
*dst = '\0';
}
// Get button font
ImFont* buttonFont = Typography::instance().button();
ImGui::PushFont(buttonFont);
// Calculate button size
ImVec2 labelSize = ImGui::CalcTextSize(upperLabel);
float iconWidth = spec.icon ? (size::IconSize + size::ButtonIconGap) : 0.0f;
ImVec2 buttonSize;
buttonSize.x = spec.fullWidth ? ImGui::GetContentRegionAvail().x
: ImMax(labelSize.x + iconWidth + size::ButtonPaddingH * 2, size::ButtonMinWidth);
buttonSize.y = size::ButtonHeight;
// Get position
ImVec2 pos = window->DC.CursorPos;
ImRect bb(pos, ImVec2(pos.x + buttonSize.x, pos.y + buttonSize.y));
ImGui::ItemSize(buttonSize, style.FramePadding.y);
if (!ImGui::ItemAdd(bb, id)) {
ImGui::PopFont();
return false;
}
// Handle interaction
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
if (!spec.enabled) {
hovered = held = false;
}
if (hovered) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
// Get colors
ImU32 primaryColor = spec.color ? spec.color : Primary();
ImU32 textColor;
ImU32 bgColor;
ImU32 borderColor = 0;
switch (spec.style) {
case ButtonStyle::Text:
bgColor = 0; // No background
textColor = spec.enabled ? primaryColor : OnSurfaceDisabled();
if (hovered) bgColor = BlendOverlay(Surface(), StateHover(), 1.0f);
if (held) bgColor = BlendOverlay(Surface(), StatePressed(), 1.0f);
break;
case ButtonStyle::Outlined:
bgColor = 0; // No background
textColor = spec.enabled ? primaryColor : OnSurfaceDisabled();
borderColor = spec.enabled ? primaryColor : OnSurfaceDisabled();
if (hovered) bgColor = BlendOverlay(Surface(), StateHover(), 1.0f);
if (held) bgColor = BlendOverlay(Surface(), StatePressed(), 1.0f);
break;
case ButtonStyle::Contained:
default:
if (spec.enabled) {
bgColor = primaryColor;
textColor = OnPrimary();
if (hovered) bgColor = BlendOverlay(primaryColor, StateHover(), 1.0f);
if (held) bgColor = BlendOverlay(primaryColor, StatePressed(), 1.0f);
} else {
bgColor = WithAlphaF(OnSurface(), 0.12f);
textColor = OnSurfaceDisabled();
}
break;
}
// Render
ImDrawList* drawList = window->DrawList;
// Background
if (bgColor) {
drawList->AddRectFilled(bb.Min, bb.Max, bgColor, size::ButtonCornerRadius);
}
// Border (for outlined)
if (borderColor) {
drawList->AddRect(bb.Min, bb.Max, borderColor, size::ButtonCornerRadius, 0, 1.0f);
}
// Icon
float contentX = bb.Min.x + size::ButtonPaddingH;
float contentY = bb.Min.y + (buttonSize.y - labelSize.y) * 0.5f;
if (spec.icon) {
ImFont* iconFont = Type().iconMed();
ImVec2 iconSize = iconFont->CalcTextSizeA(iconFont->LegacySize, FLT_MAX, 0, spec.icon);
ImVec2 iconPos(contentX, bb.Min.y + (buttonSize.y - iconSize.y) * 0.5f);
drawList->AddText(iconFont, iconFont->LegacySize, iconPos, textColor, spec.icon);
contentX += iconSize.x + size::ButtonIconGap;
}
// Label
drawList->AddText(ImVec2(contentX, contentY), textColor, upperLabel);
ImGui::PopFont();
return pressed && spec.enabled;
}
inline bool IconButton(const char* icon, const char* tooltip, bool enabled) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
const ImGuiID id = window->GetID(icon);
ImVec2 pos = window->DC.CursorPos;
ImVec2 size(size::IconButtonSize, size::IconButtonSize);
ImRect bb(pos, ImVec2(pos.x + size.x, pos.y + size.y));
ImGui::ItemSize(size);
if (!ImGui::ItemAdd(bb, id))
return false;
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
if (!enabled) {
hovered = held = false;
}
if (hovered) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
// Render ripple/hover circle
ImDrawList* drawList = window->DrawList;
ImVec2 center = bb.GetCenter();
float radius = size::IconButtonSize * 0.5f;
if (hovered || held) {
ImU32 overlayColor = held ? StatePressed() : StateHover();
drawList->AddCircleFilled(center, radius, overlayColor);
}
// Render icon (use icon font)
ImFont* iconFont = Type().iconMed();
ImU32 iconColor = enabled ? OnSurface() : OnSurfaceDisabled();
ImVec2 iconSize = iconFont->CalcTextSizeA(iconFont->LegacySize, FLT_MAX, 0, icon);
ImVec2 iconPos(center.x - iconSize.x * 0.5f, center.y - iconSize.y * 0.5f);
drawList->AddText(iconFont, iconFont->LegacySize, iconPos, iconColor, icon);
// Tooltip
if (tooltip && hovered) {
material::Tooltip("%s", tooltip);
}
return pressed && enabled;
}
inline bool FAB(const char* icon, const char* label, bool mini) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
const ImGuiID id = window->GetID(icon);
bool extended = (label != nullptr);
float fabSize = mini ? size::FabMiniSize : size::FabSize;
ImVec2 buttonSize;
if (extended) {
ImVec2 labelSize = ImGui::CalcTextSize(label);
buttonSize.x = size::FabExtendedPadding * 2 + size::IconSize + spacing::Sm + labelSize.x;
buttonSize.y = size::FabExtendedHeight;
} else {
buttonSize.x = fabSize;
buttonSize.y = fabSize;
}
ImVec2 pos = window->DC.CursorPos;
ImRect bb(pos, ImVec2(pos.x + buttonSize.x, pos.y + buttonSize.y));
ImGui::ItemSize(buttonSize);
if (!ImGui::ItemAdd(bb, id))
return false;
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
if (hovered) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
// Colors
ImU32 bgColor = Secondary();
ImU32 textColor = OnSecondary();
if (hovered) bgColor = BlendOverlay(bgColor, StateHover(), 1.0f);
if (held) bgColor = BlendOverlay(bgColor, StatePressed(), 1.0f);
// Render
ImDrawList* drawList = window->DrawList;
float radius = extended ? size::FabCornerRadius : (fabSize * 0.5f);
drawList->AddRectFilled(bb.Min, bb.Max, bgColor, radius);
// Icon
ImVec2 center = bb.GetCenter();
ImFont* iconFont = Type().iconMed();
if (extended) {
ImVec2 iconSize = iconFont->CalcTextSizeA(iconFont->LegacySize, FLT_MAX, 0, icon);
float iconX = bb.Min.x + size::FabExtendedPadding;
float iconY = center.y - iconSize.y * 0.5f;
drawList->AddText(iconFont, iconFont->LegacySize, ImVec2(iconX, iconY), textColor, icon);
// Label
Typography::instance().pushFont(TypeStyle::Button);
float labelX = iconX + iconSize.x + spacing::Sm;
float labelY = center.y - ImGui::GetFontSize() * 0.5f;
drawList->AddText(ImVec2(labelX, labelY), textColor, label);
Typography::instance().popFont();
} else {
ImVec2 iconSize = iconFont->CalcTextSizeA(iconFont->LegacySize, FLT_MAX, 0, icon);
ImVec2 iconPos(center.x - iconSize.x * 0.5f, center.y - iconSize.y * 0.5f);
drawList->AddText(iconFont, iconFont->LegacySize, iconPos, textColor, icon);
}
return pressed;
}
} // namespace material
} // namespace ui
} // namespace dragonx

View File

@@ -260,18 +260,6 @@ inline void DrawButtonGlassOverlay(ImDrawList* dl, const ImVec2& bMin,
DrawTactileOverlay(dl, bMin, bMax, rounding, active);
}
// Convenience: call right after any ImGui::Button() / SmallButton() call
// to add tactile depth. Uses the last item rect automatically.
inline void ApplyTactile(ImDrawList* dl = nullptr)
{
if (!dl) dl = ImGui::GetWindowDrawList();
ImVec2 bMin = ImGui::GetItemRectMin();
ImVec2 bMax = ImGui::GetItemRectMax();
float rounding = ImGui::GetStyle().FrameRounding;
bool active = ImGui::IsItemActive();
DrawTactileOverlay(dl, bMin, bMax, rounding, active);
}
// ── Button font tier helper ─────────────────────────────────────────────
// Resolves an int tier (0=sm, 1=md/default, 2=lg) to the matching ImFont*.
// Passing -1 or any out-of-range value returns the default button font.

View File

@@ -16,7 +16,6 @@
#include "../material/type.h"
#include "../material/draw_helpers.h"
#include "../material/colors.h"
#include "../material/components/buttons.h"
#include "../layout.h"
#include "../notifications.h"
#include "../../embedded/IconsMaterialDesign.h"

View File

@@ -16,7 +16,6 @@
#include "../material/type.h"
#include "../material/draw_helpers.h"
#include "../material/colors.h"
#include "../material/components/buttons.h"
#include "../layout.h"
#include "../notifications.h"
#include "../../embedded/IconsMaterialDesign.h"

View File

@@ -22,7 +22,6 @@
#include "../material/type.h"
#include "../material/draw_helpers.h"
#include "../material/colors.h"
#include "../material/components/buttons.h"
#include "../effects/low_spec.h"
#include "../layout.h"
#include "../notifications.h"