21 #ifdef USE_UIBUT_SPATIAL_ALIGN
79 # define SIDE_TO_UI_BUT_ALIGN \
81 UI_BUT_ALIGN_LEFT, UI_BUT_ALIGN_TOP, UI_BUT_ALIGN_RIGHT, UI_BUT_ALIGN_DOWN \
85 # define SIDE1(_s) (((_s) + 1) % TOTSIDES)
86 # define OPPOSITE(_s) (((_s) + 2) % TOTSIDES)
87 # define SIDE2(_s) (((_s) + 3) % TOTSIDES)
90 # define IS_COLUMN(_s) ((_s) % 2)
93 # define STITCH(_s) (1 << (_s))
96 # define MAX_DELTA 0.45f * max_ii(UI_UNIT_Y, UI_UNIT_X)
123 float delta, delta_side_opp;
129 const bool buts_share[2] = {
139 if (!(buts_share[0] || buts_share[1]) || !(butal_can_align || butal_other_can_align)) {
143 for (side = 0; side <
RIGHT; side++) {
158 if (delta_side_opp < delta) {
159 SWAP(
int, side, side_opp);
160 delta = delta_side_opp;
163 if (delta < max_delta) {
166 if (delta <= butal->
dists[side]) {
179 if (butal_can_align && butal_other_can_align) {
181 butal_other->
neighbors[side_opp] = butal;
183 else if (butal_can_align && (delta < butal->
dists[side])) {
186 else if (butal_other_can_align && (delta < butal_other->
dists[side_opp])) {
189 butal->
dists[side] = butal_other->
dists[side_opp] = delta;
192 if (butal_can_align && butal_other_can_align) {
193 const int side_s1 =
SIDE1(side);
194 const int side_s2 =
SIDE2(side);
196 const int stitch =
STITCH(side);
197 const int stitch_opp =
STITCH(side_opp);
203 butal_other->
neighbors[side_opp] = butal;
213 if (delta < max_delta) {
214 butal->
flags[side_s1] |= stitch;
215 butal_other->
flags[side_s1] |= stitch_opp;
218 if (delta < max_delta) {
219 butal->
flags[side_s2] |= stitch;
220 butal_other->
flags[side_s2] |= stitch_opp;
264 const int stitch_s1 =
STITCH(side_s1);
265 const int stitch_s2 =
STITCH(side_s2);
272 while ((butal->
flags[side] & stitch_s1) && (butal = butal->
neighbors[side_s1]) &&
273 (butal->
flags[side] & stitch_s2)) {
278 if (butal_neighbor) {
281 *butal_neighbor->
borders[side_opp] = co;
282 butal_neighbor->
dists[side_opp] = 0.0f;
285 else if (side ==
LEFT) {
288 else if (side ==
TOP) {
292 butal->
dists[side] = 0.0f;
295 butal->
flags[side] &= ~stitch_s2;
339 const float outline_px =
U.pixelsize;
343 rect->
ymax = region->
winy + outline_px;
347 rect->
ymin = -outline_px;
348 rect->
ymax = rect->
ymin + but_height;
351 rect->
xmin = -outline_px;
352 rect->
xmax = rect->
xmin + but_width;
355 rect->
xmax = region->
winx + outline_px;
356 rect->
xmin = rect->
xmax - but_width;
392 if (num_buttons < 2) {
401 if (num_buttons <=
ARRAY_SIZE(butal_array_buf)) {
402 butal_array = butal_array_buf;
405 butal_array =
MEM_mallocN(
sizeof(*butal_array) * num_buttons, __func__);
407 memset(butal_array, 0,
sizeof(*butal_array) * (
size_t)num_buttons);
432 for (i = 0, butal = butal_array; i < num_buttons; i++, butal++) {
436 for (j = i + 1, butal_other = &butal_array[i + 1]; j < num_buttons; j++, butal_other++) {
461 for (i = 0; i < num_buttons; i++) {
462 butal = &butal_array[i];
464 for (side = 0; side <
TOTSIDES; side++) {
468 const int side_opp =
OPPOSITE(side);
469 const int side_s1 =
SIDE1(side);
470 const int side_s2 =
SIDE2(side);
472 const int align = sides_to_ui_but_align_flags[side];
473 const int align_opp = sides_to_ui_but_align_flags[side_opp];
480 float *delta = &butal->
dists[side];
488 co = (*butal->
borders[side] += *delta);
492 *butal_other->
borders[side_opp] = co;
493 butal_other->
dists[side_opp] = 0.0f;
502 butal, side, side_opp, side_s1, side_s2, align, align_opp, co);
504 butal, side, side_opp, side_s2, side_s1, align, align_opp, co);
508 if (butal_array_buf != butal_array) {
513 # undef SIDE_TO_UI_BUT_ALIGN
534 static bool buts_are_horiz(
uiBut *but1,
uiBut *but2)
550 static void ui_block_align_calc_but(
uiBut *first,
short nr)
553 int flag = 0, cols = 0, rows = 0;
583 if (buts_are_horiz(
but,
next)) {
598 if (buts_are_horiz(
prev,
but)) {
611 else if (buts_are_horiz(
but,
next)) {
619 while (bt && bt->
alignnr == nr) {
677 else if (cols == 0) {
682 if (buts_are_horiz(
prev,
but)) {
688 else if (
prev->prev && buts_are_horiz(
prev->prev,
prev) == 0) {
715 ui_block_align_calc_but(
but, nr);
#define LISTBASE_FOREACH(type, var, list)
MINLINE float max_ff(float a, float b)
MINLINE void copy_v4_fl(float r[4], float f)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
#define RGN_ALIGN_ENUM_FROM_MASK(align)
Read Guarded memory(de)allocation.
@ UI_BUT_ALIGN_STITCH_TOP
@ UI_BUT_ALIGN_STITCH_LEFT
bool ui_but_can_align(const uiBut *but)
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 ui_block_align_but_to_region(uiBut *but, const ARegion *region)
int ui_but_align_opposite_to_area_align_get(const ARegion *region)
static void block_align_proximity_compute(ButAlign *butal, ButAlign *butal_other)
static int ui_block_align_butal_cmp(const void *a, const void *b)
#define SIDE_TO_UI_BUT_ALIGN
void ui_block_align_calc(uiBlock *block, const ARegion *region)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
SymEdge< T > * prev(const SymEdge< T > *se)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
struct ButAlign * neighbors[4]