#include "pch.h"
#include "list.h"
#include "container.h"
#include "util.h"
#include "../common/context.h"
#include "../common/object.h"
using namespace winrt;
using namespace Microsoft::
UI::Xaml;
using namespace Microsoft::
UI::Xaml::Controls;
using namespace Windows::
UI::Xaml::Interop;
using namespace winrt::Windows::Foundation;
using namespace Microsoft::
UI::Xaml::Markup;
using namespace Microsoft::
UI::Xaml::Media;
using namespace winrt::Microsoft::
UI::Xaml::Controls::Primitives;
UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args) {
UiObject* current = uic_current_obj(obj);
ListView listview = ListView();
if (args.multiselection) {
listview.SelectionMode(ListViewSelectionMode::Extended);
}
bool clickEnabled = listview.IsItemClickEnabled();
listview.IsItemClickEnabled(true);
UIElement elm = listview;
UiWidget* widget = new UiWidget(elm);
widget->data1 = args.model;
widget->data2 = args.getvalue;
ui_context_add_widget_destructor(current->ctx, widget);
ui_set_widget_groups(current->ctx, widget, args.groups);
UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname,
UI_VAR_LIST);
if (var) {
UiList* list = (UiList*)var->value;
list->update = ui_simple_list_update;
list->getselection = ui_listview_getselection;
list->setselection = ui_listview_setselection;
list->obj = widget;
ui_simple_list_update(list,
0);
}
if (args.onselection) {
ui_callback onselection = args.onselection;
void* cbdata = args.onselectiondata;
listview.SelectionChanged([onselection, cbdata, obj](IInspectable
const& sender, RoutedEventArgs evtargs) {
std::vector<
int> selectedRows = ui_create_listview_selection(sender.as<ListView>());
UiListSelection selection;
selection.rows = selectedRows.data();
selection.count = selectedRows.size();
UiEvent evt;
evt.obj = obj;
evt.window = obj->window;
evt.document = obj->ctx->document;
evt.eventdata = &selection;
evt.intval =
0;
onselection(&evt, cbdata);
});
}
if (args.onactivate) {
ui_callback cb = args.onactivate;
void* cbdata = args.onactivatedata;
listview.ItemClick([cb, cbdata, obj](IInspectable
const& sender, RoutedEventArgs evtargs) {
std::vector<
int> selectedRows = ui_create_listview_selection(sender.as<ListView>());
UiListSelection selection;
selection.rows = selectedRows.data();
selection.count = selectedRows.size();
UiEvent evt;
evt.obj = obj;
evt.window = obj->window;
evt.document = obj->ctx->document;
evt.eventdata = &selection;
evt.intval =
0;
cb(&evt, cbdata);
});
}
UI_APPLY_LAYOUT1(current, args);
current->container->Add(listview, false);
return widget;
}
UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args) {
UiObject* current = uic_current_obj(obj);
ComboBox combobox = ComboBox();
UIElement elm = combobox;
UiWidget* widget = new UiWidget(elm);
widget->data1 = args.model;
widget->data2 = args.getvalue;
ui_context_add_widget_destructor(current->ctx, widget);
ui_set_widget_groups(current->ctx, widget, args.groups);
UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname,
UI_VAR_LIST);
if (var) {
UiList* list = (UiList*)var->value;
list->update = ui_simple_list_update;
list->getselection = ui_dropdown_getselection;
list->setselection = ui_dropdown_setselection;
list->obj = widget;
ui_simple_list_update(list,
0);
}
if (args.onactivate) {
ui_callback cb = args.onactivate;
void* cbdata = args.onactivatedata;
combobox.SelectionChanged([cb, cbdata, obj](IInspectable
const& sender, RoutedEventArgs evtargs) {
int selectedrow = sender.as<ComboBox>().SelectedIndex();
UiListSelection selection;
selection.count =
1;
selection.rows = &selectedrow;
UiEvent evt;
evt.obj = obj;
evt.window = obj->window;
evt.document = obj->ctx->document;
evt.eventdata = &selection;
evt.intval = selectedrow;
cb(&evt, cbdata);
});
}
UI_APPLY_LAYOUT1(current, args);
current->container->Add(combobox, false);
return widget;
}
UiListSelection ui_listview_getselection(UiList *list) {
UiWidget *widget = (UiWidget*)list->obj;
ListView listview = widget->uielement.as<ListView>();
std::vector<
int> selectedRows = ui_create_listview_selection(listview);
UiListSelection selection = {
NULL,
0 };
if (selectedRows.size() >
0) {
selection.count = selectedRows.size();
int *data = selectedRows.data();
selection.rows = (
int*)calloc(selection.count,
sizeof(
int));
memcpy(selection.rows, data, selection.count);
}
return selection;
}
void ui_listview_setselection(UiList *list, UiListSelection selection) {
UiWidget* widget = (UiWidget*)list->obj;
if (selection.count >
0) {
ListView listview = widget->uielement.as<ListView>();
listview.SelectedIndex(selection.rows[
0]);
}
}
UiListSelection ui_dropdown_getselection(UiList *list) {
UiWidget* widget = (UiWidget*)list->obj;
ComboBox cb = widget->uielement.as<ComboBox>();
int index = cb.SelectedIndex();
UiListSelection selection = {
NULL,
0 };
if (index >=
0) {
selection.rows = (
int*)calloc(
1,
sizeof(
int));
selection.count =
1;
selection.rows[
0] = index;
}
return selection;
}
void ui_dropdown_setselection(UiList *list, UiListSelection selection) {
UiWidget* widget = (UiWidget*)list->obj;
if (selection.count >
0) {
ComboBox cb = widget->uielement.as<ComboBox>();
cb.SelectedIndex(selection.rows[
0]);
}
}
UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs args) {
UiObject* current = uic_current_obj(obj);
BreadcrumbBar bcbar = BreadcrumbBar();
UIElement elm = bcbar;
UiWidget* widget = new UiWidget(elm);
widget->data1 = args.model;
widget->data2 = args.getvalue;
ui_context_add_widget_destructor(current->ctx, widget);
ui_set_widget_groups(current->ctx, widget, args.groups);
UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname,
UI_VAR_LIST);
if (var) {
UiList* list = (UiList*)var->value;
list->update = ui_breadcrumbbar_update;
list->obj = widget;
ui_breadcrumbbar_update(list,
0);
}
if (args.onactivate) {
ui_callback cb = args.onactivate;
void* cbdata = args.onactivatedata;
bcbar.ItemClicked([cb, cbdata, obj](IInspectable
const& sender, BreadcrumbBarItemClickedEventArgs evtargs) {
UiEvent evt;
evt.obj = obj;
evt.window = obj->window;
evt.document = obj->ctx->document;
evt.eventdata = nullptr;
evt.intval = evtargs.Index();
cb(&evt, cbdata);
});
}
UI_APPLY_LAYOUT1(current, args);
current->container->Add(bcbar, false);
return widget;
}
static void* getstrvalue(
void* elm,
int ignore) {
return elm;
}
void ui_simple_list_update(UiList* list,
int i) {
UiWidget* widget = (UiWidget*)list->obj;
UiModel* model = (UiModel*)widget->data1;
ui_getvaluefunc getvalue = (ui_getvaluefunc)widget->data2;
ItemsControl listview = widget->uielement.as<ItemsControl>();
auto items = listview.Items();
if (getvalue == nullptr) {
if (model && model->getvalue) {
getvalue = model->getvalue;
}
else {
getvalue = getstrvalue;
}
}
items.Clear();
void* elm = list->first(list);
while (elm) {
char* value = (
char*)getvalue(elm,
0);
wchar_t* wstr = str2wstr(value, nullptr);
items.Append(box_value(wstr));
free(wstr);
elm = list->next(list);
}
}
extern "C" void ui_breadcrumbbar_update(UiList * list,
int i) {
UiWidget* widget = (UiWidget*)list->obj;
UiModel* model = (UiModel*)widget->data1;
ui_getvaluefunc getvalue = (ui_getvaluefunc)widget->data2;
if (getvalue == nullptr) {
if (model && model->getvalue) {
getvalue = model->getvalue;
}
else {
getvalue = getstrvalue;
}
}
BreadcrumbBar bar = widget->uielement.as<BreadcrumbBar>();
Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> items { winrt::single_threaded_vector<Windows::Foundation::IInspectable>() };
void* elm = list->first(list);
while (elm) {
char* value = (
char*)getvalue(elm,
0);
wchar_t* wstr = str2wstr(value, nullptr);
items.Append(box_value(wstr));
free(wstr);
elm = list->next(list);
}
bar.ItemsSource(items);
}
std::vector<
int> ui_create_listview_selection(ListView listview) {
std::vector<
int> selection;
int p =
0;
auto ranges = listview.SelectedRanges();
for (
auto range : ranges) {
int begin = range.FirstIndex();
int end = range.LastIndex();
for (
int i = begin; i <= end; i++) {
selection.push_back(i);
}
}
return selection;
}