ui/winui/list.cpp

branch
newapi
changeset 221
a82d9beaa94a
parent 205
b1ac0dd1d38b
child 222
1121b61f8828
--- a/ui/winui/list.cpp	Tue Oct 17 21:50:48 2023 +0200
+++ b/ui/winui/list.cpp	Thu Oct 19 18:30:19 2023 +0200
@@ -41,6 +41,8 @@
 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) {
@@ -209,6 +211,113 @@
     return widget;
 }
 
+
+extern "C" static void destroy_ui_pathbar(void* ptr) {
+    UiPathBar* pb = (UiPathBar*)ptr;
+    delete pb;
+}
+
+static void ui_context_add_pathbar_destructor(UiContext* ctx, UiPathBar* pb) {
+    cxMempoolRegister(ctx->mp, pb, destroy_ui_pathbar);
+}
+
+UIEXPORT UIWIDGET ui_pathbar_create(UiObject* obj, UiPathBarArgs args) {
+    UiObject* current = uic_current_obj(obj);
+
+    // create view and toolkit wrapper
+    Border pathbar = Border();
+    
+    IInspectable bgRes = Application::Current().Resources().Lookup(box_value(L"TextControlBackground"));
+    IInspectable borderThicknessRes = Application::Current().Resources().Lookup(box_value(L"TextControlBorderThemeThickness"));
+    IInspectable borderBrushRes = Application::Current().Resources().Lookup(box_value(L"TextControlBorderBrush"));
+    // IInspectable cornerRes = Application::Current().Resources().Lookup(box_value(L"TextControlCornerRadius"));
+
+    Brush bgBrush = unbox_value<Brush>(bgRes);
+    Thickness border = unbox_value<Thickness>(borderThicknessRes);
+    Brush borderBrush = unbox_value<Brush>(borderBrushRes);
+    CornerRadius cornerRadius = { 4, 4, 4, 4 }; //unbox_value<CornerRadius>(cornerRes);
+
+    pathbar.Background(bgBrush);
+    pathbar.BorderBrush(borderBrush);
+    pathbar.BorderThickness(border);
+    pathbar.CornerRadius(cornerRadius);
+
+    Grid content = Grid();
+    pathbar.Child(content);
+
+    GridLength gl;
+    gl.Value = 1;
+    gl.GridUnitType = GridUnitType::Star;
+
+    ColumnDefinition coldef = ColumnDefinition();
+    coldef.Width(gl);
+    content.ColumnDefinitions().Append(coldef);
+
+    TextBox pathTextBox = TextBox();
+    Thickness t = { 0, 0, 0, 0 };
+    CornerRadius c = { 0 ,0, 0, 0 };
+    pathTextBox.BorderThickness(t);
+    //pathTextBox.CornerRadius(c);
+
+
+    pathTextBox.HorizontalAlignment(HorizontalAlignment::Stretch);
+    content.SetColumn(pathTextBox, 0);
+
+    content.Children().Append(pathTextBox);
+
+    // stackpanel for buttons
+    StackPanel buttons = StackPanel();
+    buttons.Orientation(Orientation::Horizontal);
+    buttons.Visibility(Visibility::Collapsed);
+    content.SetColumn(buttons, 0);
+    content.Children().Append(buttons);
+
+    if (args.ontextinput) {
+        // TODO
+    }
+
+    //pathTextBox.Visibility(Visibility::Collapsed);
+    
+    UiPathBar* uipathbar = new UiPathBar;
+    ui_context_add_pathbar_destructor(current->ctx, uipathbar);
+    uipathbar->grid = content;
+    uipathbar->buttons = buttons;
+    uipathbar->textbox = pathTextBox;
+    uipathbar->enabledrag = args.enabledrag;
+    uipathbar->enabledrop = args.enabledrop;
+    uipathbar->getvalue = args.getvalue;
+    uipathbar->model = args.model;
+    uipathbar->onactivate = args.onactivate;
+    uipathbar->onactivatedata = args.onactivatedata;
+    uipathbar->ondragstart = args.ondragstart;
+    uipathbar->ondragstartdata = args.ondragstartdata;
+    uipathbar->ondragcomplete = args.ondragcomplete;
+    uipathbar->ondragcompletedata = args.ondragcompletedata;
+    uipathbar->ondrop = args.ondrop;
+    uipathbar->ondropdata = args.ondropsdata;
+
+    UIElement elm = pathbar;
+    UiWidget* widget = new UiWidget(elm);
+    widget->data1 = uipathbar;
+    ui_context_add_widget_destructor(current->ctx, widget);
+
+    // bind var
+    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_pathbar_update;
+        list->obj = widget;
+        ui_pathbar_update(list, 0);
+    }
+
+    // add listview to current container
+    UI_APPLY_LAYOUT1(current, args);
+
+    current->container->Add(pathbar, false);
+
+    return widget;
+}
+
 static void* getstrvalue(void* elm, int ignore) {
     return elm;
 }
@@ -273,6 +382,58 @@
     bar.ItemsSource(items);
 }
 
+static void ui_pathbar_clear(StackPanel &buttons) {
+    for (int i = buttons.Children().Size() - 1; i >= 0; i--) {
+        buttons.Children().RemoveAt(i);
+    }
+}
+
+extern "C" void ui_pathbar_update(UiList * list, int i) {
+    UiWidget* widget = (UiWidget*)list->obj;
+    UiPathBar* pb = (UiPathBar*)widget->data1;
+    Grid grid = pb->grid;
+
+    UiModel* model = pb->model;
+    ui_getvaluefunc getvalue = pb->getvalue;
+
+    // priority: getvalue, model.getvalue, getstrvalue (fallback)
+    if (getvalue == nullptr) {
+        if (model && model->getvalue) {
+            getvalue = model->getvalue;
+        }
+        else {
+            getvalue = getstrvalue;
+        }
+    }
+
+    // hide textbox, show button panel
+    pb->textbox.Visibility(Visibility::Collapsed);
+    pb->buttons.Visibility(Visibility::Visible);
+
+    // clear old buttons
+    ui_pathbar_clear(pb->buttons);
+
+    // add new buttons
+    void* elm = list->first(list);
+    while (elm) {
+        char* value = (char*)getvalue(elm, 0);
+        wchar_t* wstr = str2wstr(value, nullptr);
+        Button button = Button();
+        button.Content(box_value(wstr));
+        free(wstr);
+
+        Thickness t = { 0, 0, 1, 0 };
+        CornerRadius c = { 0 ,0, 0, 0 };
+        button.BorderThickness(t);
+        button.CornerRadius(c);
+
+        pb->buttons.Children().Append(button);
+
+        elm = list->next(list);
+    }
+}
+
+
 std::vector<int> ui_create_listview_selection(ListView listview) {
     std::vector<int> selection;
     int p = 0;

mercurial