diff options
author | wil <william.barsse@gmail.com> | 2017-01-07 20:26:46 +0100 |
---|---|---|
committer | wil <william.barsse@gmail.com> | 2017-01-07 20:26:46 +0100 |
commit | 1f47c58d63130b8de59cb81422a4339bc0273273 (patch) | |
tree | fc29c5719ef2661f1dc3409c5c153a11802a8c6b /sway | |
parent | [fix] resize should now preserve surrounding container's dimensions (diff) | |
download | sway-1f47c58d63130b8de59cb81422a4339bc0273273.tar.gz sway-1f47c58d63130b8de59cb81422a4339bc0273273.tar.zst sway-1f47c58d63130b8de59cb81422a4339bc0273273.zip |
simplification of apply_auto_layout
Achieved by introducing auto_group_bounds function that produces
the start/end indexes of a group inside an auto layot container.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/layout.c | 158 |
1 files changed, 90 insertions, 68 deletions
diff --git a/sway/layout.c b/sway/layout.c index 78673cf9..6a2af2a6 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -1164,9 +1164,7 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1164 | // a single slave group (containing slave 1 and 2). The master | 1164 | // a single slave group (containing slave 1 and 2). The master |
1165 | // group and slave group are layed out using L_VERT. | 1165 | // group and slave group are layed out using L_VERT. |
1166 | 1166 | ||
1167 | size_t nb_slaves = container->children->length - container->nb_master; | 1167 | size_t nb_groups = auto_group_count(container); |
1168 | size_t nb_groups = (container->nb_master > 0 ? 1 : 0) + | ||
1169 | MIN(container->nb_slave_groups, nb_slaves); | ||
1170 | 1168 | ||
1171 | // the target dimension of the container along the "major" axis, each | 1169 | // the target dimension of the container along the "major" axis, each |
1172 | // group in the container will be layed out using "group_layout" along | 1170 | // group in the container will be layed out using "group_layout" along |
@@ -1216,74 +1214,53 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1216 | * layout. */ | 1214 | * layout. */ |
1217 | double old_group_dim[nb_groups]; | 1215 | double old_group_dim[nb_groups]; |
1218 | double old_dim = 0; | 1216 | double old_dim = 0; |
1219 | size_t group = 0; | 1217 | for (size_t group = 0; group < nb_groups; ++group) { |
1220 | for (int i = 0; i < container->children->length;) { | 1218 | int idx; |
1221 | swayc_t *child = container->children->items[i]; | 1219 | if (auto_group_bounds(container, group, &idx, NULL)) { |
1222 | double *dim = group_layout == L_HORIZ ? &child->height : &child->width; | 1220 | swayc_t *child = container->children->items[idx]; |
1223 | if (*dim <= 0) { | 1221 | double *dim = group_layout == L_HORIZ ? &child->height : &child->width; |
1224 | // New child with uninitialized dimension | 1222 | if (*dim <= 0) { |
1225 | *dim = dim_maj; | 1223 | // New child with uninitialized dimension |
1226 | if (nb_groups > 1) { | 1224 | *dim = dim_maj; |
1227 | // child gets a dimension proportional to existing groups, | 1225 | if (nb_groups > 1) { |
1228 | // it will be later scaled based on to the available size | 1226 | // child gets a dimension proportional to existing groups, |
1229 | // in the major axis. | 1227 | // it will be later scaled based on to the available size |
1230 | *dim /= (nb_groups - 1); | 1228 | // in the major axis. |
1229 | *dim /= (nb_groups - 1); | ||
1230 | } | ||
1231 | } | 1231 | } |
1232 | old_dim += *dim; | ||
1233 | old_group_dim[group] = *dim; | ||
1232 | } | 1234 | } |
1233 | if (i == 0 && container->nb_master > 0) { | ||
1234 | i += container->nb_master; | ||
1235 | } else { | ||
1236 | i += (nb_slaves - i + container->nb_master) / (nb_groups - group); | ||
1237 | } | ||
1238 | old_dim += *dim; | ||
1239 | old_group_dim[group++] = *dim; | ||
1240 | } | 1235 | } |
1241 | |||
1242 | double scale = dim_maj / old_dim; | 1236 | double scale = dim_maj / old_dim; |
1243 | 1237 | ||
1244 | /* Apply layout to each group */ | 1238 | /* Apply layout to each group */ |
1245 | pos = pos_maj; | 1239 | pos = pos_maj; |
1246 | 1240 | ||
1247 | // first child in the current group | 1241 | for (size_t group = 0; group < nb_groups; ++group) { |
1248 | int start; | 1242 | int start, end; // index of first (inclusive) and last (exclusive) child in the group |
1249 | 1243 | if (auto_group_bounds(container, group, &start, &end)) { | |
1250 | // index immediately after the last child in the current group | 1244 | // adjusted size of the group |
1251 | int end = 0; | 1245 | group_dim = old_group_dim[group] * scale; |
1252 | 1246 | if (group == nb_groups - 1) { | |
1253 | for (group = 0; group < nb_groups; ++group) { | 1247 | group_dim = pos_maj + dim_maj - pos; // remaining width |
1254 | // column to include next by increasing position. | 1248 | } |
1255 | size_t layout_group = master_first ? group : (group + 1) % nb_groups; | 1249 | sway_log(L_DEBUG, "Arranging container %p column %zu, children [%d,%d[ (%fx%f+%f,%f)", |
1256 | 1250 | container, group, start, end, *group_w, *group_h, *group_x, *group_y); | |
1257 | // adjusted size of the group | 1251 | switch (group_layout) { |
1258 | group_dim = old_group_dim[layout_group] * scale; | 1252 | default: |
1259 | if (container->nb_master > 0 && layout_group == 0) { | 1253 | case L_VERT: |
1260 | start = 0; | 1254 | apply_vert_layout(container, *group_x, *group_y, *group_w, *group_h, start, end); |
1261 | end = MIN(container->nb_master, container->children->length); | 1255 | break; |
1262 | } else { | 1256 | case L_HORIZ: |
1263 | if (group == 0) { | 1257 | apply_horiz_layout(container, *group_x, *group_y, *group_w, *group_h, start, end); |
1264 | start = container->nb_master; | 1258 | break; |
1265 | } else { | ||
1266 | start = end; | ||
1267 | } | 1259 | } |
1268 | end = start + (nb_slaves - start + container->nb_master) / (nb_groups - layout_group); | ||
1269 | } | ||
1270 | if (group == nb_groups - 1) { | ||
1271 | group_dim = pos_maj + dim_maj - pos; // remaining width | ||
1272 | } | ||
1273 | sway_log(L_DEBUG, "Arranging container %p column %zu, children [%d,%d[ (%fx%f+%f,%f)", | ||
1274 | container, group, start, end, *group_w, *group_h, *group_x, *group_y); | ||
1275 | switch (group_layout) { | ||
1276 | default: | ||
1277 | case L_VERT: | ||
1278 | apply_vert_layout(container, *group_x, *group_y, *group_w, *group_h, start, end); | ||
1279 | break; | ||
1280 | case L_HORIZ: | ||
1281 | apply_horiz_layout(container, *group_x, *group_y, *group_w, *group_h, start, end); | ||
1282 | break; | ||
1283 | } | ||
1284 | 1260 | ||
1285 | /* update position for next group */ | 1261 | /* update position for next group */ |
1286 | pos += group_dim; | 1262 | pos += group_dim; |
1263 | } | ||
1287 | } | 1264 | } |
1288 | } | 1265 | } |
1289 | 1266 | ||
@@ -1508,7 +1485,7 @@ bool is_auto_layout(enum swayc_layouts layout) { | |||
1508 | /** | 1485 | /** |
1509 | * Return the number of master elements in a container | 1486 | * Return the number of master elements in a container |
1510 | */ | 1487 | */ |
1511 | static inline size_t auto_master_count(swayc_t *container) { | 1488 | static inline size_t auto_master_count(const swayc_t *container) { |
1512 | return MIN(container->nb_master, container->children->length); | 1489 | return MIN(container->nb_master, container->children->length); |
1513 | } | 1490 | } |
1514 | 1491 | ||
@@ -1516,21 +1493,21 @@ static inline size_t auto_master_count(swayc_t *container) { | |||
1516 | * Return the number of children in the slave groups. This corresponds to the children | 1493 | * Return the number of children in the slave groups. This corresponds to the children |
1517 | * that are not members of the master group. | 1494 | * that are not members of the master group. |
1518 | */ | 1495 | */ |
1519 | static inline size_t auto_slave_count(swayc_t *container) { | 1496 | static inline size_t auto_slave_count(const swayc_t *container) { |
1520 | return container->children->length - auto_master_count(container); | 1497 | return container->children->length - auto_master_count(container); |
1521 | } | 1498 | } |
1522 | 1499 | ||
1523 | /** | 1500 | /** |
1524 | * Return the number of slave groups in the container. | 1501 | * Return the number of slave groups in the container. |
1525 | */ | 1502 | */ |
1526 | size_t auto_slave_group_count(swayc_t *container) { | 1503 | size_t auto_slave_group_count(const swayc_t *container) { |
1527 | return MIN(container->nb_slave_groups, auto_slave_count(container)); | 1504 | return MIN(container->nb_slave_groups, auto_slave_count(container)); |
1528 | } | 1505 | } |
1529 | 1506 | ||
1530 | /** | 1507 | /** |
1531 | * Return the combined number of master and slave groups in the container. | 1508 | * Return the combined number of master and slave groups in the container. |
1532 | */ | 1509 | */ |
1533 | size_t auto_group_count(swayc_t *container) { | 1510 | size_t auto_group_count(const swayc_t *container) { |
1534 | return auto_slave_group_count(container) + (container->nb_master ? 1 : 0); | 1511 | return auto_slave_group_count(container) + (container->nb_master ? 1 : 0); |
1535 | } | 1512 | } |
1536 | 1513 | ||
@@ -1538,7 +1515,7 @@ size_t auto_group_count(swayc_t *container) { | |||
1538 | * given the index of a container's child, return the index of the first child of the group | 1515 | * given the index of a container's child, return the index of the first child of the group |
1539 | * which index is a member of. | 1516 | * which index is a member of. |
1540 | */ | 1517 | */ |
1541 | int auto_group_start_index(swayc_t *container, int index) { | 1518 | int auto_group_start_index(const swayc_t *container, int index) { |
1542 | if (index < 0 || ! is_auto_layout(container->layout) | 1519 | if (index < 0 || ! is_auto_layout(container->layout) |
1543 | || (size_t) index < container->nb_master) { | 1520 | || (size_t) index < container->nb_master) { |
1544 | return 0; | 1521 | return 0; |
@@ -1563,7 +1540,7 @@ int auto_group_start_index(swayc_t *container, int index) { | |||
1563 | * that follows the one which index is a member of. | 1540 | * that follows the one which index is a member of. |
1564 | * This makes the function usable to walk through the groups in a container. | 1541 | * This makes the function usable to walk through the groups in a container. |
1565 | */ | 1542 | */ |
1566 | int auto_group_end_index(swayc_t *container, int index) { | 1543 | int auto_group_end_index(const swayc_t *container, int index) { |
1567 | if (index < 0 || ! is_auto_layout(container->layout)) { | 1544 | if (index < 0 || ! is_auto_layout(container->layout)) { |
1568 | return container->children->length; | 1545 | return container->children->length; |
1569 | } else { | 1546 | } else { |
@@ -1590,7 +1567,7 @@ int auto_group_end_index(swayc_t *container, int index) { | |||
1590 | * return the index of the Group containing <index>th child of <container>. | 1567 | * return the index of the Group containing <index>th child of <container>. |
1591 | * The index is the order of the group along the container's major axis (starting at 0). | 1568 | * The index is the order of the group along the container's major axis (starting at 0). |
1592 | */ | 1569 | */ |
1593 | size_t auto_group_index(swayc_t *container, int index) { | 1570 | size_t auto_group_index(const swayc_t *container, int index) { |
1594 | if (index < 0) { | 1571 | if (index < 0) { |
1595 | return 0; | 1572 | return 0; |
1596 | } | 1573 | } |
@@ -1616,3 +1593,48 @@ size_t auto_group_index(swayc_t *container, int index) { | |||
1616 | return grp_idx + (master_first ? 1 : 0); | 1593 | return grp_idx + (master_first ? 1 : 0); |
1617 | } | 1594 | } |
1618 | } | 1595 | } |
1596 | |||
1597 | /** | ||
1598 | * Return the first index (inclusive) and last index (exclusive) of the elements of a group in | ||
1599 | * an auto layout. | ||
1600 | * If the bounds of the given group can be calculated, they are returned in the start/end | ||
1601 | * parameters (int pointers) and the return value will be true. | ||
1602 | * The indexes are passed by reference and can be NULL. | ||
1603 | */ | ||
1604 | bool auto_group_bounds(const swayc_t *container, size_t group_index, int *start, int *end) { | ||
1605 | size_t nb_grp = auto_group_count(container); | ||
1606 | if (group_index >= nb_grp) { | ||
1607 | return false; | ||
1608 | } | ||
1609 | bool master_first = (container->layout == L_AUTO_LEFT || container->layout == L_AUTO_TOP); | ||
1610 | size_t nb_master = auto_master_count(container); | ||
1611 | size_t nb_slave_grp = auto_slave_group_count(container); | ||
1612 | int g_start, g_end; | ||
1613 | if (nb_master && (master_first ? group_index == 0 : group_index == nb_grp - 1)) { | ||
1614 | g_start = 0; | ||
1615 | g_end = nb_master; | ||
1616 | } else { | ||
1617 | size_t nb_slaves = auto_slave_count(container); | ||
1618 | size_t grp_sz = nb_slaves / nb_slave_grp; | ||
1619 | size_t remainder = nb_slaves % nb_slave_grp; | ||
1620 | size_t g0 = master_first && container->nb_master ? 1 : 0; | ||
1621 | size_t g1 = g0 + nb_slave_grp - remainder; | ||
1622 | if (group_index < g1) { | ||
1623 | g_start = container->nb_master + (group_index - g0) * grp_sz; | ||
1624 | g_end = g_start + grp_sz; | ||
1625 | } else { | ||
1626 | size_t g2 = group_index - g1; | ||
1627 | g_start = container->nb_master | ||
1628 | + (nb_slave_grp - remainder) * grp_sz | ||
1629 | + g2 * (grp_sz + 1); | ||
1630 | g_end = g_start + grp_sz + 1; | ||
1631 | } | ||
1632 | } | ||
1633 | if (start) { | ||
1634 | *start = g_start; | ||
1635 | } | ||
1636 | if (end) { | ||
1637 | *end = g_end; | ||
1638 | } | ||
1639 | return true; | ||
1640 | } | ||