# HG changeset patch # User Olaf Wintermann # Date 1696329417 -7200 # Node ID f2332d0d33180d18c41908d6c6d53c7cae090aa5 # Parent 8a82ebe23822ee2d449a8f8f94fd0528f67cb19f add tabview based on winui the pivot control diff -r 8a82ebe23822 -r f2332d0d3318 make/vs/testapp/main.c --- a/make/vs/testapp/main.c Mon Oct 02 19:56:18 2023 +0200 +++ b/make/vs/testapp/main.c Tue Oct 03 12:36:57 2023 +0200 @@ -136,10 +136,12 @@ ui_passwordfield(obj, .value = wdata->password); ui_newline(obj); + /* ui_frame(obj, .label = "Test", .colspan = 3) { ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); } ui_newline(obj); + */ /* ui_expander(obj, .label = "Expand", .colspan = 3, .margin = 10, .spacing = 5, .isexpanded = false) { @@ -150,6 +152,16 @@ */ ui_combobox(obj, .list = wdata->list, .onselection= action_listselection_changed, .onactivate= action_onactivate); + ui_newline(obj); + + ui_tabview(obj, .colspan = 3, .vexpand = true, .hexpand = true) { + ui_tab(obj, "Tab 1") { + ui_button(obj, .label = "Tab 1 Button"); + } + ui_tab(obj, "Tab 2") { + ui_button(obj, .label = "Tab 2 Button"); + } + } } } diff -r 8a82ebe23822 -r f2332d0d3318 ui/ui/container.h --- a/ui/ui/container.h Mon Oct 02 19:56:18 2023 +0200 +++ b/ui/ui/container.h Tue Oct 03 12:36:57 2023 +0200 @@ -41,6 +41,15 @@ UI_CONTAINER_GRID } UiSubContainerType; +typedef enum UiTabViewType { + UI_TABVIEW_DEFAULT = 0, + UI_TABVIEW_DOC, + UI_TABVIEW_NAVIGATION_SIDE, + UI_TABVIEW_NAVIGATION_TOP, + UI_TABVIEW_NAVIGATION_TOP2, + UI_TABVIEW_INVISIBLE +} UiTabViewType; + typedef struct UiContainerArgs { UiTri fill; UiBool hexpand; @@ -72,6 +81,27 @@ UiBool isexpanded; } UiFrameArgs; +typedef struct UiTabViewArgs { + UiTri fill; + UiBool hexpand; + UiBool vexpand; + int colspan; + int rowspan; + + UiTabViewType tabview; + + UiSubContainerType subcontainer; + + int margin; + int spacing; + int columnspacing; + int rowspacing; + + const char* label; + UiBool isexpanded; +} UiTabViewArgs; + + #define UI_CTN(obj, ctn) for(ctn;ui_container_finish(obj);ui_container_begin_close(obj)) @@ -81,6 +111,7 @@ #define ui_frame(obj, ...) for(ui_frame_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj)) #define ui_expander(obj, ...) for(ui_expander_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj)) #define ui_scrolledwindow(obj, ...) for(ui_scrolledwindow_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj)) +#define ui_tabview(obj, ...) for(ui_tabview_create(obj, (UiTabViewArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj)) #define ui_vbox0(obj) for(ui_vbox_create(obj, (UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj)) #define ui_hbox0(obj) for(ui_hbox_create(obj, (UiContainerArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj)) @@ -88,6 +119,9 @@ #define ui_frame0(obj) for(ui_frame_create(obj, (UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj)) #define ui_expander0(obj) for(ui_expande_create(obj, (UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj)) #define ui_scrolledwindow0(obj) for(ui_scrolledwindow_create(obj, (UiFrameArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj)) +#define ui_tabview0(obj) for(ui_tabview_create(obj, (UiTabViewArgs){ 0 });ui_container_finish(obj);ui_container_begin_close(obj)) + +#define ui_tab(obj, label) for(ui_tab_create(obj, label);ui_container_finish(obj);ui_container_begin_close(obj)) void ui_end(UiObject *obj); @@ -97,7 +131,9 @@ UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args); UIWIDGET ui_expander_create(UiObject* obj, UiFrameArgs args); UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs args); +UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args); +void ui_tab_create(UiObject* obj, const char* title); UIWIDGET ui_scrolledwindow_deprecated(UiObject *obj); @@ -106,8 +142,8 @@ UIWIDGET ui_hsplitpane(UiObject *obj, int max); UIWIDGET ui_vsplitpane(UiObject *obj, int max); -UIWIDGET ui_tabview(UiObject *obj); -void ui_tab(UiObject *obj, char *title); +UIWIDGET ui_tabview_deprecated(UiObject *obj); + void ui_select_tab(UIWIDGET tabview, int tab); // box container layout functions diff -r 8a82ebe23822 -r f2332d0d3318 ui/winui/container.cpp --- a/ui/winui/container.cpp Mon Oct 02 19:56:18 2023 +0200 +++ b/ui/winui/container.cpp Tue Oct 03 12:36:57 2023 +0200 @@ -305,19 +305,19 @@ // sub container UiContainer* ctn = nullptr; switch (args.subcontainer) { - default: - case UI_CONTAINER_VBOX: { - ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_VBOX, args.margin, args.spacing); - break; - } - case UI_CONTAINER_HBOX: { - ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_HBOX, args.margin, args.spacing); - break; - } - case UI_CONTAINER_GRID: { - ctn = new UiGridContainer(workarea, args.margin, args.columnspacing, args.rowspacing); - break; - } + default: + case UI_CONTAINER_VBOX: { + ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_VBOX, args.margin, args.spacing); + break; + } + case UI_CONTAINER_HBOX: { + ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_HBOX, args.margin, args.spacing); + break; + } + case UI_CONTAINER_GRID: { + ctn = new UiGridContainer(workarea, args.margin, args.columnspacing, args.rowspacing); + break; + } } UiObject* newobj = uic_object_new(obj, widget); @@ -414,6 +414,106 @@ return widget; } +// --------------------- UI TabView --------------------- + +UiTabViewContainer::UiTabViewContainer(UiTabView* tabview) { + this->tabview = tabview; +} + +void UiTabViewContainer::Add(FrameworkElement control, UiBool fill) { + // noop +} + +static UiObject* create_subcontainer_obj(UiObject* current, Grid subcontainer, UiSubContainerType type, int margin, int spacing, int columnspacing, int rowspacing) { + UiContainer* ctn = nullptr; + switch (type) { + default: + case UI_CONTAINER_VBOX: { + ctn = new UiBoxContainer(subcontainer, UI_BOX_CONTAINER_VBOX, margin, spacing); + break; + } + case UI_CONTAINER_HBOX: { + ctn = new UiBoxContainer(subcontainer, UI_BOX_CONTAINER_HBOX, margin, spacing); + break; + } + case UI_CONTAINER_GRID: { + ctn = new UiGridContainer(subcontainer, margin, columnspacing, rowspacing); + break; + } + } + + UIElement elm = subcontainer; + UiWidget* widget = new UiWidget(elm); + UiObject* newobj = uic_object_new(current, widget); + newobj->container = ctn; + return newobj; +} + +UiPivotTabView::UiPivotTabView(UiObject* obj, Pivot pivot, UiTabViewArgs args) { + this->current = obj; + this->pivot = pivot; + this->margin = args.margin; + this->spacing = args.spacing; + this->columnspacing = args.columnspacing; + this->rowspacing = args.rowspacing; +} + +UiObject* UiPivotTabView::AddTab(const char* label) { + TextBlock text = TextBlock(); + wchar_t* wlabel = str2wstr(label, nullptr); + winrt::hstring hstr(wlabel); + text.Text(hstr); + free(wlabel); + + PivotItem item = PivotItem(); + item.Header(text); + + // sub container + Grid subcontainer = Grid(); + item.Content(subcontainer); + pivot.Items().Append(item); + + return create_subcontainer_obj(current, subcontainer, this->subcontainer, margin, spacing, columnspacing, rowspacing); +} + +FrameworkElement UiPivotTabView::GetFrameworkElement() { + return pivot; +} + +static UiTabView* tabview_pivot_create(UiObject* obj, UiTabViewArgs args) { + Pivot pivot = Pivot(); + UiPivotTabView* tabview = new UiPivotTabView(obj, pivot, args); + + return tabview; +} + +UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) { + UiTabViewType type = args.tabview == UI_TABVIEW_DEFAULT ? UI_TABVIEW_NAVIGATION_TOP2 : args.tabview; + UiTabView *tabview = tabview_pivot_create(obj, args); + UiTabViewContainer* ctn = new UiTabViewContainer(tabview); + + // add frame to the parent container + UiObject* current = uic_current_obj(obj); + UI_APPLY_LAYOUT1(current, args); + current->container->Add(tabview->GetFrameworkElement(), true); + + UIElement elm = tabview->GetFrameworkElement(); + UiWidget* widget = new UiWidget(elm); + widget->data1 = tabview; + + UiObject* newobj = uic_object_new(obj, widget); + newobj->container = ctn; + uic_obj_add(obj, newobj); + + return widget; +} + +void ui_tab_create(UiObject* obj, const char* title) { + UiObject* current = uic_current_obj(obj); + UiTabView* tabview = (UiTabView*)current->widget->data1; + UiObject* newobj = tabview->AddTab(title); + uic_obj_add(current, newobj); +} /* * -------------------- Layout Functions -------------------- diff -r 8a82ebe23822 -r f2332d0d3318 ui/winui/container.h --- a/ui/winui/container.h Mon Oct 02 19:56:18 2023 +0200 +++ b/ui/winui/container.h Tue Oct 03 12:36:57 2023 +0200 @@ -106,3 +106,34 @@ void Add(FrameworkElement control, UiBool fill); }; + +struct UiTabView { + UiObject* current; + int close = 0; + + virtual UiObject* AddTab(const char* label) = 0; + + virtual FrameworkElement GetFrameworkElement() = 0; +}; + +struct UiTabViewContainer : UiContainer { + UiTabView* tabview; + + UiTabViewContainer(UiTabView* tabview); + + void Add(FrameworkElement control, UiBool fill); +}; + +struct UiPivotTabView : UiTabView { + Pivot pivot; + UiSubContainerType subcontainer; + int margin; + int spacing; + int columnspacing; + int rowspacing; + + UiPivotTabView(UiObject *obj, Pivot pivot, UiTabViewArgs args); + + UiObject* AddTab(const char* label); + FrameworkElement GetFrameworkElement(); +};