Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/interface/interface_align.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/interface/interface_align.c')
-rw-r--r--source/blender/editors/interface/interface_align.c1152
1 files changed, 585 insertions, 567 deletions
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 9e1563e6511..61f9005ce44 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -55,77 +55,87 @@
* but not sure we want to support such exotic cases anyway.
*/
typedef struct ButAlign {
- uiBut *but;
+ uiBut *but;
- /* Neighbor buttons */
- struct ButAlign *neighbors[4];
+ /* Neighbor buttons */
+ struct ButAlign *neighbors[4];
- /* Pointers to coordinates (rctf values) of the button. */
- float *borders[4];
+ /* Pointers to coordinates (rctf values) of the button. */
+ float *borders[4];
- /* Distances to the neighbors. */
- float dists[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];
+ /* 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,
+ /* 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}
+# 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)
+# 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)
+# define IS_COLUMN(_s) ((_s) % 2)
/* Stitch flag from side value. */
-#define STITCH(_s) (1 << (_s))
+# 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)
+# define MAX_DELTA 0.45f * max_ii(UI_UNIT_Y, UI_UNIT_X)
bool ui_but_can_align(const uiBut *but)
{
- const bool btype_can_align = !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N,
- UI_BTYPE_TAB, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER);
- return (btype_can_align && (BLI_rctf_size_x(&but->rect) > 0.0f) && (BLI_rctf_size_y(&but->rect) > 0.0f));
+ const bool btype_can_align = !ELEM(but->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_CHECKBOX,
+ UI_BTYPE_CHECKBOX_N,
+ UI_BTYPE_TAB,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_SEPR_SPACER);
+ return (btype_can_align && (BLI_rctf_size_x(&but->rect) > 0.0f) &&
+ (BLI_rctf_size_y(&but->rect) > 0.0f));
}
int ui_but_align_opposite_to_area_align_get(const ARegion *ar)
{
- switch (ar->alignment) {
- case RGN_ALIGN_TOP:
- return UI_BUT_ALIGN_DOWN;
- case RGN_ALIGN_BOTTOM:
- return UI_BUT_ALIGN_TOP;
- case RGN_ALIGN_LEFT:
- return UI_BUT_ALIGN_RIGHT;
- case RGN_ALIGN_RIGHT:
- return UI_BUT_ALIGN_LEFT;
- }
-
- return 0;
+ switch (ar->alignment) {
+ case RGN_ALIGN_TOP:
+ return UI_BUT_ALIGN_DOWN;
+ case RGN_ALIGN_BOTTOM:
+ return UI_BUT_ALIGN_TOP;
+ case RGN_ALIGN_LEFT:
+ return UI_BUT_ALIGN_RIGHT;
+ case RGN_ALIGN_RIGHT:
+ return UI_BUT_ALIGN_LEFT;
+ }
+
+ return 0;
}
/**
@@ -136,114 +146,115 @@ int ui_but_align_opposite_to_area_align_get(const ARegion *ar)
*/
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, delta_side_opp;
- int side, side_opp;
-
- 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 < RIGHT; 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)]) {
- side_opp = OPPOSITE(side);
-
- /* We check both opposite sides at once, because with very small buttons,
- * delta could be below max_delta for the wrong side
- * (that is, in horizontal case, the total width of two buttons can be below max_delta).
- * 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);
- delta_side_opp = max_ff(fabsf(*butal->borders[side_opp] - *butal_other->borders[side]), FLT_MIN);
- if (delta_side_opp < delta) {
- SWAP(int, side, side_opp);
- delta = delta_side_opp;
- }
-
- 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]) {
- {
- /* We found an as close or 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 others matching
- * neighbor to NULL if its 'proximity distance'
- * is really lower with current one.
- *
- * NOTE: We cannot only execute that piece of code in case we found a
- * **closer** neighbor, due to the limited way we represent neighbors
- * (buttons only know **one** neighbor on each side, when they can
- * actually have several ones), it would prevent some buttons to be
- * properly 'neighborly-initialized'. */
- 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;
- }
- }
- }
+ /* That's the biggest gap between two borders to consider them 'alignable'. */
+ const float max_delta = MAX_DELTA;
+ float delta, delta_side_opp;
+ int side, side_opp;
+
+ 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 < RIGHT; 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)]) {
+ side_opp = OPPOSITE(side);
+
+ /* We check both opposite sides at once, because with very small buttons,
+ * delta could be below max_delta for the wrong side
+ * (that is, in horizontal case, the total width of two buttons can be below max_delta).
+ * 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);
+ delta_side_opp = max_ff(fabsf(*butal->borders[side_opp] - *butal_other->borders[side]),
+ FLT_MIN);
+ if (delta_side_opp < delta) {
+ SWAP(int, side, side_opp);
+ delta = delta_side_opp;
+ }
+
+ 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]) {
+ {
+ /* We found an as close or 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 others matching
+ * neighbor to NULL if its 'proximity distance'
+ * is really lower with current one.
+ *
+ * NOTE: We cannot only execute that piece of code in case we found a
+ * **closer** neighbor, due to the limited way we represent neighbors
+ * (buttons only know **one** neighbor on each side, when they can
+ * actually have several ones), it would prevent some buttons to be
+ * properly 'neighborly-initialized'. */
+ 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;
+ }
+ }
+ }
}
/**
@@ -265,47 +276,49 @@ static void block_align_proximity_compute(ButAlign *butal, ButAlign *butal_other
* \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)
+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);
-
- /* 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 stitching 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) {
- butal->but->drawflag |= UI_BUT_ALIGN_STITCH_TOP;
- }
- *butal->borders[side] = co;
- butal->dists[side] = 0.0f;
- /* Clearing one of the 'flags pair' here is enough to prevent this loop running on
- * the same column, side and direction again. */
- butal->flags[side] &= ~stitch_s2;
- }
+ ButAlign *butal_neighbor;
+
+ const int stitch_s1 = STITCH(side_s1);
+ const int stitch_s2 = STITCH(side_s2);
+
+ /* 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 stitching 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) {
+ butal->but->drawflag |= UI_BUT_ALIGN_STITCH_TOP;
+ }
+ *butal->borders[side] = co;
+ butal->dists[side] = 0.0f;
+ /* Clearing one of the 'flags pair' here is enough to prevent this loop running on
+ * the same column, side and direction again. */
+ butal->flags[side] &= ~stitch_s2;
+ }
}
/**
@@ -316,61 +329,61 @@ static void block_align_stitch_neighbors(
*/
static int ui_block_align_butal_cmp(const void *a, const void *b)
{
- const ButAlign *butal = a;
- const ButAlign *butal_other = b;
-
- /* Sort by align group. */
- if (butal->but->alignnr != butal_other->but->alignnr) {
- return butal->but->alignnr - butal_other->but->alignnr;
- }
-
- /* Sort vertically.
- * Note that Y of buttons is decreasing (first buttons have higher Y value than later ones). */
- if (*butal->borders[TOP] != *butal_other->borders[TOP]) {
- return (*butal_other->borders[TOP] > *butal->borders[TOP]) ? 1 : -1;
- }
-
- /* Sort horizontally. */
- if (*butal->borders[LEFT] != *butal_other->borders[LEFT]) {
- return (*butal->borders[LEFT] > *butal_other->borders[LEFT]) ? 1 : -1;
- }
-
- /* XXX We cannot actually assert here, since in some very compressed space cases,
- * stupid UI code produces widgets which have the same TOP and LEFT positions...
- * We do not care really,
- * because this happens when UI is way too small to be usable anyway. */
- /* BLI_assert(0); */
- return 0;
+ const ButAlign *butal = a;
+ const ButAlign *butal_other = b;
+
+ /* Sort by align group. */
+ if (butal->but->alignnr != butal_other->but->alignnr) {
+ return butal->but->alignnr - butal_other->but->alignnr;
+ }
+
+ /* Sort vertically.
+ * Note that Y of buttons is decreasing (first buttons have higher Y value than later ones). */
+ if (*butal->borders[TOP] != *butal_other->borders[TOP]) {
+ return (*butal_other->borders[TOP] > *butal->borders[TOP]) ? 1 : -1;
+ }
+
+ /* Sort horizontally. */
+ if (*butal->borders[LEFT] != *butal_other->borders[LEFT]) {
+ return (*butal->borders[LEFT] > *butal_other->borders[LEFT]) ? 1 : -1;
+ }
+
+ /* XXX We cannot actually assert here, since in some very compressed space cases,
+ * stupid UI code produces widgets which have the same TOP and LEFT positions...
+ * We do not care really,
+ * because this happens when UI is way too small to be usable anyway. */
+ /* BLI_assert(0); */
+ return 0;
}
static void ui_block_align_but_to_region(uiBut *but, const ARegion *region)
{
- rctf *rect = &but->rect;
- const float but_width = BLI_rctf_size_x(rect);
- const float but_height = BLI_rctf_size_y(rect);
- const float outline_px = U.pixelsize; /* This may have to be made more variable. */
-
- switch (but->drawflag & UI_BUT_ALIGN) {
- case UI_BUT_ALIGN_TOP:
- rect->ymax = region->winy + outline_px;
- rect->ymin = but->rect.ymax - but_height;
- break;
- case UI_BUT_ALIGN_DOWN:
- rect->ymin = -outline_px;
- rect->ymax = rect->ymin + but_height;
- break;
- case UI_BUT_ALIGN_LEFT:
- rect->xmin = -outline_px;
- rect->xmax = rect->xmin + but_width;
- break;
- case UI_BUT_ALIGN_RIGHT:
- rect->xmax = region->winx + outline_px;
- rect->xmin = rect->xmax - but_width;
- break;
- default:
- BLI_assert(0);
- break;
- }
+ rctf *rect = &but->rect;
+ const float but_width = BLI_rctf_size_x(rect);
+ const float but_height = BLI_rctf_size_y(rect);
+ const float outline_px = U.pixelsize; /* This may have to be made more variable. */
+
+ switch (but->drawflag & UI_BUT_ALIGN) {
+ case UI_BUT_ALIGN_TOP:
+ rect->ymax = region->winy + outline_px;
+ rect->ymin = but->rect.ymax - but_height;
+ break;
+ case UI_BUT_ALIGN_DOWN:
+ rect->ymin = -outline_px;
+ rect->ymax = rect->ymin + but_height;
+ break;
+ case UI_BUT_ALIGN_LEFT:
+ rect->xmin = -outline_px;
+ rect->xmax = rect->xmin + but_width;
+ break;
+ case UI_BUT_ALIGN_RIGHT:
+ rect->xmax = region->winx + outline_px;
+ rect->xmin = rect->xmax - but_width;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
/**
@@ -381,350 +394,355 @@ static void ui_block_align_but_to_region(uiBut *but, const ARegion *region)
*/
void ui_block_align_calc(uiBlock *block, const ARegion *region)
{
- uiBut *but;
- int num_buttons = 0;
-
- const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN;
-
- ButAlign *butal_array;
- ButAlign *butal, *butal_other;
- int side;
- int i, j;
-
- /* First loop: we count number of buttons belonging to an align group, and clear their align flag.
- * Tabs get some special treatment here, they get aligned to region border. */
- for (but = block->buttons.first; but; but = but->next) {
- /* special case: tabs need to be aligned to a region border, drawflag tells which one */
- if (but->type == UI_BTYPE_TAB) {
- ui_block_align_but_to_region(but, region);
- }
- else {
- /* Clear old align flags. */
- but->drawflag &= ~UI_BUT_ALIGN_ALL;
- }
-
- if (but->alignnr != 0) {
- num_buttons++;
- }
- }
-
- if (num_buttons < 2) {
- /* No need to go further if we have nothing to align... */
- return;
- }
-
- butal_array = alloca(sizeof(*butal_array) * (size_t)num_buttons);
- memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons);
-
- /* Second loop: we initialize our ButAlign data for each button. */
- for (but = block->buttons.first, butal = butal_array; but; but = but->next) {
- if (but->alignnr != 0) {
- butal->but = but;
- butal->borders[LEFT] = &but->rect.xmin;
- butal->borders[RIGHT] = &but->rect.xmax;
- butal->borders[DOWN] = &but->rect.ymin;
- butal->borders[TOP] = &but->rect.ymax;
- copy_v4_fl(butal->dists, FLT_MAX);
- butal++;
- }
- }
-
- /* This will give us ButAlign items regrouped by align group, vertical and horizontal location.
- * Note that, given how buttons are defined in UI code,
- * butal_array shall already be "nearly sorted"... */
- qsort(butal_array, (size_t)num_buttons, sizeof(*butal_array), ui_block_align_butal_cmp);
-
- /* Third loop: for each pair of buttons in the same align group,
- * we compute their potential proximity. Note that each pair is checked only once, and that we
- * break early in case we know all remaining pairs will always be too far away. */
- for (i = 0, butal = butal_array; i < num_buttons; i++, butal++) {
- const short alignnr = butal->but->alignnr;
-
- for (j = i + 1, butal_other = &butal_array[i + 1]; j < num_buttons; j++, butal_other++) {
- const float max_delta = MAX_DELTA;
-
- /* Since they are sorted, buttons after current butal can only be of same or higher
- * group, and once they are not of same group, we know we can break this sub-loop and
- * start checking with next butal. */
- if (butal_other->but->alignnr != alignnr) {
- break;
- }
-
- /* Since they are sorted vertically first, buttons after current butal can only be at
- * same or lower height, and once they are lower than a given threshold, we know we can
- * break this sub-loop and start checking with next butal. */
- if ((*butal->borders[DOWN] - *butal_other->borders[TOP]) > max_delta) {
- break;
- }
-
- block_align_proximity_compute(butal, butal_other);
- }
- }
-
- /* Fourth loop: we have all our 'aligned' buttons as a 'map' in butal_array. We need to:
- * - update their relevant coordinates to stitch them.
- * - assign them valid flags.
- */
- for (i = 0; i < num_buttons; i++) {
- butal = &butal_array[i];
-
- for (side = 0; side < TOTSIDES; side++) {
- butal_other = butal->neighbors[side];
-
- if (butal_other) {
- const int side_opp = OPPOSITE(side);
- const int side_s1 = SIDE1(side);
- const int side_s2 = SIDE2(side);
-
- const int align = sides_to_ui_but_align_flags[side];
- const int align_opp = sides_to_ui_but_align_flags[side_opp];
-
- float co;
-
- butal->but->drawflag |= align;
- butal_other->but->drawflag |= align_opp;
- if (butal->dists[side]) {
- float *delta = &butal->dists[side];
-
- if (*butal->borders[side] < *butal_other->borders[side_opp]) {
- *delta *= 0.5f;
- }
- else {
- *delta *= -0.5f;
- }
- co = (*butal->borders[side] += *delta);
-
- if (butal_other->dists[side_opp]) {
- BLI_assert(butal_other->dists[side_opp] * 0.5f == fabsf(*delta));
- *butal_other->borders[side_opp] = co;
- butal_other->dists[side_opp] = 0.0f;
- }
- *delta = 0.0f;
- }
- else {
- co = *butal->borders[side];
- }
-
- block_align_stitch_neighbors(butal, side, side_opp, side_s1, side_s2, align, align_opp, co);
- block_align_stitch_neighbors(butal, side, side_opp, side_s2, side_s1, align, align_opp, co);
- }
- }
- }
+ uiBut *but;
+ int num_buttons = 0;
+
+ const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN;
+
+ ButAlign *butal_array;
+ ButAlign *butal, *butal_other;
+ int side;
+ int i, j;
+
+ /* First loop: we count number of buttons belonging to an align group, and clear their align flag.
+ * Tabs get some special treatment here, they get aligned to region border. */
+ for (but = block->buttons.first; but; but = but->next) {
+ /* special case: tabs need to be aligned to a region border, drawflag tells which one */
+ if (but->type == UI_BTYPE_TAB) {
+ ui_block_align_but_to_region(but, region);
+ }
+ else {
+ /* Clear old align flags. */
+ but->drawflag &= ~UI_BUT_ALIGN_ALL;
+ }
+
+ if (but->alignnr != 0) {
+ num_buttons++;
+ }
+ }
+
+ if (num_buttons < 2) {
+ /* No need to go further if we have nothing to align... */
+ return;
+ }
+
+ butal_array = alloca(sizeof(*butal_array) * (size_t)num_buttons);
+ memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons);
+
+ /* Second loop: we initialize our ButAlign data for each button. */
+ for (but = block->buttons.first, butal = butal_array; but; but = but->next) {
+ if (but->alignnr != 0) {
+ butal->but = but;
+ butal->borders[LEFT] = &but->rect.xmin;
+ butal->borders[RIGHT] = &but->rect.xmax;
+ butal->borders[DOWN] = &but->rect.ymin;
+ butal->borders[TOP] = &but->rect.ymax;
+ copy_v4_fl(butal->dists, FLT_MAX);
+ butal++;
+ }
+ }
+
+ /* This will give us ButAlign items regrouped by align group, vertical and horizontal location.
+ * Note that, given how buttons are defined in UI code,
+ * butal_array shall already be "nearly sorted"... */
+ qsort(butal_array, (size_t)num_buttons, sizeof(*butal_array), ui_block_align_butal_cmp);
+
+ /* Third loop: for each pair of buttons in the same align group,
+ * we compute their potential proximity. Note that each pair is checked only once, and that we
+ * break early in case we know all remaining pairs will always be too far away. */
+ for (i = 0, butal = butal_array; i < num_buttons; i++, butal++) {
+ const short alignnr = butal->but->alignnr;
+
+ for (j = i + 1, butal_other = &butal_array[i + 1]; j < num_buttons; j++, butal_other++) {
+ const float max_delta = MAX_DELTA;
+
+ /* Since they are sorted, buttons after current butal can only be of same or higher
+ * group, and once they are not of same group, we know we can break this sub-loop and
+ * start checking with next butal. */
+ if (butal_other->but->alignnr != alignnr) {
+ break;
+ }
+
+ /* Since they are sorted vertically first, buttons after current butal can only be at
+ * same or lower height, and once they are lower than a given threshold, we know we can
+ * break this sub-loop and start checking with next butal. */
+ if ((*butal->borders[DOWN] - *butal_other->borders[TOP]) > max_delta) {
+ break;
+ }
+
+ block_align_proximity_compute(butal, butal_other);
+ }
+ }
+
+ /* Fourth loop: we have all our 'aligned' buttons as a 'map' in butal_array. We need to:
+ * - update their relevant coordinates to stitch them.
+ * - assign them valid flags.
+ */
+ for (i = 0; i < num_buttons; i++) {
+ butal = &butal_array[i];
+
+ for (side = 0; side < TOTSIDES; side++) {
+ butal_other = butal->neighbors[side];
+
+ if (butal_other) {
+ const int side_opp = OPPOSITE(side);
+ const int side_s1 = SIDE1(side);
+ const int side_s2 = SIDE2(side);
+
+ const int align = sides_to_ui_but_align_flags[side];
+ const int align_opp = sides_to_ui_but_align_flags[side_opp];
+
+ float co;
+
+ butal->but->drawflag |= align;
+ butal_other->but->drawflag |= align_opp;
+ if (butal->dists[side]) {
+ float *delta = &butal->dists[side];
+
+ if (*butal->borders[side] < *butal_other->borders[side_opp]) {
+ *delta *= 0.5f;
+ }
+ else {
+ *delta *= -0.5f;
+ }
+ co = (*butal->borders[side] += *delta);
+
+ if (butal_other->dists[side_opp]) {
+ BLI_assert(butal_other->dists[side_opp] * 0.5f == fabsf(*delta));
+ *butal_other->borders[side_opp] = co;
+ butal_other->dists[side_opp] = 0.0f;
+ }
+ *delta = 0.0f;
+ }
+ else {
+ co = *butal->borders[side];
+ }
+
+ block_align_stitch_neighbors(
+ butal, side, side_opp, side_s1, side_s2, align, align_opp, co);
+ block_align_stitch_neighbors(
+ butal, side, side_opp, side_s2, side_s1, align, align_opp, co);
+ }
+ }
+ }
}
-#undef SIDE_TO_UI_BUT_ALIGN
-#undef SIDE1
-#undef OPPOSITE
-#undef SIDE2
-#undef IS_COLUMN
-#undef STITCH
-#undef MAX_DELTA
+# undef SIDE_TO_UI_BUT_ALIGN
+# undef SIDE1
+# undef OPPOSITE
+# undef SIDE2
+# undef IS_COLUMN
+# undef STITCH
+# undef MAX_DELTA
#else
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, UI_BTYPE_SEPR_SPACER);
+ return !ELEM(but->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_CHECKBOX,
+ UI_BTYPE_CHECKBOX_N,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_SEPR_SPACER);
}
static bool buts_are_horiz(uiBut *but1, uiBut *but2)
{
- float dx, dy;
+ float dx, dy;
- /* simple case which can fail if buttons shift apart
- * with proportional layouts, see: [#38602] */
- if ((but1->rect.ymin == but2->rect.ymin) &&
- (but1->rect.xmin != but2->rect.xmin))
- {
- return true;
- }
+ /* simple case which can fail if buttons shift apart
+ * with proportional layouts, see: [#38602] */
+ if ((but1->rect.ymin == but2->rect.ymin) && (but1->rect.xmin != but2->rect.xmin)) {
+ return true;
+ }
- dx = fabsf(but1->rect.xmax - but2->rect.xmin);
- dy = fabsf(but1->rect.ymin - but2->rect.ymax);
+ dx = fabsf(but1->rect.xmax - but2->rect.xmin);
+ dy = fabsf(but1->rect.ymin - but2->rect.ymax);
- return (dx <= dy);
+ return (dx <= dy);
}
static void ui_block_align_calc_but(uiBut *first, short nr)
{
- uiBut *prev, *but = NULL, *next;
- int flag = 0, cols = 0, rows = 0;
-
- /* auto align */
-
- for (but = first; but && but->alignnr == nr; but = but->next) {
- if (but->next && but->next->alignnr == nr) {
- if (buts_are_horiz(but, but->next)) {
- cols++;
- }
- else {
- rows++;
- }
- }
- }
-
- /* rows == 0: 1 row, cols == 0: 1 column */
-
- /* note; how it uses 'flag' in loop below (either set it, or OR it) is confusing */
- for (but = first, prev = NULL; but && but->alignnr == nr; prev = but, but = but->next) {
- next = but->next;
- if (next && next->alignnr != nr) {
- next = NULL;
- }
-
- /* clear old flag */
- but->drawflag &= ~UI_BUT_ALIGN;
-
- if (flag == 0) { /* first case */
- if (next) {
- if (buts_are_horiz(but, next)) {
- if (rows == 0) {
- flag = UI_BUT_ALIGN_RIGHT;
- }
- else {
- flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT;
- }
- }
- else {
- flag = UI_BUT_ALIGN_DOWN;
- }
- }
- }
- else if (next == NULL) { /* last case */
- if (prev) {
- if (buts_are_horiz(prev, but)) {
- if (rows == 0) {
- flag = UI_BUT_ALIGN_LEFT;
- }
- else {
- flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT;
- }
- }
- else {
- flag = UI_BUT_ALIGN_TOP;
- }
- }
- }
- else if (buts_are_horiz(but, next)) {
- /* check if this is already second row */
- if (prev && buts_are_horiz(prev, but) == 0) {
- flag &= ~UI_BUT_ALIGN_LEFT;
- flag |= UI_BUT_ALIGN_TOP;
- /* exception case: bottom row */
- if (rows > 0) {
- uiBut *bt = but;
- while (bt && bt->alignnr == nr) {
- if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) {
- break;
- }
- bt = bt->next;
- }
- if (bt == NULL || bt->alignnr != nr) {
- flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
- }
- }
- }
- else {
- flag |= UI_BUT_ALIGN_LEFT;
- }
- }
- else {
- if (cols == 0) {
- flag |= UI_BUT_ALIGN_TOP;
- }
- else { /* next button switches to new row */
-
- if (prev && buts_are_horiz(prev, but)) {
- flag |= UI_BUT_ALIGN_LEFT;
- }
- else {
- flag &= ~UI_BUT_ALIGN_LEFT;
- flag |= UI_BUT_ALIGN_TOP;
- }
-
- if ((flag & UI_BUT_ALIGN_TOP) == 0) { /* still top row */
- if (prev) {
- if (next && buts_are_horiz(but, next)) {
- flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT;
- }
- else {
- /* last button in top row */
- flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT;
- }
- }
- else {
- flag |= UI_BUT_ALIGN_DOWN;
- }
- }
- else {
- flag |= UI_BUT_ALIGN_TOP;
- }
- }
- }
-
- but->drawflag |= flag;
-
- /* merge coordinates */
- if (prev) {
- /* simple cases */
- if (rows == 0) {
- but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
- prev->rect.xmax = but->rect.xmin;
- }
- else if (cols == 0) {
- but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
- prev->rect.ymin = but->rect.ymax;
- }
- else {
- if (buts_are_horiz(prev, but)) {
- but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
- prev->rect.xmax = but->rect.xmin;
- /* copy height too */
- but->rect.ymax = prev->rect.ymax;
- }
- else if (prev->prev && buts_are_horiz(prev->prev, prev) == 0) {
- /* the previous button is a single one in its row */
- but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
- prev->rect.ymin = but->rect.ymax;
-
- but->rect.xmin = prev->rect.xmin;
- if (next && buts_are_horiz(but, next) == 0) {
- but->rect.xmax = prev->rect.xmax;
- }
- }
- else {
- /* the previous button is not a single one in its row */
- but->rect.ymax = prev->rect.ymin;
- }
- }
- }
- }
+ uiBut *prev, *but = NULL, *next;
+ int flag = 0, cols = 0, rows = 0;
+
+ /* auto align */
+
+ for (but = first; but && but->alignnr == nr; but = but->next) {
+ if (but->next && but->next->alignnr == nr) {
+ if (buts_are_horiz(but, but->next)) {
+ cols++;
+ }
+ else {
+ rows++;
+ }
+ }
+ }
+
+ /* rows == 0: 1 row, cols == 0: 1 column */
+
+ /* note; how it uses 'flag' in loop below (either set it, or OR it) is confusing */
+ for (but = first, prev = NULL; but && but->alignnr == nr; prev = but, but = but->next) {
+ next = but->next;
+ if (next && next->alignnr != nr) {
+ next = NULL;
+ }
+
+ /* clear old flag */
+ but->drawflag &= ~UI_BUT_ALIGN;
+
+ if (flag == 0) { /* first case */
+ if (next) {
+ if (buts_are_horiz(but, next)) {
+ if (rows == 0) {
+ flag = UI_BUT_ALIGN_RIGHT;
+ }
+ else {
+ flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT;
+ }
+ }
+ else {
+ flag = UI_BUT_ALIGN_DOWN;
+ }
+ }
+ }
+ else if (next == NULL) { /* last case */
+ if (prev) {
+ if (buts_are_horiz(prev, but)) {
+ if (rows == 0) {
+ flag = UI_BUT_ALIGN_LEFT;
+ }
+ else {
+ flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT;
+ }
+ }
+ else {
+ flag = UI_BUT_ALIGN_TOP;
+ }
+ }
+ }
+ else if (buts_are_horiz(but, next)) {
+ /* check if this is already second row */
+ if (prev && buts_are_horiz(prev, but) == 0) {
+ flag &= ~UI_BUT_ALIGN_LEFT;
+ flag |= UI_BUT_ALIGN_TOP;
+ /* exception case: bottom row */
+ if (rows > 0) {
+ uiBut *bt = but;
+ while (bt && bt->alignnr == nr) {
+ if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) {
+ break;
+ }
+ bt = bt->next;
+ }
+ if (bt == NULL || bt->alignnr != nr) {
+ flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
+ }
+ }
+ }
+ else {
+ flag |= UI_BUT_ALIGN_LEFT;
+ }
+ }
+ else {
+ if (cols == 0) {
+ flag |= UI_BUT_ALIGN_TOP;
+ }
+ else { /* next button switches to new row */
+
+ if (prev && buts_are_horiz(prev, but)) {
+ flag |= UI_BUT_ALIGN_LEFT;
+ }
+ else {
+ flag &= ~UI_BUT_ALIGN_LEFT;
+ flag |= UI_BUT_ALIGN_TOP;
+ }
+
+ if ((flag & UI_BUT_ALIGN_TOP) == 0) { /* still top row */
+ if (prev) {
+ if (next && buts_are_horiz(but, next)) {
+ flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT;
+ }
+ else {
+ /* last button in top row */
+ flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT;
+ }
+ }
+ else {
+ flag |= UI_BUT_ALIGN_DOWN;
+ }
+ }
+ else {
+ flag |= UI_BUT_ALIGN_TOP;
+ }
+ }
+ }
+
+ but->drawflag |= flag;
+
+ /* merge coordinates */
+ if (prev) {
+ /* simple cases */
+ if (rows == 0) {
+ but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
+ prev->rect.xmax = but->rect.xmin;
+ }
+ else if (cols == 0) {
+ but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
+ prev->rect.ymin = but->rect.ymax;
+ }
+ else {
+ if (buts_are_horiz(prev, but)) {
+ but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
+ prev->rect.xmax = but->rect.xmin;
+ /* copy height too */
+ but->rect.ymax = prev->rect.ymax;
+ }
+ else if (prev->prev && buts_are_horiz(prev->prev, prev) == 0) {
+ /* the previous button is a single one in its row */
+ but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
+ prev->rect.ymin = but->rect.ymax;
+
+ but->rect.xmin = prev->rect.xmin;
+ if (next && buts_are_horiz(but, next) == 0) {
+ but->rect.xmax = prev->rect.xmax;
+ }
+ }
+ else {
+ /* the previous button is not a single one in its row */
+ but->rect.ymax = prev->rect.ymin;
+ }
+ }
+ }
+ }
}
void ui_block_align_calc(uiBlock *block)
{
- uiBut *but;
- short nr;
-
- /* align buttons with same align nr */
- for (but = block->buttons.first; but; ) {
- if (but->alignnr) {
- nr = but->alignnr;
- ui_block_align_calc_but(but, nr);
-
- /* skip with same number */
- for (; but && but->alignnr == nr; but = but->next) {
- /* pass */
- }
-
- if (!but) {
- break;
- }
- }
- else {
- but = but->next;
- }
- }
+ uiBut *but;
+ short nr;
+
+ /* align buttons with same align nr */
+ for (but = block->buttons.first; but;) {
+ if (but->alignnr) {
+ nr = but->alignnr;
+ ui_block_align_calc_but(but, nr);
+
+ /* skip with same number */
+ for (; but && but->alignnr == nr; but = but->next) {
+ /* pass */
+ }
+
+ if (!but) {
+ break;
+ }
+ }
+ else {
+ but = but->next;
+ }
+ }
}
#endif