[Bf-blender-cvs] [341dbce] ui_layout_gridflow: Painfully enhanced columns/rows computation to make best use of available space.

Bastien Montagne noreply at git.blender.org
Sun Dec 4 12:46:01 CET 2016


Commit: 341dbce1b7263d57fbd6590d23b27b8270d33d3f
Author: Bastien Montagne
Date:   Sat Dec 3 01:39:59 2016 +0100
Branches: ui_layout_gridflow
https://developer.blender.org/rB341dbce1b7263d57fbd6590d23b27b8270d33d3f

Painfully enhanced columns/rows computation to make best use of available space.

Now layout will use less columns than possible, if it does not increase
number of rows. Allows to fill more evenly available space.

Also fixed some quirks and corner-cases issues.

===================================================================

M	release/scripts/startup/bl_ui/properties_data_mesh.py
M	release/scripts/startup/bl_ui/properties_texture.py
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/makesrna/intern/rna_ui_api.c
M	source/blenderplayer/bad_level_call_stubs/stubs.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 23072f4..c10c2cd 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -212,35 +212,31 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
             col.separator()
             col.operator("object.vertex_group_move", icon='TRIA_UP', text="").direction = 'UP'
             col.operator("object.vertex_group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
-        """
-        col = layout.column(align=True)
-        for vg in ob.vertex_groups:
-            col.prop(vg, "name", text="")
-
-        layout.separator()
 
-        gflow = layout.grid_flow(row_major=True, num_columns=0, align=False, even_columns=False, even_rows=False)
+        box = layout.box()
+        box.label(text="Row, auto, col_tweak 2")
+        gflow = box.grid_flow(row_major=True, num_columns=0, even_columns=False, even_rows=False, align=False)
         for vg in ob.vertex_groups:
             gflow.prop(vg, "name", text="")
             gflow.prop(vg, "lock_weight")
 
-        layout.separator()
-
-        gflow = layout.grid_flow(row_major=False, num_columns=0, align=False, even_columns=False, even_rows=False)
+        box = layout.box()
+        box.label(text="Col, auto, col_tweak 2")
+        gflow = box.grid_flow(row_major=False, num_columns=0, even_columns=False, even_rows=False, align=False)
         for vg in ob.vertex_groups:
             gflow.prop(vg, "name", text="")
             gflow.prop(vg, "lock_weight")
 
-        layout.separator()
-
-        gflow = layout.grid_flow(row_major=True, num_columns=-2, align=True, even_columns=False, even_rows=False)
+        box = layout.box()
+        box.label(text="Row, auto % 2, col_tweak 2")
+        gflow = box.grid_flow(row_major=True, num_columns=-2, even_columns=False, even_rows=False, align=False)
         for vg in ob.vertex_groups:
             gflow.prop(vg, "name", text="")
             gflow.prop(vg, "lock_weight")
 
-        layout.separator()
-        """
-        gflow = layout.grid_flow(row_major=False, num_columns=-2, align=True, even_columns=False, even_rows=False)
+        box = layout.box()
+        box.label(text="Col, auto % 2, col_tweak 2")
+        gflow = box.grid_flow(row_major=False, num_columns=-2, even_columns=False, even_rows=False, align=False)
         for vg in ob.vertex_groups:
             gflow.prop(vg, "name", text="")
             gflow.prop(vg, "lock_weight")
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index c431e3d..31c7b67 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -1096,7 +1096,7 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
                 box = layout.box()
                 box.label(text="¡GRID FLOW LAYOUT!")
 
-                gflow = box.grid_flow(row_major=True, num_columns=0, align=False, even_columns=True, even_rows=False)
+                gflow = box.grid_flow(row_major=True, num_columns=0, even_columns=True, even_rows=False, align=False)
 
                 col = gflow.column()
                 col.label(text="Diffuse:")
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index a309c1e..384fa74 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -893,7 +893,8 @@ float uiLayoutGetScaleY(uiLayout *layout);
 uiLayout *uiLayoutRow(uiLayout *layout, int align);
 uiLayout *uiLayoutColumn(uiLayout *layout, int align);
 uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align);
-uiLayout *uiLayoutGridFlow(uiLayout *layout, int row_major, int num_columns, int align, int even_columns, int even_rows);
+uiLayout *uiLayoutGridFlow(
+        uiLayout *layout, int row_major, int num_columns, int even_columns, int even_rows, int align);
 uiLayout *uiLayoutBox(uiLayout *layout);
 uiLayout *uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct PointerRNA *ptr, struct PropertyRNA *prop,
                           struct PointerRNA *actptr, struct PropertyRNA *actprop);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index d376d4b..4656332 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -159,7 +159,12 @@ typedef struct uiLayoutItemGridFlow {
 	uiLayout litem;
 
 	/* Extra parameters */
-	bool row_major, even_columns, even_rows;
+	bool row_major;     /* Fill first row first, instead of filling first column first. */
+	bool even_columns;  /* Same width for all columns. */
+	bool even_rows;     /* Same height for all rows. */
+	/* If positive, absolute fixed number of columns.
+	 * If 0, fully automatic (based on available width).
+	 * If negative, automatic but only generates number of columns/rows multiple of given (absolute) value. */
 	int num_columns;
 
 	/* Pure internal runtime storage. */
@@ -2547,13 +2552,23 @@ static void ui_litem_grid_flow_compute(
 	float *avg_w = NULL, *totweight_w = NULL;
 	int *max_h = NULL;
 
-	BLI_assert(tot_cols != 0 || (r_cos_x == NULL && r_widths == NULL));
-	BLI_assert(tot_rows != 0 || (r_cos_y == NULL && r_heights == NULL));
+	BLI_assert(tot_cols != 0 || (r_cos_x == NULL && r_widths == NULL && r_tot_w == NULL));
+	BLI_assert(tot_rows != 0 || (r_cos_y == NULL && r_heights == NULL && r_tot_h == NULL));
 
 	if (r_tot_items) {
 		*r_tot_items = 0;
 	}
 
+	if (items->first == NULL) {
+		if (r_global_avg_w) {
+			*r_global_avg_w = 0.0f;
+		}
+		if (r_global_max_h) {
+			*r_global_max_h = 0;
+		}
+		return;
+	}
+
 	if (tot_cols != 0) {
 		avg_w = alloca(sizeof(*avg_w) * tot_cols);
 		totweight_w = alloca(sizeof(*totweight_w) * tot_cols);
@@ -2674,6 +2689,12 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem)
 		        &avg_w, 0, NULL, NULL, NULL,
 		        &max_h, 0, NULL, NULL, NULL);
 
+		if (gflow->tot_items == 0) {
+			litem->w = litem->h = 0;
+			gflow->tot_columns = gflow->tot_rows = 0;
+			return;
+		}
+
 		/* Even in varying column width case, we fix our columns number from weighted average width of items,
 		 * a proper solving of required width would be too costly, and this should give reasonably good results
 		 * in all resonable cases... */
@@ -2688,22 +2709,40 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem)
 				gflow->tot_columns = min_ii(max_ii((int)(litem->w / avg_w), 1), gflow->tot_items);
 			}
 		}
+		gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
 
-		/* In column major case, we may need to adjust number of columns, e.g. with 8 items, if we auto-compute
-		 * 5 columns, we can only actually fill 4 of them (since we need 2 rows anyway)... */
-		if (!gflow->row_major && gflow->num_columns <= 0) {
-			gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
-			gflow->tot_columns = (int)ceilf((float)gflow->tot_items / gflow->tot_rows);
-		}
+		/* Try to tweak number of columns and rows to get better filling of last column or row,
+		 * and apply 'modulo' value to number of columns or rows.
+		 * Note that modulo does not prevent ending with fewer columns/rows than modulo, if mandatory
+		 * to avoid empty column/row. */
+		{
+			const int modulo = (gflow->num_columns < -1) ? -gflow->num_columns : 0;
+			const int step = modulo ? modulo : 1;
 
-		/* 'Modulo' number of columns as last step. */
-		if (gflow->num_columns < -1) {
-			const int modulo = -gflow->num_columns;
-			gflow->tot_columns = max_ii(modulo, gflow->tot_columns - (gflow->tot_columns % modulo));
+			if (gflow->row_major) {
+				/* Adjust number of columns to be mutiple of given modulo. */
+				if (modulo && gflow->tot_columns % modulo != 0 && gflow->tot_columns > modulo) {
+					gflow->tot_columns = gflow->tot_columns - (gflow->tot_columns % modulo);
+				}
+				/* Find smallest number of columns conserving computed optimal number of rows. */
+				for (gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
+				     (gflow->tot_columns - step) > 0 &&
+				     (int)ceilf((float)gflow->tot_items / (gflow->tot_columns - step)) <= gflow->tot_rows;
+				     gflow->tot_columns -= step);
+			}
+			else {
+				/* Adjust number of rows to be mutiple of given modulo. */
+				if (modulo && gflow->tot_rows % modulo != 0) {
+					gflow->tot_rows = min_ii(gflow->tot_rows + modulo - (gflow->tot_rows % modulo), gflow->tot_items);
+				}
+				/* Find smallest number of rows conserving computed optimal number of columns. */
+				for (gflow->tot_columns = (int)ceilf((float)gflow->tot_items / gflow->tot_rows);
+				     (gflow->tot_rows - step) > 0 &&
+				     (int)ceilf((float)gflow->tot_items / (gflow->tot_rows - step)) <= gflow->tot_columns;
+				     gflow->tot_rows -= step);
+			}
 		}
 
-		gflow->tot_rows = max_ii((int)ceilf((float)gflow->tot_items / gflow->tot_columns), 1);
-
 		/* Set evenly-spaced axes size (quick optimization in case we have even columns and rows). */
 		if (gflow->even_columns && gflow->even_rows) {
 			litem->w = (int)(gflow->tot_columns * avg_w) + space_x * (gflow->tot_columns - 1);
@@ -2735,6 +2774,14 @@ static void ui_litem_layout_grid_flow(uiLayout *litem)
 	uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem;
 	uiItem *item;
 
+	if (gflow->tot_items == 0) {
+		litem->w = litem->h = 0;
+		return;
+	}
+
+	BLI_assert(gflow->tot_columns > 0);
+	BLI_assert(gflow->tot_rows > 0);
+
 	const int space_x = style->columnspace;
 	const int space_y = style->buttonspacey;
 
@@ -3001,7 +3048,8 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
 	return &flow->litem;
 }
 
-uiLayout *uiLayoutGridFlow(uiLayout *layout, int row_major, int num_columns, int align, int even_columns, int even_rows)
+uiLayout *uiLayoutGridFlow(
+        uiLayout *layout, int row_major, int num_columns, int even_columns, int even_rows, int align)
 {
 	uiLayoutItemGridFlow *flow;
 
diff --git a/source/blender/makesrna/inter

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list