[Bf-blender-cvs] [a156360] ui-align-rework: Split align group code into its own file.

Bastien Montagne noreply at git.blender.org
Fri Nov 6 18:37:18 CET 2015


Commit: a156360fdfb4f6c43d6b3ebff6dece0847f2d6d9
Author: Bastien Montagne
Date:   Fri Nov 6 18:27:15 2015 +0100
Branches: ui-align-rework
https://developer.blender.org/rBa156360fdfb4f6c43d6b3ebff6dece0847f2d6d9

Split align group code into its own file.

interface.c is becomming a bit too fat...

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

M	source/blender/editors/interface/CMakeLists.txt
M	source/blender/editors/interface/interface.c
A	source/blender/editors/interface/interface_align.c

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

diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 3efb492..c57f8d5 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -40,6 +40,7 @@ set(INC_SYS
 
 set(SRC
 	interface.c
+	interface_align.c
 	interface_anim.c
 	interface_draw.c
 	interface_eyedropper.c
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index f988114..947ba9c 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -42,7 +42,6 @@
 #include "DNA_screen_types.h"
 #include "DNA_userdef_types.h"
 
-#include "BLI_alloca.h"
 #include "BLI_math.h"
 #include "BLI_listbase.h"
 #include "BLI_string.h"
@@ -2945,622 +2944,6 @@ void UI_block_align_end(uiBlock *block)
 	block->flag &= ~UI_BUT_ALIGN;  /* all 4 flags */
 }
 
-#ifdef USE_UIBUT_SPATIAL_ALIGN
-
-/**
- * This struct stores a (simplified) 2D representation of all buttons of a same align group, with their
- * immediate neighbors (if found), and needed value to compute 'stitching' of aligned buttons.
- *
- * \note This simplistic struct cannot fully represent complex layouts where buttons share some 'align space' with
- *       several others (see schema below), we'd need linked list and more complex code to handle that.
- *       However, looks like we can do without that for now, which is rather lucky!
- *
- *       <pre>
- *       +-----------+-----------+
- *       |   BUT 1   |   BUT 2   |      BUT 3 has two 'top' neighbors...
- *       |-----------------------|  =>  In practice, we only store one of BUT 1 or 2 (which ones is not
- *       |         BUT 3         |      really deterministic), and assume the other stores a ref to BUT 3.
- *       +-----------------------+
- *       </pre>
- *
- *       This will probably not work in all possible cases, but not sure we want to support such exotic cases anyway.
- */
-typedef struct ButAlign {
-	uiBut *but;
-
-	/* Neighbor buttons */
-	struct ButAlign *neighbors[4];
-
-	/* Pointers to coordinates (rctf values) of the button. */
-	float *borders[4];
-
-	/* Distances to the neighbors. */
-	float dists[4];
-
-	/* Flags, used to mark whether we should 'stitch' the corners of this button with its neighbors' ones. */
-	char flags[4];
-} ButAlign;
-
-/* Side-related enums and flags. */
-enum {
-	/* Sides (used as indices, order is **crucial**, this allows us to factorize code in a loop over the four sides). */
-	LEFT         = 0,
-	TOP          = 1,
-	RIGHT        = 2,
-	DOWN         = 3,
-	TOTSIDES     = 4,
-
-	/* Stitch flags, built from sides values. */
-	STITCH_LEFT  = 1 << LEFT,
-	STITCH_TOP   = 1 << TOP,
-	STITCH_RIGHT = 1 << RIGHT,
-	STITCH_DOWN  = 1 << DOWN,
-};
-
-/* Mapping between 'our' sides and 'public' UI_BUT_ALIGN flags, order must match enum above. */
-#define SIDE_TO_UI_BUT_ALIGN {UI_BUT_ALIGN_LEFT, UI_BUT_ALIGN_TOP, UI_BUT_ALIGN_RIGHT, UI_BUT_ALIGN_DOWN}
-
-/* Given one side, compute the three other ones */
-#define SIDE1(_s) (((_s) + 1) % TOTSIDES)
-#define OPPOSITE(_s) (((_s) + 2) % TOTSIDES)
-#define SIDE2(_s) (((_s) + 3) % TOTSIDES)
-
-/* 0: LEFT/RIGHT sides; 1 = TOP/DOWN sides. */
-#define IS_COLUMN(_s) ((_s) % 2)
-
-/* Stich flag from side value. */
-#define STITCH(_s) (1 << (_s))
-
-/* Max distance between to buttons for them to be 'mergeable'. */
-#define MAX_DELTA 0.45f * max_ii(UI_UNIT_Y, UI_UNIT_X)
-
-bool ui_but_can_align(uiBut *but)
-{
-	return !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE);
-}
-
-/**
- * This function checks a pair of buttons (assumed in a same align group), and if they are neighbors,
- * set needed data accordingly.
- *
- * \note It is designed to be called in total random order of buttons. Order-based optimizations are done by caller.
- */
-static void block_align_proximity_compute(ButAlign *butal, ButAlign *butal_other)
-{
-	/* That's the biggest gap between two borders to consider them 'alignable'. */
-	const float max_delta = MAX_DELTA;
-	float delta;
-	int side;
-
-	const bool butal_can_align = ui_but_can_align(butal->but);
-	const bool butal_other_can_align = ui_but_can_align(butal_other->but);
-
-	const bool buts_share[2] = {
-	    /* Sharing same line? */
-	    !((*butal->borders[DOWN] >= *butal_other->borders[TOP]) ||
-	      (*butal->borders[TOP] <= *butal_other->borders[DOWN])),
-	    /* Sharing same column? */
-	    !((*butal->borders[LEFT] >= *butal_other->borders[RIGHT]) ||
-	      (*butal->borders[RIGHT] <= *butal_other->borders[LEFT])),
-	};
-
-	/* Early out in case buttons share no column or line, or if none can align... */
-	if (!(buts_share[0] || buts_share[1]) || !(butal_can_align || butal_other_can_align)) {
-		return;
-	}
-
-	for (side = 0; side < TOTSIDES; side++) {
-		/* We are only interested in buttons which share a same line (LEFT/RIGHT sides) or column (TOP/DOWN sides). */
-		if (buts_share[IS_COLUMN(side)]) {
-			const int side_opp = OPPOSITE(side);
-
-			/* We rely on exact zero value here as an 'already processed' flag, so ensure we never actually
-			 * set a zero value at this stage. FLT_MIN is zero-enough for UI position computing. ;) */
-			delta = max_ff(fabsf(*butal->borders[side] - *butal_other->borders[side_opp]), FLT_MIN);
-			if (delta < max_delta) {
-				/* We are only interested in neighbors that are at least as close as already found ones. */
-				if (delta <= butal->dists[side]) {
-					if (delta <= butal->dists[side]) {
-						/* We found a closer neighbor.
-						 * If both buttons are alignable, we set them as each other neighbors.
-						 * Else, we have an unalignable one, we need to reset the other's matching neighbor to NULL
-						 * if its 'proximity distance' is really lower with current one. */
-						if (butal_can_align && butal_other_can_align) {
-							butal->neighbors[side] = butal_other;
-							butal_other->neighbors[side_opp] = butal;
-						}
-						else if (butal_can_align && (delta < butal->dists[side])) {
-							butal->neighbors[side] = NULL;
-						}
-						else if (butal_other_can_align && (delta < butal_other->dists[side_opp])) {
-							butal_other->neighbors[side_opp] = NULL;
-						}
-						butal->dists[side] = butal_other->dists[side_opp] = delta;
-					}
-					if (butal_can_align && butal_other_can_align) {
-						const int side_s1 = SIDE1(side);
-						const int side_s2 = SIDE2(side);
-
-						const int stitch = STITCH(side);
-						const int stitch_opp = STITCH(side_opp);
-
-						if (butal->neighbors[side] == NULL) {
-							butal->neighbors[side] = butal_other;
-						}
-						if (butal_other->neighbors[side_opp] == NULL) {
-							butal_other->neighbors[side_opp] = butal;
-						}
-
-						/* We have a pair of neighbors, we have to check whether we can stitch their matching corners.
-						 *   E.g. if butal_other is on the left of butal (that is, side == LEFT),
-						 *        if both TOP (side_s1) coordinates of buttons are close enough, we can stitch
-						 *        their upper matching corners, and same for DOWN (side_s2) side. */
-						delta = fabsf(*butal->borders[side_s1] - *butal_other->borders[side_s1]);
-						if (delta < max_delta) {
-							butal->flags[side_s1] |= stitch;
-							butal_other->flags[side_s1] |= stitch_opp;
-						}
-						delta = fabsf(*butal->borders[side_s2] - *butal_other->borders[side_s2]);
-						if (delta < max_delta) {
-							butal->flags[side_s2] |= stitch;
-							butal_other->flags[side_s2] |= stitch_opp;
-						}
-					}
-				}
-				/* We assume two buttons can only share one side at most - for until we have sperical UI... */
-				return;
-			}
-		}
-	}
-}
-
-/**
- * This function takes care of case described in this schema:
- *
- * <pre>
- * +-----------+-----------+
- * |   BUT 1   |   BUT 2   |
- * |-----------------------+
- * |   BUT 3   |
- * +-----------+
- * </pre>
- *
- * Here, BUT 3 RIGHT side would not get 'dragged' to align with BUT 1 RIGHT side, since BUT 3 has not RIGHT neighbor.
- * So, this function, when called with BUT 1, will 'walk' the whole column in \a side_s1 direction (TOP or DOWN when
- * called for RIGHT side), and force buttons like BUT 3 to align as needed, if BUT 1 and BUT 3 were detected as needing
- * top-right corner stitching in \a block_align_proximity_compute() step.
- *
- * \note To avoid doing this twice, some stitching flags are cleared to break the 'stitching connection'
- *       between neighbors.
- */
-static void block_align_stitch_neighbors(
-        ButAlign *butal,
-        const int side, const int side_opp, const int side_s1, const int side_s2,
-        const int align, const int align_opp, const float co)
-{
-	ButAlign *butal_neighbor;
-
-	const int stitch_s1 = STITCH(side_s1);
-	const int stitch_s2 = STITCH(side_s2);
-
-//	printf("%s (%d) (%f, %f)\n", butal->but->str[0] ? butal->but->str : "<noname>", i, *butal->borders[i], *butal->borders[i_opp]);
-//	if (STREQ(butal->but->str, "Frame Step: ")) {
-//		printf("%s: main side %d, stride side %d: %f\n", butal->but->str, i, i_s1, butal->dists[i]);
-//	}
-
-	/* We have to check stitching flags on both sides of the stitching, since we only clear one of them flags to break
-	 * any future loop on same 'columns/side' case.
-     * Also, if butal is spanning over several rows or columns of neighbors, it may have both of its  stiching flags
-     * set, but would not be the case of its immediate neighbor! */
-	while ((butal->flags[side] & stitch_s1) &&
-	       (butal = butal->neighbors[side_s1]) &&
-	       (butal->flags[side] & stitch_s2))
-	{
-		butal_neighbor = butal->neighbors[side];
-
-		/* If we actually do have a neighbor, we directly set its values accordingly, and clear its matching 'dist'
-		 * to prevent it being set again later... */
-		if (butal_neighbor) {
-			butal->but->drawflag |= align;
-			butal_neighbor->but->drawflag |= align_opp;
-			*butal_neighbor->borders[side_opp] = co;
-			butal_neighbor->dists[side_opp] = 0.0f;
-		}
-		/* See definition of UI_BUT_ALIGN_STITCH_LEFT/TOP for reason of this... */
-		else if (side == LEFT) {
-			butal->but->drawflag |= UI_BUT_ALIGN_STITCH_LEFT;
-		}
-		else if (side == TOP)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list