Files
egutierrez dff0d735c1 feat(cpp/core): primitivas UI estilo Mantine
Anade 9 primitivas reutilizables al registry C++ que replican el comportamiento
de los componentes correspondientes de @fn_library / Mantine v9, todas
estilizadas con tokens_cpp_core (colores Mantine dark + indigo):

- button_cpp_core         (component, pure)  variantes primary/secondary/subtle/danger + sm/md/lg
- icon_button_cpp_core    (component, pure)  cuadrado 28x28 con glyph centrado + tooltip
- toolbar_cpp_core        (component, pure)  grupo horizontal de acciones con separadores
- modal_dialog_cpp_core   (component, pure)  popup modal centrada + close con Escape
- text_input_cpp_core     (component, impure) InputText con label muted + placeholder
- select_cpp_core         (component, impure) dropdown con label + opcion '(none)' opcional
- toast_cpp_core          (component, impure) notificaciones efimeras + inbox con badge
- tree_view_cpp_core      (component, impure) jerarquia low-level con tree_node_clicked helper
- process_runner_cpp_core (component, impure) tarea en std::thread + spinner inline

Cada primitiva tiene su .md con frontmatter completo (params/output) y se
indexa via fn index. Son la base del primitives_gallery y de cualquier
app fn_ui futura.
2026-04-25 21:25:39 +02:00

63 lines
2.2 KiB
C++

#include "core/select.h"
#include "core/tokens.h"
#include <imgui.h>
#include <cstdio>
namespace fn_ui {
bool select(const char* label, int* selected_idx,
const char* const* options, int count,
bool allow_none) {
using namespace fn_tokens;
if (!selected_idx) return false;
// Label muted
ImGui::PushStyleColor(ImGuiCol_Text, colors::text_muted);
ImGui::TextUnformatted(label);
ImGui::PopStyleColor();
// Combo con estilo tokens
ImGui::PushStyleColor(ImGuiCol_FrameBg, colors::bg);
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, colors::surface_hover);
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, colors::surface);
ImGui::PushStyleColor(ImGuiCol_Border, colors::border);
ImGui::PushStyleColor(ImGuiCol_PopupBg, colors::surface);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, colors::surface_hover);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, radius::sm);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(spacing::sm, spacing::xs + 2.0f));
char id[160];
std::snprintf(id, sizeof(id), "##%s", label);
ImGui::SetNextItemWidth(-FLT_MIN);
const char* preview = "(none)";
if (*selected_idx >= 0 && *selected_idx < count) preview = options[*selected_idx];
bool changed = false;
if (ImGui::BeginCombo(id, preview)) {
if (allow_none) {
bool is_sel = (*selected_idx == -1);
if (ImGui::Selectable("(none)", is_sel)) {
if (*selected_idx != -1) { *selected_idx = -1; changed = true; }
}
if (is_sel) ImGui::SetItemDefaultFocus();
}
for (int i = 0; i < count; i++) {
bool is_sel = (*selected_idx == i);
if (ImGui::Selectable(options[i], is_sel)) {
if (*selected_idx != i) { *selected_idx = i; changed = true; }
}
if (is_sel) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(7);
return changed;
}
} // namespace fn_ui