mirror of
https://github.com/tmux/tmux.git
synced 2025-12-18 00:02:54 -05:00
Add box border drawing for active pane
Add screen_redraw_draw_active_box() to draw a complete box border around the active pane when box mode is enabled: - Draw styled border (using pane-active-border-style) for active pane - Draw blank spaces for inactive pane border areas - Skip normal pane separator borders when box mode is active - Adjust pane content drawing to account for box mode offset - Call box drawing on border redraws, window redraws, and pane redraws The box border uses the configured pane-border-lines style for the line drawing characters.
This commit is contained in:
parent
3d3cdaedda
commit
27baf46563
165
screen-redraw.c
165
screen-redraw.c
@ -35,6 +35,7 @@ static void screen_redraw_draw_scrollbar(struct screen_redraw_ctx *,
|
||||
struct window_pane *, int, int, int, u_int, u_int, u_int);
|
||||
static void screen_redraw_draw_pane_scrollbar(struct screen_redraw_ctx *,
|
||||
struct window_pane *);
|
||||
static void screen_redraw_draw_active_box(struct screen_redraw_ctx *);
|
||||
|
||||
#define START_ISOLATE "\342\201\246"
|
||||
#define END_ISOLATE "\342\201\251"
|
||||
@ -662,11 +663,13 @@ screen_redraw_screen(struct client *c)
|
||||
screen_redraw_draw_borders(&ctx);
|
||||
if (ctx.pane_status != PANE_STATUS_OFF)
|
||||
screen_redraw_draw_pane_status(&ctx);
|
||||
screen_redraw_draw_active_box(&ctx);
|
||||
screen_redraw_draw_pane_scrollbars(&ctx);
|
||||
}
|
||||
if (flags & CLIENT_REDRAWWINDOW) {
|
||||
log_debug("%s: redrawing panes", c->name);
|
||||
screen_redraw_draw_panes(&ctx);
|
||||
screen_redraw_draw_active_box(&ctx);
|
||||
screen_redraw_draw_pane_scrollbars(&ctx);
|
||||
}
|
||||
if (ctx.statuslines != 0 &&
|
||||
@ -696,8 +699,10 @@ screen_redraw_pane(struct client *c, struct window_pane *wp,
|
||||
tty_sync_start(&c->tty);
|
||||
tty_update_mode(&c->tty, c->tty.mode, NULL);
|
||||
|
||||
if (!redraw_scrollbar_only)
|
||||
if (!redraw_scrollbar_only) {
|
||||
screen_redraw_draw_pane(&ctx, wp);
|
||||
screen_redraw_draw_active_box(&ctx);
|
||||
}
|
||||
|
||||
if (window_pane_show_scrollbar(wp, ctx.pane_scrollbars))
|
||||
screen_redraw_draw_pane_scrollbar(&ctx, wp);
|
||||
@ -833,11 +838,20 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx)
|
||||
struct client *c = ctx->c;
|
||||
struct session *s = c->session;
|
||||
struct window *w = s->curw->window;
|
||||
struct options *oo = w->options;
|
||||
struct window_pane *wp;
|
||||
u_int i, j;
|
||||
|
||||
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
||||
|
||||
/*
|
||||
* Skip drawing pane separator borders when box mode is active,
|
||||
* since each pane has its own complete box border.
|
||||
*/
|
||||
if (options_get_number(oo, "pane-border-indicators") == PANE_BORDER_BOX &&
|
||||
TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL)
|
||||
return;
|
||||
|
||||
TAILQ_FOREACH(wp, &w->panes, entry)
|
||||
wp->border_gc_set = 0;
|
||||
|
||||
@ -847,6 +861,134 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw box border around the active pane. */
|
||||
static void
|
||||
screen_redraw_draw_active_box(struct screen_redraw_ctx *ctx)
|
||||
{
|
||||
struct client *c = ctx->c;
|
||||
struct session *s = c->session;
|
||||
struct window *w = s->curw->window;
|
||||
struct options *oo = w->options;
|
||||
struct tty *tty = &c->tty;
|
||||
struct window_pane *wp, *active_wp;
|
||||
struct grid_cell gc, blank_gc;
|
||||
struct format_tree *ft;
|
||||
u_int i, top, left, right, bottom, tty_top;
|
||||
int is_active;
|
||||
|
||||
/* Check if box mode is enabled. */
|
||||
if (options_get_number(oo, "pane-border-indicators") != PANE_BORDER_BOX)
|
||||
return;
|
||||
if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) == NULL)
|
||||
return;
|
||||
|
||||
/* Get active pane. */
|
||||
active_wp = server_client_get_pane(c);
|
||||
|
||||
/* Account for status line at top. */
|
||||
if (ctx->statustop)
|
||||
tty_top = ctx->statuslines;
|
||||
else
|
||||
tty_top = 0;
|
||||
|
||||
/* Set up blank cell for inactive pane borders. */
|
||||
memcpy(&blank_gc, &grid_default_cell, sizeof blank_gc);
|
||||
utf8_set(&blank_gc.data, ' ');
|
||||
|
||||
/* Draw border area for all panes. */
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (!window_pane_visible(wp))
|
||||
continue;
|
||||
if (wp->sx < 3 || wp->sy < 3)
|
||||
continue;
|
||||
|
||||
is_active = (wp == active_wp);
|
||||
|
||||
log_debug("%s: %s @%u %%%u active=%d", __func__, c->name,
|
||||
w->id, wp->id, is_active);
|
||||
|
||||
/* Calculate box position. */
|
||||
left = wp->xoff;
|
||||
right = wp->xoff + wp->sx - 1;
|
||||
top = wp->yoff;
|
||||
bottom = wp->yoff + wp->sy - 1;
|
||||
|
||||
if (is_active) {
|
||||
/* Set up grid cell with active border style. */
|
||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||
ft = format_create_defaults(NULL, c, s, s->curw, wp);
|
||||
style_apply(&gc, oo, "pane-active-border-style", ft);
|
||||
format_free(ft);
|
||||
}
|
||||
|
||||
/* Draw top border. */
|
||||
for (i = left; i <= right; i++) {
|
||||
if (is_active) {
|
||||
if (i == left)
|
||||
screen_redraw_border_set(w, wp,
|
||||
ctx->pane_lines, CELL_TOPLEFT, &gc);
|
||||
else if (i == right)
|
||||
screen_redraw_border_set(w, wp,
|
||||
ctx->pane_lines, CELL_TOPRIGHT, &gc);
|
||||
else
|
||||
screen_redraw_border_set(w, wp,
|
||||
ctx->pane_lines, CELL_LEFTRIGHT, &gc);
|
||||
tty_cursor(tty, i, tty_top + top);
|
||||
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||
} else {
|
||||
tty_cursor(tty, i, tty_top + top);
|
||||
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw bottom border. */
|
||||
for (i = left; i <= right; i++) {
|
||||
if (is_active) {
|
||||
if (i == left)
|
||||
screen_redraw_border_set(w, wp,
|
||||
ctx->pane_lines, CELL_BOTTOMLEFT, &gc);
|
||||
else if (i == right)
|
||||
screen_redraw_border_set(w, wp,
|
||||
ctx->pane_lines, CELL_BOTTOMRIGHT, &gc);
|
||||
else
|
||||
screen_redraw_border_set(w, wp,
|
||||
ctx->pane_lines, CELL_LEFTRIGHT, &gc);
|
||||
tty_cursor(tty, i, tty_top + bottom);
|
||||
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||
} else {
|
||||
tty_cursor(tty, i, tty_top + bottom);
|
||||
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw left border (excluding corners). */
|
||||
for (i = top + 1; i < bottom; i++) {
|
||||
if (is_active) {
|
||||
screen_redraw_border_set(w, wp, ctx->pane_lines,
|
||||
CELL_TOPBOTTOM, &gc);
|
||||
tty_cursor(tty, left, tty_top + i);
|
||||
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||
} else {
|
||||
tty_cursor(tty, left, tty_top + i);
|
||||
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw right border (excluding corners). */
|
||||
for (i = top + 1; i < bottom; i++) {
|
||||
if (is_active) {
|
||||
screen_redraw_border_set(w, wp, ctx->pane_lines,
|
||||
CELL_TOPBOTTOM, &gc);
|
||||
tty_cursor(tty, right, tty_top + i);
|
||||
tty_cell(tty, &gc, &grid_default_cell, NULL, NULL);
|
||||
} else {
|
||||
tty_cursor(tty, right, tty_top + i);
|
||||
tty_cell(tty, &blank_gc, &grid_default_cell, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the panes. */
|
||||
static void
|
||||
screen_redraw_draw_panes(struct screen_redraw_ctx *ctx)
|
||||
@ -896,8 +1038,11 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
||||
struct colour_palette *palette = &wp->palette;
|
||||
struct grid_cell defaults;
|
||||
u_int i, j, top, x, y, width;
|
||||
int box_mode;
|
||||
|
||||
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
|
||||
box_mode = window_pane_box_mode(wp);
|
||||
log_debug("%s: %s @%u %%%u box=%d", __func__, c->name, w->id, wp->id,
|
||||
box_mode);
|
||||
|
||||
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx)
|
||||
return;
|
||||
@ -905,34 +1050,44 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
||||
top = ctx->statuslines;
|
||||
else
|
||||
top = 0;
|
||||
for (j = 0; j < wp->sy; j++) {
|
||||
for (j = 0; j < (box_mode ? wp->sy - 2 : wp->sy); j++) {
|
||||
if (wp->yoff + j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy)
|
||||
continue;
|
||||
y = top + wp->yoff + j - ctx->oy;
|
||||
|
||||
if (wp->xoff >= ctx->ox &&
|
||||
if (box_mode) {
|
||||
/* Box mode: draw at offset position. */
|
||||
y = top + wp->yoff + 1 + j - ctx->oy;
|
||||
i = 0;
|
||||
x = wp->xoff + 1 - ctx->ox;
|
||||
width = wp->sx - 2;
|
||||
} else if (wp->xoff >= ctx->ox &&
|
||||
wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
|
||||
/* All visible. */
|
||||
y = top + wp->yoff + j - ctx->oy;
|
||||
i = 0;
|
||||
x = wp->xoff - ctx->ox;
|
||||
width = wp->sx;
|
||||
} else if (wp->xoff < ctx->ox &&
|
||||
wp->xoff + wp->sx > ctx->ox + ctx->sx) {
|
||||
/* Both left and right not visible. */
|
||||
y = top + wp->yoff + j - ctx->oy;
|
||||
i = ctx->ox;
|
||||
x = 0;
|
||||
width = ctx->sx;
|
||||
} else if (wp->xoff < ctx->ox) {
|
||||
/* Left not visible. */
|
||||
y = top + wp->yoff + j - ctx->oy;
|
||||
i = ctx->ox - wp->xoff;
|
||||
x = 0;
|
||||
width = wp->sx - i;
|
||||
} else {
|
||||
/* Right not visible. */
|
||||
y = top + wp->yoff + j - ctx->oy;
|
||||
i = 0;
|
||||
x = wp->xoff - ctx->ox;
|
||||
width = ctx->sx - x;
|
||||
}
|
||||
|
||||
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
|
||||
__func__, c->name, wp->id, i, j, x, y, width);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user