feat(kotlin-compose): finalize design system + apps + sync sub-repo gitlinks
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
#include "data_table_logic.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace data_table {
|
||||
|
||||
const char* op_label(Op o) {
|
||||
switch (o) {
|
||||
case Op::Eq: return "=";
|
||||
case Op::Neq: return "!=";
|
||||
case Op::Gt: return ">";
|
||||
case Op::Gte: return ">=";
|
||||
case Op::Lt: return "<";
|
||||
case Op::Lte: return "<=";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
bool parse_number(const char* s, double& out) {
|
||||
if (!s || !*s) return false;
|
||||
char* end = nullptr;
|
||||
double v = std::strtod(s, &end);
|
||||
if (end == s) return false;
|
||||
while (*end == ' ' || *end == '\t') end++;
|
||||
if (*end != '\0') return false;
|
||||
out = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compare(const char* a, const char* b, Op op) {
|
||||
if (!a) a = "";
|
||||
if (!b) b = "";
|
||||
double na, nb;
|
||||
bool numeric = parse_number(a, na) && parse_number(b, nb);
|
||||
if (numeric) {
|
||||
switch (op) {
|
||||
case Op::Eq: return na == nb;
|
||||
case Op::Neq: return na != nb;
|
||||
case Op::Gt: return na > nb;
|
||||
case Op::Gte: return na >= nb;
|
||||
case Op::Lt: return na < nb;
|
||||
case Op::Lte: return na <= nb;
|
||||
}
|
||||
}
|
||||
int c = std::strcmp(a, b);
|
||||
switch (op) {
|
||||
case Op::Eq: return c == 0;
|
||||
case Op::Neq: return c != 0;
|
||||
case Op::Gt: return c > 0;
|
||||
case Op::Gte: return c >= 0;
|
||||
case Op::Lt: return c < 0;
|
||||
case Op::Lte: return c <= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<int> compute_visible_rows(const char* const* cells,
|
||||
int rows, int cols,
|
||||
const State& st)
|
||||
{
|
||||
std::vector<int> out;
|
||||
out.reserve(rows);
|
||||
for (int r = 0; r < rows; ++r) {
|
||||
bool keep = true;
|
||||
for (const auto& f : st.filters) {
|
||||
if (f.col < 0 || f.col >= cols) continue;
|
||||
const char* cell = cells[r * cols + f.col];
|
||||
if (!compare(cell, f.value.c_str(), f.op)) { keep = false; break; }
|
||||
}
|
||||
if (keep) out.push_back(r);
|
||||
}
|
||||
if (st.sort_col >= 0 && st.sort_col < cols) {
|
||||
int sc = st.sort_col;
|
||||
bool desc = st.sort_desc;
|
||||
std::sort(out.begin(), out.end(), [&](int a, int b) {
|
||||
const char* ca = cells[a * cols + sc];
|
||||
const char* cb = cells[b * cols + sc];
|
||||
if (!ca) ca = "";
|
||||
if (!cb) cb = "";
|
||||
double na, nb;
|
||||
bool num = parse_number(ca, na) && parse_number(cb, nb);
|
||||
int cmp;
|
||||
if (num) cmp = (na < nb) ? -1 : (na > nb ? 1 : 0);
|
||||
else cmp = std::strcmp(ca, cb);
|
||||
return desc ? (cmp > 0) : (cmp < 0);
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace data_table
|
||||
Reference in New Issue
Block a user