# HG changeset patch # User Olaf Wintermann # Date 1701009868 -3600 # Node ID 097f45f9c1fac53443c024cd9f7b48132dd4427b # Parent 88bc21b19213fd81dff07ebc29039777cc6c05bc add new path textfield (WinUI3) diff -r 88bc21b19213 -r 097f45f9c1fa make/vs/testapp/main.c --- a/make/vs/testapp/main.c Fri Oct 20 16:34:33 2023 +0200 +++ b/make/vs/testapp/main.c Sun Nov 26 15:44:28 2023 +0100 @@ -44,6 +44,7 @@ UiString* t1; UiString* t2; UiString* t3; + UiString* path; UiList* list2; UiList* list3; UiDouble* progress; @@ -140,6 +141,7 @@ void action_breadcrumb(UiEvent* event, void* data) { int i = event->intval; + char* c = event->eventdata; printf("index: %d\n", i); } @@ -175,6 +177,7 @@ wdata->t1 = ui_string_new(obj->ctx, "t1"); wdata->t2 = ui_string_new(obj->ctx, "t2"); wdata->t3 = ui_string_new(obj->ctx, "t3"); + wdata->path = ui_string_new(obj->ctx, "path"); wdata->progress = ui_double_new(obj->ctx, "progress"); wdata->spinner = ui_int_new(obj->ctx, "spinner"); @@ -258,9 +261,11 @@ ui_newline(obj); //ui_breadcrumbbar(obj, .list = wdata->list3, .onactivate=action_breadcrumb); - ui_pathbar(obj, .colspan = 3, .list = wdata->list3, .onactivate = action_breadcrumb); + ui_textfield(obj, .varname = "newtext"); + ui_path_textfield(obj, .colspan = 2, .value=wdata->path, .onactivate = action_breadcrumb); ui_newline(obj); - + wdata->path->set(wdata->path, "/usr/path/test"); + ui_textfield(obj, .value = wdata->text); ui_passwordfield(obj, .value = wdata->password); ui_newline(obj); diff -r 88bc21b19213 -r 097f45f9c1fa ui/ui/text.h --- a/ui/ui/text.h Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/ui/text.h Sun Nov 26 15:44:28 2023 +0100 @@ -49,6 +49,41 @@ void* onchangedata; } UiTextFieldArgs; +typedef struct UiPathElmRet { + char* name; + size_t name_len; + char* path; + size_t path_len; +} UiPathElm; + +typedef UiPathElm*(*ui_pathelm_func)(const char *full_path, size_t len, size_t *ret_nelm, void* data); + + + +typedef struct UiPathTextFieldArgs { + UiTri fill; + UiBool hexpand; + UiBool vexpand; + int colspan; + int rowspan; + + UiString *value; + const char* varname; + + ui_pathelm_func getpathelm; + void* getpathelmdata; + + ui_callback onactivate; + void* onactivatedata; + + ui_callback ondragstart; + void* ondragstartdata; + ui_callback ondragcomplete; + void* ondragcompletedata; + ui_callback ondrop; + void* ondropsdata; +} UiPathTextFieldArgs; + UIWIDGET ui_textarea(UiObject *obj, UiText *value); UIWIDGET ui_textarea_nv(UiObject *obj, char *varname); @@ -60,10 +95,13 @@ #define ui_textfield(obj, ...) ui_textfield_create(obj, (UiTextFieldArgs) { __VA_ARGS__ }) #define ui_frameless_textfield(obj, ...) ui_frameless_field_create(obj, (UiTextFieldArgs) { __VA_ARGS__ }) #define ui_passwordfield(obj, ...) ui_passwordfield_create(obj, (UiTextFieldArgs) { __VA_ARGS__ }) +#define ui_path_textfield(obj, ...) ui_path_textfield_create(obj, (UiPathTextFieldArgs) { __VA_ARGS__ } ) UIEXPORT UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs args); UIEXPORT UIWIDGET ui_frameless_textfield_create(UiObject* obj, UiTextFieldArgs args); UIEXPORT UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs args); + +UIEXPORT UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs args); #ifdef __cplusplus } diff -r 88bc21b19213 -r 097f45f9c1fa ui/ui/tree.h --- a/ui/ui/tree.h Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/ui/tree.h Sun Nov 26 15:44:28 2023 +0100 @@ -41,7 +41,6 @@ typedef struct UiListDnd UiListDnd; typedef struct UiListArgs UiListArgs; -typedef struct UiPathBarArgs UiPathBarArgs; typedef enum UiModelType { UI_STRING = 0, @@ -135,31 +134,6 @@ UiBool multiselection; }; -struct UiPathBarArgs { - UiTri fill; - UiBool hexpand; - UiBool vexpand; - int colspan; - int rowspan; - - UiList* list; - const char* varname; - UiModel* model; - ui_getvaluefunc getvalue; - ui_callback onactivate; - void* onactivatedata; - ui_callback ontextinput; - void* ontextinputdata; - ui_callback ondragstart; - void* ondragstartdata; - ui_callback ondragcomplete; - void* ondragcompletedata; - ui_callback ondrop; - void* ondropsdata; - UiBool enabledrag; - UiBool enabledrop; -}; - UIEXPORT UiModel* ui_model(UiContext *ctx, ...); UIEXPORT UiModel* ui_model_copy(UiContext *ctx, UiModel* model); UIEXPORT void ui_model_free(UiContext *ctx, UiModel *mi); @@ -168,13 +142,11 @@ #define ui_table(obj, ...) ui_table_create(obj, (UiListArgs) { __VA_ARGS__ } ) #define ui_combobox(obj, ...) ui_combobox_create(obj, (UiListArgs) { __VA_ARGS__ } ) #define ui_breadcrumbbar(obj, ...) ui_breadcrumbbar_create(obj, (UiListArgs) { __VA_ARGS__ } ) -#define ui_pathbar(obj, ...) ui_pathbar_create(obj, (UiPathBarArgs) { __VA_ARGS__ } ) UIEXPORT UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args); UIEXPORT UIWIDGET ui_table_create(UiObject* obj, UiListArgs args); UIEXPORT UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args); UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs args); -UIEXPORT UIWIDGET ui_pathbar_create(UiObject* obj, UiPathBarArgs args); void ui_table_dragsource(UIWIDGET tablewidget, int actions, char *target0, ...); diff -r 88bc21b19213 -r 097f45f9c1fa ui/winui/list.cpp --- a/ui/winui/list.cpp Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/winui/list.cpp Sun Nov 26 15:44:28 2023 +0100 @@ -45,6 +45,7 @@ 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); @@ -211,114 +212,6 @@ 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(bgRes); - Thickness border = unbox_value(borderThicknessRes); - Brush borderBrush = unbox_value(borderBrushRes); - CornerRadius cornerRadius = { 4, 4, 4, 4 }; //unbox_value(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->obj = obj; - 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; } @@ -383,71 +276,6 @@ 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); - int j = 0; - while (elm) { - char* value = (char*)getvalue(elm, 0); - wchar_t* wstr = str2wstr(value, nullptr); - Button button = Button(); - button.Content(box_value(wstr)); - free(wstr); - - if (pb->onactivate) { - button.Click([pb, j](IInspectable const& sender, RoutedEventArgs) { - UiEvent evt; - evt.obj = pb->obj; - evt.window = evt.obj->window; - evt.document = evt.obj->ctx->document; - evt.eventdata = nullptr; - evt.intval = j; - pb->onactivate(&evt, pb->onactivatedata); - }); - } - - Thickness t = { 0, 0, 1, 0 }; - CornerRadius c = { 0 ,0, 0, 0 }; - button.BorderThickness(t); - button.CornerRadius(c); - - pb->buttons.Children().Append(button); - - j++; - elm = list->next(list); - } -} - std::vector ui_create_listview_selection(ListView listview) { std::vector selection; diff -r 88bc21b19213 -r 097f45f9c1fa ui/winui/list.h --- a/ui/winui/list.h Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/winui/list.h Sun Nov 26 15:44:28 2023 +0100 @@ -33,28 +33,6 @@ #include "../ui/container.h" -struct UiPathBar { - winrt::Microsoft::UI::Xaml::Controls::Grid grid = { nullptr }; - winrt::Microsoft::UI::Xaml::Controls::StackPanel buttons = { nullptr }; - winrt::Microsoft::UI::Xaml::Controls::TextBox textbox = { nullptr }; - - UiObject* obj; - UiModel* model; - ui_getvaluefunc getvalue; - ui_callback onactivate; - void* onactivatedata; - ui_callback ontextinput; - void* ontextinputdata; - ui_callback ondragstart; - void* ondragstartdata; - ui_callback ondragcomplete; - void* ondragcompletedata; - ui_callback ondrop; - void* ondropdata; - UiBool enabledrag; - UiBool enabledrop; -}; - extern "C" void ui_simple_list_update(UiList * list, int i); diff -r 88bc21b19213 -r 097f45f9c1fa ui/winui/pch.h --- a/ui/winui/pch.h Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/winui/pch.h Sun Nov 26 15:44:28 2023 +0100 @@ -29,5 +29,8 @@ #include #include #include +#include +#include +#include #include diff -r 88bc21b19213 -r 097f45f9c1fa ui/winui/text.cpp --- a/ui/winui/text.cpp Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/winui/text.cpp Sun Nov 26 15:44:28 2023 +0100 @@ -33,16 +33,23 @@ #include "../common/context.h" #include "../common/object.h" +#include +#include + #include "util.h" #include "container.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; - +using namespace winrt::Windows::UI::Xaml::Input; UIWIDGET ui_textfield_create(UiObject* obj, UiTextFieldArgs args) { UiObject* current = uic_current_obj(obj); @@ -160,3 +167,303 @@ PasswordBox box = widget->uielement.as(); box.Password(ui_string_set(str, newvalue)); } + + +// ------------------------ path textfield -------------------------------------- + +extern "C" static void destroy_ui_pathtextfield(void* ptr) { + UiPathTextField* pb = (UiPathTextField*)ptr; + delete pb; +} + +static void ui_context_add_pathtextfield_destructor(UiContext* ctx, UiPathTextField* pb) { + cxMempoolRegister(ctx->mp, pb, destroy_ui_pathtextfield); +} + +static void ui_pathtextfield_clear(StackPanel& buttons) { + for (int i = buttons.Children().Size() - 1; i >= 0; i--) { + buttons.Children().RemoveAt(i); + } +} + +static void ui_pathfield_free_pathelms(UiPathElm* elms, size_t nelm) { + if (!elms) { + return; + } + for (int i = 0; i < nelm; i++) { + UiPathElm e = elms[i]; + free(e.name); + free(e.path); + } + free(elms); +} + +UiPathTextField::~UiPathTextField() { + ui_pathfield_free_pathelms(this->current_path, this->current_path_nelms); +} + +static UiPathElm* default_pathelm_func(const char* full_path, size_t len, size_t* ret_nelm, void* data) { + cxstring *pathelms; + size_t nelm = cx_strsplit_a(cxDefaultAllocator, cx_strn(full_path, len), CX_STR("/"), 4096, &pathelms); + + if (nelm == 0) { + *ret_nelm = 0; + return nullptr; + } + + UiPathElm* elms = (UiPathElm*)calloc(nelm, sizeof(UiPathElm)); + size_t n = nelm; + int j = 0; + for (int i = 0; i < nelm; i++) { + cxstring c = pathelms[i]; + if (c.length == 0) { + if (i == 0) { + c.length = 1; + } + else { + n--; + continue; + } + } + + cxmutstr m = cx_strdup(c); + elms[j].name = m.ptr; + elms[j].name_len = m.length; + + size_t elm_path_len = c.ptr + c.length - full_path; + cxmutstr elm_path = cx_strdup(cx_strn(full_path, elm_path_len)); + elms[j].path = elm_path.ptr; + elms[j].path_len = elm_path.length; + + j++; + } + *ret_nelm = n; + + return elms; +} + +void ui_pathtextfield_update(UiPathTextField* pb, const char *full_path) { + Grid grid = pb->grid; + + ui_pathelm_func getpathelm = pb->getpathelm; + void* getpathelmdata = pb->getpathelmdata; + + // hide textbox, show button panel + pb->textbox.Visibility(Visibility::Collapsed); + pb->buttons.Visibility(Visibility::Visible); + + // clear old buttons + ui_pathtextfield_clear(pb->buttons); + + size_t full_path_len = full_path ? strlen(full_path) : 0; + + size_t nelm = 0; + UiPathElm* path_elm = getpathelm(full_path, full_path_len, &nelm, getpathelmdata); + ui_pathfield_free_pathelms(pb->current_path, pb->current_path_nelms); + pb->current_path = path_elm; + pb->current_path_nelms = nelm; + + // add new buttons + int j = 0; + for (int i = 0; i < nelm;i++) { + UiPathElm elm = path_elm[i]; + wchar_t* wstr = str2wstr_len(elm.name, elm.name_len, nullptr); + Button button = Button(); + button.Content(box_value(wstr)); + free(wstr); + + if (pb->onactivate) { + button.Click([pb, j, elm](IInspectable const& sender, RoutedEventArgs) { + // copy elm.path because it could be a non-terminated string + cxmutstr elmpath = cx_strdup(cx_strn(elm.path, elm.path_len)); + + UiEvent evt; + evt.obj = pb->obj; + evt.window = evt.obj->window; + evt.document = evt.obj->ctx->document; + evt.eventdata = elmpath.ptr; + evt.intval = j; + pb->onactivate(&evt, pb->onactivatedata); + + free(elmpath.ptr); + }); + } + + Thickness t = { 0, 0, 1, 0 }; + CornerRadius c = { 0 ,0, 0, 0 }; + button.BorderThickness(t); + button.CornerRadius(c); + + pb->buttons.Children().Append(button); + + j++; + } +} + +char* ui_path_textfield_get(UiString * str) { + UiPathTextField* widget = (UiPathTextField*)str->obj; + TextBox box = widget->textbox; + std::wstring wstr(box.Text()); + return ui_string_get(str, wstr); +} + +void ui_path_textfield_set(UiString* str, const char* newvalue) { + UiPathTextField* widget = (UiPathTextField*)str->obj; + TextBox box = widget->textbox; + box.Text(ui_string_set(str, newvalue)); + ui_pathtextfield_update(widget, newvalue); +} + +UIEXPORT UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs 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(bgRes); + Thickness border = unbox_value(borderThicknessRes); + Brush borderBrush = unbox_value(borderBrushRes); + CornerRadius cornerRadius = { 4, 4, 4, 4 }; //unbox_value(cornerRes); + + pathbar.Background(bgBrush); + pathbar.BorderBrush(borderBrush); + pathbar.BorderThickness(border); + pathbar.CornerRadius(cornerRadius); + + Grid content = Grid(); + pathbar.Child(content); + + GridLength gl; + gl.Value = 0; + gl.GridUnitType = GridUnitType::Auto; + + ColumnDefinition coldef = ColumnDefinition(); + coldef.Width(gl); + content.ColumnDefinitions().Append(coldef); + + gl.Value = 1; + gl.GridUnitType = GridUnitType::Star; + + ColumnDefinition coldef2 = ColumnDefinition(); + coldef2.Width(gl); + content.ColumnDefinitions().Append(coldef2); + + 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.SetColumnSpan(pathTextBox, 2); + + 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); + + TextBlock filler = TextBlock(); + filler.VerticalAlignment(VerticalAlignment::Stretch); + //filler.Text(winrt::hstring(L"hello filler")); + + filler.HorizontalAlignment(HorizontalAlignment::Stretch); + filler.VerticalAlignment(VerticalAlignment::Stretch); + content.SetColumn(filler, 1); + content.Children().Append(filler); + + filler.PointerPressed( + winrt::Microsoft::UI::Xaml::Input::PointerEventHandler( + [=](IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& args) { + pathTextBox.Visibility(Visibility::Visible); + buttons.Visibility(Visibility::Collapsed); + filler.Visibility(Visibility::Collapsed); + pathTextBox.SelectionStart(pathTextBox.Text().size()); + pathTextBox.SelectionLength(0); + pathTextBox.Focus(FocusState::Keyboard); + }) + ); + + //pathTextBox.Visibility(Visibility::Collapsed); + + UiPathTextField* uipathbar = new UiPathTextField; + ui_context_add_pathtextfield_destructor(current->ctx, uipathbar); + uipathbar->grid = content; + uipathbar->buttons = buttons; + uipathbar->textbox = pathTextBox; + uipathbar->filler = filler; + uipathbar->obj = obj; + uipathbar->getpathelm = args.getpathelm ? args.getpathelm : default_pathelm_func; + uipathbar->getpathelmdata = args.getpathelmdata; + 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; + + + pathTextBox.KeyDown( + winrt::Microsoft::UI::Xaml::Input::KeyEventHandler( + [=](winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const& e) { + auto key = e.Key(); + bool showButtons = false; + bool update = false; + if (key == Windows::System::VirtualKey::Escape) { + showButtons = true; + } + else if (key == Windows::System::VirtualKey::Enter) { + showButtons = true; + update = true; + } + + if (showButtons) { + pathTextBox.Visibility(Visibility::Collapsed); + buttons.Visibility(Visibility::Visible); + filler.Visibility(Visibility::Visible); + if (update) { + std::wstring value(pathTextBox.Text()); + char* full_path = wchar2utf8(value.c_str(), value.length()); + ui_pathtextfield_update(uipathbar, full_path); + free(full_path); + } + + //buttons.Focus(FocusState::Keyboard); + } + }) + ); + + + 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.value, args.varname, UI_VAR_LIST); + if (var) { + UiString* value = (UiString*)var->value; + value->obj = uipathbar; + value->get = ui_path_textfield_get; + value->set = ui_path_textfield_set; + } + + // add listview to current container + UI_APPLY_LAYOUT1(current, args); + + current->container->Add(pathbar, false); + + return widget; +} diff -r 88bc21b19213 -r 097f45f9c1fa ui/winui/text.h --- a/ui/winui/text.h Fri Oct 20 16:34:33 2023 +0200 +++ b/ui/winui/text.h Sun Nov 26 15:44:28 2023 +0100 @@ -33,6 +33,32 @@ #include "../ui/container.h" +struct UiPathTextField { + winrt::Microsoft::UI::Xaml::Controls::Grid grid = { nullptr }; + winrt::Microsoft::UI::Xaml::Controls::StackPanel buttons = { nullptr }; + winrt::Microsoft::UI::Xaml::Controls::TextBox textbox = { nullptr }; + winrt::Microsoft::UI::Xaml::Controls::TextBlock filler = { nullptr }; + + ~UiPathTextField(); + + UiPathElm* current_path = nullptr; + size_t current_path_nelms = 0; + + UiObject* obj; + + ui_pathelm_func getpathelm; + void* getpathelmdata; + + ui_callback onactivate; + void* onactivatedata; + + ui_callback ondragstart; + void* ondragstartdata; + ui_callback ondragcomplete; + void* ondragcompletedata; + ui_callback ondrop; + void* ondropdata; +}; char* ui_string_get(UiString* str, std::wstring& value); std::wstring ui_string_set(UiString* str, const char* value); @@ -42,3 +68,6 @@ extern "C" char* ui_passwordfield_get(UiString * str); extern "C" void ui_passwordfield_set(UiString * str, const char* newvalue); + +extern "C" char* ui_path_textfield_get(UiString * str); +extern "C" void ui_path_textfield_set(UiString * str, const char* newvalue);