add tabview based on winui the pivot control newapi

Tue, 03 Oct 2023 12:36:57 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 03 Oct 2023 12:36:57 +0200
branch
newapi
changeset 198
f2332d0d3318
parent 197
8a82ebe23822
child 199
84e0a24bab4a

add tabview based on winui the pivot control

make/vs/testapp/main.c file | annotate | diff | comparison | revisions
ui/ui/container.h file | annotate | diff | comparison | revisions
ui/winui/container.cpp file | annotate | diff | comparison | revisions
ui/winui/container.h file | annotate | diff | comparison | revisions
--- 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");
+                }
+            }
         }
     }   
 
--- 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
--- 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 --------------------
--- 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();
+};

mercurial