#include "noesis_shim.h"
#include <NsCore/BaseComponent.h>
#include <NsCore/DynamicCast.h>
#include <NsCore/Noesis.h>
#include <NsCore/Ptr.h>
#include <NsGui/BaseCollection.h>
#include <NsGui/ColumnDefinition.h>
#include <NsGui/Decorator.h>
#include <NsGui/Grid.h>
#include <NsGui/GridLength.h>
#include <NsGui/Panel.h>
#include <NsGui/RowDefinition.h>
#include <NsGui/UICollection.h>
#include <NsGui/UIElement.h>
#include <NsGui/UIElementCollection.h>
static_assert(Noesis::GridUnitType_Auto == 0, "GridUnitType ordinal drift");
static_assert(Noesis::GridUnitType_Pixel == 1, "GridUnitType ordinal drift");
static_assert(Noesis::GridUnitType_Star == 2, "GridUnitType ordinal drift");
namespace {
void* handout(Noesis::BaseComponent* c) {
if (!c) return nullptr;
c->AddReference();
return c;
}
template <class T>
T* cast(void* p) {
if (!p) return nullptr;
return Noesis::DynamicCast<T*>(static_cast<Noesis::BaseComponent*>(p));
}
using UIElemColl = Noesis::UICollection<Noesis::UIElement>;
UIElemColl* as_children(void* p) {
if (!p) return nullptr;
return Noesis::DynamicCast<UIElemColl*>(static_cast<Noesis::BaseComponent*>(p));
}
Noesis::BaseCollection* as_defs(void* p) {
if (!p) return nullptr;
return Noesis::DynamicCast<Noesis::BaseCollection*>(static_cast<Noesis::BaseComponent*>(p));
}
}
extern "C" bool noesis_decorator_set_child(void* decorator, void* child) {
auto* d = cast<Noesis::Decorator>(decorator);
if (!d) return false;
if (!child) {
d->SetChild(nullptr);
return true;
}
auto* ui = cast<Noesis::UIElement>(child);
if (!ui) return false;
d->SetChild(ui);
return true;
}
extern "C" void* noesis_decorator_get_child(void* decorator) {
auto* d = cast<Noesis::Decorator>(decorator);
if (!d) return nullptr;
return static_cast<Noesis::BaseComponent*>(d->GetChild());
}
extern "C" void* noesis_panel_children_get(void* panel) {
auto* p = cast<Noesis::Panel>(panel);
if (!p) return nullptr;
return handout(p->GetChildren());
}
extern "C" int32_t noesis_panel_children_add(void* coll, void* child) {
UIElemColl* c = as_children(coll);
auto* ui = cast<Noesis::UIElement>(child);
if (!c || !ui) return -1;
return c->Add(ui);
}
extern "C" bool noesis_panel_children_insert(void* coll, uint32_t index, void* child) {
UIElemColl* c = as_children(coll);
auto* ui = cast<Noesis::UIElement>(child);
if (!c || !ui || index > (uint32_t)c->Count()) return false;
c->Insert(index, ui);
return true;
}
extern "C" bool noesis_panel_children_remove_at(void* coll, uint32_t index) {
UIElemColl* c = as_children(coll);
if (!c || index >= (uint32_t)c->Count()) return false;
c->RemoveAt(index);
return true;
}
extern "C" bool noesis_panel_children_clear(void* coll) {
UIElemColl* c = as_children(coll);
if (!c) return false;
c->Clear();
return true;
}
extern "C" int32_t noesis_panel_children_count(void* coll) {
UIElemColl* c = as_children(coll);
return c ? c->Count() : -1;
}
extern "C" void* noesis_panel_children_get_at(void* coll, uint32_t index) {
UIElemColl* c = as_children(coll);
if (!c || index >= (uint32_t)c->Count()) return nullptr;
return static_cast<Noesis::BaseComponent*>(c->Get(index));
}
extern "C" void* noesis_grid_row_definition_create(void) {
Noesis::Ptr<Noesis::RowDefinition> d = *new Noesis::RowDefinition();
return handout(d.GetPtr());
}
extern "C" void* noesis_grid_column_definition_create(void) {
Noesis::Ptr<Noesis::ColumnDefinition> d = *new Noesis::ColumnDefinition();
return handout(d.GetPtr());
}
extern "C" bool noesis_grid_row_definition_set_height(void* def, float value, int32_t unit) {
auto* d = cast<Noesis::RowDefinition>(def);
if (!d || unit < 0 || unit > 2) return false;
d->SetHeight(Noesis::GridLength(value, static_cast<Noesis::GridUnitType>(unit)));
return true;
}
extern "C" bool noesis_grid_row_definition_get_height(
void* def, float* out_value, int32_t* out_unit) {
auto* d = cast<Noesis::RowDefinition>(def);
if (!d) return false;
const Noesis::GridLength& gl = d->GetHeight();
if (out_value) *out_value = gl.GetValue();
if (out_unit) *out_unit = static_cast<int32_t>(gl.GetGridUnitType());
return true;
}
extern "C" bool noesis_grid_column_definition_set_width(void* def, float value, int32_t unit) {
auto* d = cast<Noesis::ColumnDefinition>(def);
if (!d || unit < 0 || unit > 2) return false;
d->SetWidth(Noesis::GridLength(value, static_cast<Noesis::GridUnitType>(unit)));
return true;
}
extern "C" bool noesis_grid_column_definition_get_width(
void* def, float* out_value, int32_t* out_unit) {
auto* d = cast<Noesis::ColumnDefinition>(def);
if (!d) return false;
const Noesis::GridLength& gl = d->GetWidth();
if (out_value) *out_value = gl.GetValue();
if (out_unit) *out_unit = static_cast<int32_t>(gl.GetGridUnitType());
return true;
}
extern "C" void* noesis_grid_get_row_definitions(void* grid) {
auto* g = cast<Noesis::Grid>(grid);
if (!g) return nullptr;
return handout(g->GetRowDefinitions());
}
extern "C" void* noesis_grid_get_column_definitions(void* grid) {
auto* g = cast<Noesis::Grid>(grid);
if (!g) return nullptr;
return handout(g->GetColumnDefinitions());
}
extern "C" int32_t noesis_definition_collection_add(void* coll, void* def) {
Noesis::BaseCollection* c = as_defs(coll);
auto* d = cast<Noesis::BaseDefinition>(def);
if (!c || !d) return -1;
return c->AddComponent(static_cast<Noesis::BaseComponent*>(d));
}
extern "C" bool noesis_definition_collection_insert(void* coll, uint32_t index, void* def) {
Noesis::BaseCollection* c = as_defs(coll);
auto* d = cast<Noesis::BaseDefinition>(def);
if (!c || !d || index > (uint32_t)c->Count()) return false;
c->InsertComponent(index, static_cast<Noesis::BaseComponent*>(d));
return true;
}
extern "C" bool noesis_definition_collection_remove_at(void* coll, uint32_t index) {
Noesis::BaseCollection* c = as_defs(coll);
if (!c || index >= (uint32_t)c->Count()) return false;
c->RemoveAt(index);
return true;
}
extern "C" bool noesis_definition_collection_clear(void* coll) {
Noesis::BaseCollection* c = as_defs(coll);
if (!c) return false;
c->Clear();
return true;
}
extern "C" int32_t noesis_definition_collection_count(void* coll) {
Noesis::BaseCollection* c = as_defs(coll);
return c ? c->Count() : -1;
}
extern "C" void* noesis_definition_collection_get(void* coll, uint32_t index) {
Noesis::BaseCollection* c = as_defs(coll);
if (!c || index >= (uint32_t)c->Count()) return nullptr;
return c->GetComponent(index).GetPtr();
}