78#define SIDE_TO_UI_BUT_ALIGN \
79 {UI_BUT_ALIGN_LEFT, UI_BUT_ALIGN_TOP, UI_BUT_ALIGN_RIGHT, UI_BUT_ALIGN_DOWN}
82#define SIDE1(_s) (((_s) + 1) % TOTSIDES)
83#define OPPOSITE(_s) (((_s) + 2) % TOTSIDES)
84#define SIDE2(_s) (((_s) + 3) % TOTSIDES)
87#define IS_COLUMN(_s) ((_s) % 2)
90#define STITCH(_s) (1 << (_s))
93#define MAX_DELTA 0.45f * max_ii(UI_UNIT_Y, UI_UNIT_X)
97 const bool btype_can_align = !
ELEM(but->
type,
119 float delta, delta_side_opp;
125 const bool buts_share[2] = {
135 if (!(buts_share[0] || buts_share[1]) || !(butal_can_align || butal_other_can_align)) {
139 for (side = 0; side <
RIGHT; side++) {
154 if (delta_side_opp < delta) {
155 std::swap(side, side_opp);
156 delta = delta_side_opp;
159 if (delta < max_delta) {
162 if (delta <= butal->dists[side]) {
175 if (butal_can_align && butal_other_can_align) {
177 butal_other->
neighbors[side_opp] = butal;
179 else if (butal_can_align && (delta < butal->dists[side])) {
182 else if (butal_other_can_align && (delta < butal_other->dists[side_opp])) {
183 butal_other->
neighbors[side_opp] =
nullptr;
185 butal->
dists[side] = butal_other->
dists[side_opp] = delta;
188 if (butal_can_align && butal_other_can_align) {
189 const int side_s1 =
SIDE1(side);
190 const int side_s2 =
SIDE2(side);
192 const int stitch =
STITCH(side);
193 const int stitch_opp =
STITCH(side_opp);
198 if (butal_other->
neighbors[side_opp] ==
nullptr) {
199 butal_other->
neighbors[side_opp] = butal;
209 if (delta < max_delta) {
210 butal->
flags[side_s1] |= stitch;
211 butal_other->
flags[side_s1] |= stitch_opp;
214 if (delta < max_delta) {
215 butal->
flags[side_s2] |= stitch;
216 butal_other->
flags[side_s2] |= stitch_opp;
260 const int stitch_s1 =
STITCH(side_s1);
261 const int stitch_s2 =
STITCH(side_s2);
268 while ((butal->
flags[side] & stitch_s1) && (butal = butal->
neighbors[side_s1]) &&
269 (butal->
flags[side] & stitch_s2))
275 if (butal_neighbor) {
278 *butal_neighbor->
borders[side_opp] = co;
279 butal_neighbor->
dists[side_opp] = 0.0f;
282 else if (side ==
LEFT) {
285 else if (side ==
TOP) {
289 butal->
dists[side] = 0.0f;
292 butal->
flags[side] &= ~stitch_s2;
329 const float outline_px =
U.pixelsize;
333 rect->
ymax = region->
winy + outline_px;
337 rect->
ymin = -outline_px;
338 rect->
ymax = rect->
ymin + but_height;
341 rect->
xmin = -outline_px;
342 rect->
xmax = rect->
xmin + but_width;
345 rect->
xmax = region->
winx + outline_px;
346 rect->
xmin = rect->
xmax - but_width;
366 for (
const std::unique_ptr<uiBut> &but : block->
buttons) {
376 if (but->alignnr == 0) {
381 butal.
but = but.get();
390 if (butal_array.
size() < 2) {
413 if (butal_other.but->alignnr != alignnr) {
420 if ((*butal.
borders[
DOWN] - *butal_other.borders[
TOP]) > max_delta) {
432 for (
ButAlign &butal : butal_array) {
434 for (
int side = 0; side <
TOTSIDES; side++) {
438 const int side_opp =
OPPOSITE(side);
439 const int side_s1 =
SIDE1(side);
440 const int side_s2 =
SIDE2(side);
442 const int align = sides_to_ui_but_align_flags[side];
443 const int align_opp = sides_to_ui_but_align_flags[side_opp];
447 butal.but->drawflag |= align;
449 if (!
IS_EQF(butal.dists[side], 0.0f)) {
450 float *delta = &butal.dists[side];
452 if (*butal.borders[side] < *butal_other->
borders[side_opp]) {
458 co = (*butal.borders[side] += *delta);
462 *butal_other->
borders[side_opp] = co;
463 butal_other->
dists[side_opp] = 0.0f;
468 co = *butal.borders[side];
472 &butal, side, side_opp, side_s1, side_s2, align, align_opp, co);
474 &butal, side, side_opp, side_s2, side_s1, align, align_opp, co);
480#undef SIDE_TO_UI_BUT_ALIGN
MINLINE float max_ff(float a, float b)
bool BLI_rctf_is_empty(const struct rctf *rect)
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
IndexRange index_range() const
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
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 bool ui_block_align_butal_cmp(const ButAlign &butal, const ButAlign &butal_other)
#define SIDE_TO_UI_BUT_ALIGN
void ui_block_align_calc(uiBlock *block, const ARegion *region)
VecBase< float, 4 > float4
blender::VecBase< int8_t, 4 > char4
std::array< float *, 4 > borders
blender::Vector< std::unique_ptr< uiBut > > buttons