画廊添加

This commit is contained in:
2026-08-08 16:06:36 +08:00
parent 989ad91b69
commit b21043e3b8
17 changed files with 1008 additions and 170 deletions
+19 -2
View File
@@ -12,10 +12,12 @@ namespace adminive {
enum class View_Node_Kind {
all_fields,
field,
frontend,
vertical,
horizontal,
flow,
grid,
list,
group,
card,
tabs,
@@ -107,6 +109,10 @@ View_Node make_view_container(View_Node_Kind kind, Children&&... children) {
return result;
}
template <class... Children>
View_Node frontend(Children&&... children) {
return make_view_container(View_Node_Kind::frontend, std::forward<Children>(children)...);
}
template <class... Children>
View_Node vertical(Children&&... children) {
return make_view_container(View_Node_Kind::vertical, std::forward<Children>(children)...);
}
@@ -125,6 +131,10 @@ View_Node grid(std::size_t columns, Children&&... children) {
return result;
}
template <class... Children>
View_Node list(Children&&... children) {
return make_view_container(View_Node_Kind::list, std::forward<Children>(children)...);
}
template <class... Children>
View_Node group(std::string title, Children&&... children) {
auto result = make_view_container(View_Node_Kind::group, std::forward<Children>(children)...);
result.title = std::move(title);
@@ -380,7 +390,7 @@ bool descriptor_has_field(const Descriptor& descriptor, std::string_view name) {
return found;
}
template <Described_Type T>
void validate_view_node(const View_Node& node) {
void validate_view_node_impl(const View_Node& node, bool tab_allowed) {
const auto descriptor = describe<T>();
if(node.kind == View_Node_Kind::field && !descriptor_has_field(descriptor, node.field)) {
throw std::invalid_argument("view field does not exist: " + node.field);
@@ -388,6 +398,9 @@ void validate_view_node(const View_Node& node) {
if(node.kind == View_Node_Kind::grid && node.columns == 0) {
throw std::invalid_argument("grid view requires at least one column");
}
if(node.kind == View_Node_Kind::tab && !tab_allowed) {
throw std::invalid_argument("tab view can only be used inside tabs");
}
if(node.kind == View_Node_Kind::tabs) {
for(const auto& child : node.children) {
if(child.kind != View_Node_Kind::tab) {
@@ -396,10 +409,14 @@ void validate_view_node(const View_Node& node) {
}
}
for(const auto& child : node.children) {
validate_view_node<T>(child);
validate_view_node_impl<T>(child, node.kind == View_Node_Kind::tabs);
}
}
template <Described_Type T>
void validate_view_node(const View_Node& node) {
validate_view_node_impl<T>(node, false);
}
template <Described_Type T>
void validate_form_view(const Form_View& view) {
if(view.name.empty()) {
throw std::invalid_argument("form view name must not be empty");