mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Add an "absolute-centre" alignment to use the centre of the total space
instead of only the available space. From Magnus Gross in GitHub issue 2578.
This commit is contained in:
parent
d98f9f7fe5
commit
3eb91efba1
214
format-draw.c
214
format-draw.c
@ -157,13 +157,14 @@ format_draw_put_list(struct screen_write_ctx *octx,
|
||||
static void
|
||||
format_draw_none(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
|
||||
struct format_ranges *frs)
|
||||
struct screen *abs_centre, struct format_ranges *frs)
|
||||
{
|
||||
u_int width_left, width_centre, width_right;
|
||||
u_int width_left, width_centre, width_right, width_abs_centre;
|
||||
|
||||
width_left = left->cx;
|
||||
width_centre = centre->cx;
|
||||
width_right = right->cx;
|
||||
width_abs_centre = abs_centre->cx;
|
||||
|
||||
/*
|
||||
* Try to keep as much of the left and right as possible at the expense
|
||||
@ -199,23 +200,34 @@ format_draw_none(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
- width_centre / 2,
|
||||
centre->cx / 2 - width_centre / 2,
|
||||
width_centre);
|
||||
|
||||
/*
|
||||
* Write abs_centre in the perfect centre of all horizontal space.
|
||||
*/
|
||||
if (width_abs_centre > available)
|
||||
width_abs_centre = available;
|
||||
format_draw_put(octx, ocx, ocy, abs_centre, frs,
|
||||
(available - width_abs_centre) / 2,
|
||||
0,
|
||||
width_abs_centre);
|
||||
}
|
||||
|
||||
/* Draw format with list on the left. */
|
||||
static void
|
||||
format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
|
||||
struct screen *list, struct screen *list_left, struct screen *list_right,
|
||||
struct screen *after, int focus_start, int focus_end,
|
||||
struct format_ranges *frs)
|
||||
struct screen *abs_centre, struct screen *list, struct screen *list_left,
|
||||
struct screen *list_right, struct screen *after, int focus_start,
|
||||
int focus_end, struct format_ranges *frs)
|
||||
{
|
||||
u_int width_left, width_centre, width_right;
|
||||
u_int width_list, width_after;
|
||||
u_int width_list, width_after, width_abs_centre;
|
||||
struct screen_write_ctx ctx;
|
||||
|
||||
width_left = left->cx;
|
||||
width_centre = centre->cx;
|
||||
width_right = right->cx;
|
||||
width_abs_centre = abs_centre->cx;
|
||||
width_list = list->cx;
|
||||
width_after = after->cx;
|
||||
|
||||
@ -247,7 +259,7 @@ format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
format_draw_none(octx, available, ocx, ocy, left, centre,
|
||||
right, frs);
|
||||
right, abs_centre, frs);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -291,23 +303,34 @@ format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
focus_start = focus_end = 0;
|
||||
format_draw_put_list(octx, ocx, ocy, width_left, width_list, list,
|
||||
list_left, list_right, focus_start, focus_end, frs);
|
||||
|
||||
/*
|
||||
* Write abs_centre in the perfect centre of all horizontal space.
|
||||
*/
|
||||
if (width_abs_centre > available)
|
||||
width_abs_centre = available;
|
||||
format_draw_put(octx, ocx, ocy, abs_centre, frs,
|
||||
(available - width_abs_centre) / 2,
|
||||
0,
|
||||
width_abs_centre);
|
||||
}
|
||||
|
||||
/* Draw format with list in the centre. */
|
||||
static void
|
||||
format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
|
||||
struct screen *list, struct screen *list_left, struct screen *list_right,
|
||||
struct screen *after, int focus_start, int focus_end,
|
||||
struct format_ranges *frs)
|
||||
struct screen *abs_centre, struct screen *list, struct screen *list_left,
|
||||
struct screen *list_right, struct screen *after, int focus_start,
|
||||
int focus_end, struct format_ranges *frs)
|
||||
{
|
||||
u_int width_left, width_centre, width_right;
|
||||
u_int width_list, width_after, middle;
|
||||
u_int width_left, width_centre, width_right, middle;
|
||||
u_int width_list, width_after, width_abs_centre;
|
||||
struct screen_write_ctx ctx;
|
||||
|
||||
width_left = left->cx;
|
||||
width_centre = centre->cx;
|
||||
width_right = right->cx;
|
||||
width_abs_centre = abs_centre->cx;
|
||||
width_list = list->cx;
|
||||
width_after = after->cx;
|
||||
|
||||
@ -339,7 +362,7 @@ format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
format_draw_none(octx, available, ocx, ocy, left, centre,
|
||||
right, frs);
|
||||
right, abs_centre, frs);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -388,23 +411,34 @@ format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
format_draw_put_list(octx, ocx, ocy, middle - width_list / 2,
|
||||
width_list, list, list_left, list_right, focus_start, focus_end,
|
||||
frs);
|
||||
|
||||
/*
|
||||
* Write abs_centre in the perfect centre of all horizontal space.
|
||||
*/
|
||||
if (width_abs_centre > available)
|
||||
width_abs_centre = available;
|
||||
format_draw_put(octx, ocx, ocy, abs_centre, frs,
|
||||
(available - width_abs_centre) / 2,
|
||||
0,
|
||||
width_abs_centre);
|
||||
}
|
||||
|
||||
/* Draw format with list on the right. */
|
||||
static void
|
||||
format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
|
||||
struct screen *list, struct screen *list_left, struct screen *list_right,
|
||||
struct screen *after, int focus_start, int focus_end,
|
||||
struct format_ranges *frs)
|
||||
struct screen *abs_centre, struct screen *list,
|
||||
struct screen *list_left, struct screen *list_right, struct screen *after,
|
||||
int focus_start, int focus_end, struct format_ranges *frs)
|
||||
{
|
||||
u_int width_left, width_centre, width_right;
|
||||
u_int width_list, width_after;
|
||||
u_int width_list, width_after, width_abs_centre;
|
||||
struct screen_write_ctx ctx;
|
||||
|
||||
width_left = left->cx;
|
||||
width_centre = centre->cx;
|
||||
width_right = right->cx;
|
||||
width_abs_centre = abs_centre->cx;
|
||||
width_list = list->cx;
|
||||
width_after = after->cx;
|
||||
|
||||
@ -436,7 +470,7 @@ format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
format_draw_none(octx, available, ocx, ocy, left, centre,
|
||||
right, frs);
|
||||
right, abs_centre, frs);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -484,6 +518,118 @@ format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
|
||||
format_draw_put_list(octx, ocx, ocy, available - width_list -
|
||||
width_after, width_list, list, list_left, list_right, focus_start,
|
||||
focus_end, frs);
|
||||
|
||||
/*
|
||||
* Write abs_centre in the perfect centre of all horizontal space.
|
||||
*/
|
||||
if (width_abs_centre > available)
|
||||
width_abs_centre = available;
|
||||
format_draw_put(octx, ocx, ocy, abs_centre, frs,
|
||||
(available - width_abs_centre) / 2,
|
||||
0,
|
||||
width_abs_centre);
|
||||
}
|
||||
|
||||
static void
|
||||
format_draw_absolute_centre(struct screen_write_ctx *octx, u_int available,
|
||||
u_int ocx, u_int ocy, struct screen *left, struct screen *centre,
|
||||
struct screen *right, struct screen *abs_centre, struct screen *list,
|
||||
struct screen *list_left, struct screen *list_right, struct screen *after,
|
||||
int focus_start, int focus_end, struct format_ranges *frs)
|
||||
{
|
||||
u_int width_left, width_centre, width_right, width_abs_centre;
|
||||
u_int width_list, width_after, middle, abs_centre_offset;
|
||||
|
||||
width_left = left->cx;
|
||||
width_centre = centre->cx;
|
||||
width_right = right->cx;
|
||||
width_abs_centre = abs_centre->cx;
|
||||
width_list = list->cx;
|
||||
width_after = after->cx;
|
||||
|
||||
/*
|
||||
* Trim first centre, then the right, then the left.
|
||||
*/
|
||||
while (width_left +
|
||||
width_centre +
|
||||
width_right > available) {
|
||||
if (width_centre > 0)
|
||||
width_centre--;
|
||||
else if (width_right > 0)
|
||||
width_right--;
|
||||
else
|
||||
width_left--;
|
||||
}
|
||||
|
||||
/*
|
||||
* We trim list after and abs_centre independently, as we are drawing
|
||||
* them over the rest. Trim first the list, then after the list, then
|
||||
* abs_centre.
|
||||
*/
|
||||
while (width_list + width_after + width_abs_centre > available) {
|
||||
if (width_list > 0)
|
||||
width_list--;
|
||||
else if (width_after > 0)
|
||||
width_after--;
|
||||
else
|
||||
width_abs_centre--;
|
||||
}
|
||||
|
||||
/* Write left at 0. */
|
||||
format_draw_put(octx, ocx, ocy, left, frs, 0, 0, width_left);
|
||||
|
||||
/* Write right at available - width_right. */
|
||||
format_draw_put(octx, ocx, ocy, right, frs,
|
||||
available - width_right,
|
||||
right->cx - width_right,
|
||||
width_right);
|
||||
|
||||
/*
|
||||
* Keep writing centre at the relative centre. Only the list is written
|
||||
* in the absolute centre of the horizontal space.
|
||||
*/
|
||||
middle = (width_left + ((available - width_right) - width_left) / 2);
|
||||
|
||||
/*
|
||||
* Write centre at
|
||||
* middle - width_centre.
|
||||
*/
|
||||
format_draw_put(octx, ocx, ocy, centre, frs,
|
||||
middle - width_centre,
|
||||
0,
|
||||
width_centre);
|
||||
|
||||
/*
|
||||
* If there is no focus given, keep the centre in focus.
|
||||
*/
|
||||
if (focus_start == -1 || focus_end == -1)
|
||||
focus_start = focus_end = list->cx / 2;
|
||||
|
||||
/*
|
||||
* We centre abs_centre and the list together, so their shared centre is
|
||||
* in the perfect centre of horizontal space.
|
||||
*/
|
||||
abs_centre_offset = (available - width_list - width_abs_centre) / 2;
|
||||
|
||||
/*
|
||||
* Write abs_centre before the list.
|
||||
*/
|
||||
format_draw_put(octx, ocx, ocy, abs_centre, frs, abs_centre_offset,
|
||||
0, width_abs_centre);
|
||||
abs_centre_offset += width_abs_centre;
|
||||
|
||||
/*
|
||||
* Draw the list in the absolute centre
|
||||
*/
|
||||
format_draw_put_list(octx, ocx, ocy, abs_centre_offset, width_list,
|
||||
list, list_left, list_right, focus_start, focus_end, frs);
|
||||
abs_centre_offset += width_list;
|
||||
|
||||
/*
|
||||
* Write after at the end of the centre
|
||||
*/
|
||||
format_draw_put(octx, ocx, ocy, after, frs, abs_centre_offset, 0,
|
||||
width_after);
|
||||
}
|
||||
|
||||
/* Draw multiple characters. */
|
||||
@ -506,6 +652,7 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
|
||||
enum { LEFT,
|
||||
CENTRE,
|
||||
RIGHT,
|
||||
ABSOLUTE_CENTRE,
|
||||
LIST,
|
||||
LIST_LEFT,
|
||||
LIST_RIGHT,
|
||||
@ -514,6 +661,7 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
|
||||
const char *names[] = { "LEFT",
|
||||
"CENTRE",
|
||||
"RIGHT",
|
||||
"ABSOLUTE_CENTRE",
|
||||
"LIST",
|
||||
"LIST_LEFT",
|
||||
"LIST_RIGHT",
|
||||
@ -522,7 +670,11 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
|
||||
struct screen *os = octx->s, s[TOTAL];
|
||||
struct screen_write_ctx ctx[TOTAL];
|
||||
u_int ocx = os->cx, ocy = os->cy, n, i, width[TOTAL];
|
||||
u_int map[] = { LEFT, LEFT, CENTRE, RIGHT };
|
||||
u_int map[] = { LEFT,
|
||||
LEFT,
|
||||
CENTRE,
|
||||
RIGHT,
|
||||
ABSOLUTE_CENTRE };
|
||||
int focus_start = -1, focus_end = -1;
|
||||
int list_state = -1, fill = -1, even;
|
||||
enum style_align list_align = STYLE_ALIGN_DEFAULT;
|
||||
@ -789,25 +941,35 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
|
||||
case STYLE_ALIGN_DEFAULT:
|
||||
/* No list. */
|
||||
format_draw_none(octx, available, ocx, ocy, &s[LEFT],
|
||||
&s[CENTRE], &s[RIGHT], &frs);
|
||||
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &frs);
|
||||
break;
|
||||
case STYLE_ALIGN_LEFT:
|
||||
/* List is part of the left. */
|
||||
format_draw_left(octx, available, ocx, ocy, &s[LEFT],
|
||||
&s[CENTRE], &s[RIGHT], &s[LIST], &s[LIST_LEFT],
|
||||
&s[LIST_RIGHT], &s[AFTER], focus_start, focus_end, &frs);
|
||||
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
|
||||
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
|
||||
focus_start, focus_end, &frs);
|
||||
break;
|
||||
case STYLE_ALIGN_CENTRE:
|
||||
/* List is part of the centre. */
|
||||
format_draw_centre(octx, available, ocx, ocy, &s[LEFT],
|
||||
&s[CENTRE], &s[RIGHT], &s[LIST], &s[LIST_LEFT],
|
||||
&s[LIST_RIGHT], &s[AFTER], focus_start, focus_end, &frs);
|
||||
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
|
||||
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
|
||||
focus_start, focus_end, &frs);
|
||||
break;
|
||||
case STYLE_ALIGN_RIGHT:
|
||||
/* List is part of the right. */
|
||||
format_draw_right(octx, available, ocx, ocy, &s[LEFT],
|
||||
&s[CENTRE], &s[RIGHT], &s[LIST], &s[LIST_LEFT],
|
||||
&s[LIST_RIGHT], &s[AFTER], focus_start, focus_end, &frs);
|
||||
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
|
||||
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
|
||||
focus_start, focus_end, &frs);
|
||||
break;
|
||||
case STYLE_ALIGN_ABSOLUTE_CENTRE:
|
||||
/* List is in the centre of the entire horizontal space. */
|
||||
format_draw_absolute_centre(octx, available, ocx, ocy, &s[LEFT],
|
||||
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
|
||||
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
|
||||
focus_start, focus_end, &frs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ static const char *options_table_status_keys_list[] = {
|
||||
"emacs", "vi", NULL
|
||||
};
|
||||
static const char *options_table_status_justify_list[] = {
|
||||
"left", "centre", "right", NULL
|
||||
"left", "centre", "right", "absolute-centre", NULL
|
||||
};
|
||||
static const char *options_table_status_position_list[] = {
|
||||
"top", "bottom", NULL
|
||||
|
4
style.c
4
style.c
@ -139,6 +139,8 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in)
|
||||
sy->align = STYLE_ALIGN_CENTRE;
|
||||
else if (strcasecmp(tmp + 6, "right") == 0)
|
||||
sy->align = STYLE_ALIGN_RIGHT;
|
||||
else if (strcasecmp(tmp + 6, "absolute-centre") == 0)
|
||||
sy->align = STYLE_ALIGN_ABSOLUTE_CENTRE;
|
||||
else
|
||||
goto error;
|
||||
} else if (end > 5 && strncasecmp(tmp, "fill=", 5) == 0) {
|
||||
@ -227,6 +229,8 @@ style_tostring(struct style *sy)
|
||||
tmp = "centre";
|
||||
else if (sy->align == STYLE_ALIGN_RIGHT)
|
||||
tmp = "right";
|
||||
else if (sy->align == STYLE_ALIGN_ABSOLUTE_CENTRE)
|
||||
tmp = "absolute-centre";
|
||||
off += xsnprintf(s + off, sizeof s - off, "%salign=%s", comma,
|
||||
tmp);
|
||||
comma = ",";
|
||||
|
7
tmux.1
7
tmux.1
@ -3815,10 +3815,11 @@ seconds.
|
||||
By default, updates will occur every 15 seconds.
|
||||
A setting of zero disables redrawing at interval.
|
||||
.It Xo Ic status-justify
|
||||
.Op Ic left | centre | right
|
||||
.Op Ic left | centre | right | absolute-centre
|
||||
.Xc
|
||||
Set the position of the window list component of the status line: left, centre
|
||||
or right justified.
|
||||
Set the position of the window list in the status line: left, centre or right.
|
||||
centre puts the window list in the relative centre of the available free space;
|
||||
absolute-centre uses the centre of the entire horizontal space.
|
||||
.It Xo Ic status-keys
|
||||
.Op Ic vi | emacs
|
||||
.Xc
|
||||
|
Loading…
Reference in New Issue
Block a user