implement grid container (WinUI) newapi

Sun, 24 Sep 2023 12:03:57 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 24 Sep 2023 12:03:57 +0200
branch
newapi
changeset 185
4a8b1a748f09
parent 184
8c9b4b28aaa9
child 186
5db4979bf482

implement grid container (WinUI)

make/vs/testapp/main.c 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	Sat Sep 23 15:41:23 2023 +0200
+++ b/make/vs/testapp/main.c	Sun Sep 24 12:03:57 2023 +0200
@@ -42,9 +42,27 @@
 void application_startup(UiEvent* event, void* data) {
     UiObject* obj = ui_window("Test", NULL);
 
+    /*
     ui_button(obj, "Button1", action1, "action1");
     ui_button(obj, "Button2", action1, "action2");
+    ui_layout_fill(obj, TRUE);
     ui_button(obj, "Button3", action1, "action3");
+    */
+
+    UI_GRID_SP(obj, 10, 5, 20) {
+        ui_button(obj, "Button1", action1, "action1");
+        ui_button(obj, "Button2", action1, "action2");
+        ui_layout_hexpand(obj, 1);
+        ui_button(obj, "Button3", action1, "action3");
+        ui_newline(obj);
+
+        ui_button(obj, "Button4", action1, "action4");
+        ui_layout_gridwidth(obj, 2);
+        ui_button(obj, "Button5_", action1, "action5");
+        ui_newline(obj);
+
+        ui_button(obj, "Very Long Button Label Text ____________ Test", action1, "test");
+    }
 
     ui_show(obj);
 }
--- a/ui/winui/container.cpp	Sat Sep 23 15:41:23 2023 +0200
+++ b/ui/winui/container.cpp	Sun Sep 24 12:03:57 2023 +0200
@@ -28,23 +28,55 @@
 
 #include "container.h"
 
+#include "../common/context.h"
+#include "../common/object.h"
+
+
+void ui_container_begin_close(UiObject* obj) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->close = 1;
+}
+
+int ui_container_finish(UiObject* obj) {
+	UiContainer* ct = uic_get_current_container(obj);
+	if (ct->close) {
+		ui_end(obj);
+		return 0;
+	}
+	return 1;
+}
+
+
+// --------------------- UiBoxContainer ---------------------
 
 UiBoxContainer::UiBoxContainer(Grid grid, enum UiBoxContainerType type) {
 	this->grid = grid;
 	this->type = type;
 
+	GridLength gl;
+	gl.Value = 1;
+	gl.GridUnitType = GridUnitType::Star;
+
 	// hbox needs one row def, vbox needs one col def
 	// all other col/row defs are created when elements are added
 	if (type == UI_CONTAINER_HBOX) {
-		RowDefinition rowdef = RowDefinition();
-		grid.RowDefinitions().Append(rowdef);
+		boxRowDef = RowDefinition();
+		boxRowDef.Height(gl);
+		grid.RowDefinitions().Append(boxRowDef);
 	} else {
-		ColumnDefinition coldef = ColumnDefinition();
-		grid.ColumnDefinitions().Append(coldef);
+		boxColDef = ColumnDefinition();
+		boxColDef.Width(gl);
+		grid.ColumnDefinitions().Append(boxColDef);
 	}
+
+	ui_reset_layout(layout);
 }
 
-void UiBoxContainer::Add(Control control, UiBool fill) {
+void UiBoxContainer::Add(FrameworkElement control, UiBool fill) {
+	if (this->layout.fill != UI_LAYOUT_UNDEFINED) {
+		fill = ui_lb2bool(this->layout.fill);
+	}
+
 	GridLength gl;
 	if (fill) {
 		gl.Value = 1;
@@ -55,18 +87,155 @@
 		gl.GridUnitType = GridUnitType::Auto;
 	}
 	
+	control.HorizontalAlignment(HorizontalAlignment::Stretch);
+	control.VerticalAlignment(VerticalAlignment::Stretch);
+
 	if (type == UI_CONTAINER_HBOX) {
 		ColumnDefinition coldef = ColumnDefinition();
 		coldef.Width(gl);
 		grid.ColumnDefinitions().Append(coldef);
 		grid.SetColumn(control, grid.Children().Size());
+		grid.SetRow(control, 0);
 	} else {
 		RowDefinition rowdef = RowDefinition();
 		rowdef.Height(gl);
 		grid.RowDefinitions().Append(rowdef);
 		grid.SetRow(control, grid.Children().Size());
+		grid.SetColumn(control, 0);
 	}
 
 	grid.Children().Append(control);
+
+	ui_reset_layout(layout);
+}
+
+// --------------------- UiBoxContainer ---------------------
+
+UIWIDGET ui_grid(UiObject* obj) {
+	return ui_grid_sp(obj, 0, 0, 0);
+}
+
+UIWIDGET ui_grid_sp(UiObject* obj, int margin, int columnspacing, int rowspacing) {
+	UiContainer* ct = uic_get_current_container(obj);
+
+	Grid grid = Grid();
+	ct->Add(grid, true);
+
+	UIElement elm = grid;
+	UiWidget* widget = new UiWidget(elm);
+
+	UiObject* newobj = uic_object_new(obj, widget);
+	newobj->container = new UiGridContainer(grid, margin, columnspacing, rowspacing);
+	uic_obj_add(obj, newobj);
+
+	return widget;
+}
+
+UiGridContainer::UiGridContainer(Grid grid, int margin, int columnspacing, int rowspacing) {
+	this->grid = grid;
+	Thickness t = { (double)margin, (double)margin, (double)margin, (double)margin };
+	grid.Margin(t);
+	grid.ColumnSpacing((double)columnspacing);
+	grid.RowSpacing((double)rowspacing);
+	ui_reset_layout(layout);
 }
 
+void UiGridContainer::Add(FrameworkElement control, UiBool fill) {
+	GridLength gl;
+
+	int hexpand = FALSE;
+	int vexpand = FALSE;
+	if (layout.hexpand != UI_LAYOUT_UNDEFINED) {
+		hexpand = layout.hexpand;
+	}
+	if (layout.vexpand != UI_LAYOUT_UNDEFINED) {
+		vexpand = layout.vexpand;
+	}
+
+	// create new RowDefinition for the new line
+	if (layout.newline || y == -1) {
+		x = 0;
+		y++;
+		RowDefinition rowdef = RowDefinition();
+		if (vexpand) {
+			gl.GridUnitType = GridUnitType::Star;
+			gl.Value = 1;
+		}
+		else {
+			gl.GridUnitType = GridUnitType::Auto;
+			gl.Value = 0;
+		}
+		rowdef.Height(gl);
+		grid.RowDefinitions().Append(rowdef);
+	}
+
+	// create new columndefinition, if a new column is added
+	if (x == cols) {
+		if (hexpand) {
+			gl.GridUnitType = GridUnitType::Star;
+			gl.Value = 1;
+		}
+		else {
+			gl.GridUnitType = GridUnitType::Auto;
+			gl.Value = 0;
+		}
+		ColumnDefinition coldef = ColumnDefinition();
+		coldef.Width(gl);
+		grid.ColumnDefinitions().Append(coldef);
+		cols++;
+	}
+
+	// add control
+	control.HorizontalAlignment(HorizontalAlignment::Stretch);
+	control.VerticalAlignment(VerticalAlignment::Stretch);
+
+	if (layout.gridwidth > 0) {
+		grid.SetColumnSpan(control, layout.gridwidth);
+	}
+
+	grid.SetRow(control, y);
+	grid.SetColumn(control, x);
+	grid.Children().Append(control);
+
+	x++;
+
+	ui_reset_layout(layout);
+}
+
+/*
+ * -------------------- Layout Functions --------------------
+ *
+ * functions for setting layout attributes for the current container
+ *
+ */
+
+void ui_layout_fill(UiObject* obj, UiBool fill) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->layout.fill = ui_bool2lb(fill);
+}
+
+void ui_layout_hexpand(UiObject* obj, UiBool expand) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->layout.hexpand = expand;
+}
+
+void ui_layout_vexpand(UiObject* obj, UiBool expand) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->layout.vexpand = expand;
+}
+
+void ui_layout_width(UiObject* obj, int width) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->layout.width = width;
+}
+
+void ui_layout_gridwidth(UiObject* obj, int width) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->layout.gridwidth = width;
+}
+
+void ui_newline(UiObject* obj) {
+	UiContainer* ct = uic_get_current_container(obj);
+	ct->layout.newline = TRUE;
+}
+
--- a/ui/winui/container.h	Sat Sep 23 15:41:23 2023 +0200
+++ b/ui/winui/container.h	Sun Sep 24 12:03:57 2023 +0200
@@ -40,6 +40,11 @@
 #include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
 #include <winrt/Microsoft.UI.Xaml.Markup.h>
 
+
+#define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout))
+#define ui_lb2bool(b) ((b) == UI_LAYOUT_TRUE ? TRUE : FALSE)
+#define ui_bool2lb(b) ((b) ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE)
+
 typedef struct UiLayout UiLayout;
 typedef enum UiLayoutBool UiLayoutBool;
 
@@ -68,9 +73,9 @@
 
 struct UiContainer {
     UiLayout layout;
-    int close;
+    int close = 0;
 
-    virtual void Add(Control control, UiBool fill) = 0;
+    virtual void Add(FrameworkElement control, UiBool fill) = 0;
 };
 
 enum UiBoxContainerType {
@@ -81,8 +86,21 @@
 struct UiBoxContainer : UiContainer {
     Grid grid;
     enum UiBoxContainerType type;
+    RowDefinition boxRowDef;
+    ColumnDefinition boxColDef;
 
     UiBoxContainer(Grid grid, enum UiBoxContainerType type);
 
-    void Add(Control control, UiBool fill);
+    void Add(FrameworkElement control, UiBool fill);
 };
+
+struct UiGridContainer : UiContainer {
+    Grid grid;
+    int x = 0;
+    int y = -1;
+    int cols = 0;
+
+    UiGridContainer(Grid grid, int margin, int columnspacing, int rowspacing);
+
+    void Add(FrameworkElement control, UiBool fill);
+};

mercurial