version 1.21, 2012/07/10 11:53:01 |
version 1.22, 2012/08/11 06:45:33 |
|
|
void window_choose_scroll_up(struct window_pane *); |
void window_choose_scroll_up(struct window_pane *); |
void window_choose_scroll_down(struct window_pane *); |
void window_choose_scroll_down(struct window_pane *); |
|
|
|
enum window_choose_input_type { |
|
WINDOW_CHOOSE_NORMAL = -1, |
|
WINDOW_CHOOSE_GOTO_ITEM, |
|
}; |
|
|
const struct window_mode window_choose_mode = { |
const struct window_mode window_choose_mode = { |
window_choose_init, |
window_choose_init, |
window_choose_free, |
window_choose_free, |
|
|
struct mode_key_data mdata; |
struct mode_key_data mdata; |
|
|
ARRAY_DECL(, struct window_choose_mode_item) list; |
ARRAY_DECL(, struct window_choose_mode_item) list; |
|
int width; |
u_int top; |
u_int top; |
u_int selected; |
u_int selected; |
|
enum window_choose_input_type input_type; |
|
const char *input_prompt; |
|
char *input_str; |
|
|
void (*callbackfn)(struct window_choose_data *); |
void (*callbackfn)(struct window_choose_data *); |
void (*freefn)(struct window_choose_data *); |
void (*freefn)(struct window_choose_data *); |
}; |
}; |
|
|
int window_choose_key_index(struct window_choose_mode_data *, u_int); |
int window_choose_index_key(int); |
int window_choose_index_key(struct window_choose_mode_data *, int); |
void window_choose_prompt_input(enum window_choose_input_type, |
|
const char *, struct window_pane *, int); |
|
|
void |
void |
window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) |
window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) |
{ |
{ |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_data *data = wp->modedata; |
struct window_choose_mode_item *item; |
struct window_choose_mode_item *item; |
|
int width; |
|
char tmp[10]; |
|
|
ARRAY_EXPAND(&data->list, 1); |
ARRAY_EXPAND(&data->list, 1); |
item = &ARRAY_LAST(&data->list); |
item = &ARRAY_LAST(&data->list); |
|
|
item->name = format_expand(wcd->ft, wcd->ft_template); |
item->name = format_expand(wcd->ft, wcd->ft_template); |
item->wcd = wcd; |
item->wcd = wcd; |
|
item->pos = ARRAY_LENGTH(&data->list) - 1; |
|
|
|
width = snprintf (tmp, sizeof tmp, "%u", item->pos); |
|
if (width > data->width) |
|
data->width = width; |
} |
} |
|
|
void |
void |
|
|
|
|
data->callbackfn = NULL; |
data->callbackfn = NULL; |
data->freefn = NULL; |
data->freefn = NULL; |
|
data->input_type = WINDOW_CHOOSE_NORMAL; |
|
data->input_str = xstrdup(""); |
|
data->input_prompt = NULL; |
|
|
ARRAY_INIT(&data->list); |
ARRAY_INIT(&data->list); |
data->top = 0; |
data->top = 0; |
|
|
free(item->name); |
free(item->name); |
} |
} |
ARRAY_FREE(&data->list); |
ARRAY_FREE(&data->list); |
|
free(data->input_str); |
|
|
screen_free(&data->screen); |
screen_free(&data->screen); |
free(data); |
free(data); |
|
|
wp->mode = oldmode; |
wp->mode = oldmode; |
} |
} |
|
|
|
void |
|
window_choose_prompt_input(enum window_choose_input_type input_type, |
|
const char *prompt, struct window_pane *wp, int key) |
|
{ |
|
struct window_choose_mode_data *data = wp->modedata; |
|
size_t input_len; |
|
|
|
data->input_type = input_type; |
|
data->input_prompt = prompt; |
|
input_len = strlen(data->input_str) + 2; |
|
|
|
data->input_str = xrealloc(data->input_str, 1, input_len); |
|
data->input_str[input_len - 2] = key; |
|
data->input_str[input_len - 1] = '\0'; |
|
|
|
window_choose_redraw_screen(wp); |
|
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
void |
window_choose_key(struct window_pane *wp, unused struct session *sess, int key) |
window_choose_key(struct window_pane *wp, unused struct session *sess, int key) |
|
|
struct screen *s = &data->screen; |
struct screen *s = &data->screen; |
struct screen_write_ctx ctx; |
struct screen_write_ctx ctx; |
struct window_choose_mode_item *item; |
struct window_choose_mode_item *item; |
u_int items; |
size_t input_len; |
|
u_int items, n; |
int idx; |
int idx; |
|
|
items = ARRAY_LENGTH(&data->list); |
items = ARRAY_LENGTH(&data->list); |
|
|
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
break; |
break; |
case MODEKEYCHOICE_CHOOSE: |
case MODEKEYCHOICE_CHOOSE: |
item = &ARRAY_ITEM(&data->list, data->selected); |
switch (data->input_type) { |
window_choose_fire_callback(wp, item->wcd); |
case WINDOW_CHOOSE_NORMAL: |
window_pane_reset_mode(wp); |
item = &ARRAY_ITEM(&data->list, data->selected); |
|
window_choose_fire_callback(wp, item->wcd); |
|
window_pane_reset_mode(wp); |
|
break; |
|
case WINDOW_CHOOSE_GOTO_ITEM: |
|
n = strtonum(data->input_str, 0, INT_MAX, NULL); |
|
if (n > items - 1) |
|
break; |
|
item = &ARRAY_ITEM(&data->list, n); |
|
window_choose_fire_callback(wp, item->wcd); |
|
window_pane_reset_mode(wp); |
|
break; |
|
} |
break; |
break; |
case MODEKEYCHOICE_UP: |
case MODEKEYCHOICE_UP: |
if (items == 0) |
if (items == 0) |
|
|
data->top = data->selected; |
data->top = data->selected; |
window_choose_redraw_screen(wp); |
window_choose_redraw_screen(wp); |
break; |
break; |
default: |
case MODEKEYCHOICE_BACKSPACE: |
idx = window_choose_index_key(data, key); |
input_len = strlen(data->input_str); |
if (idx < 0 || (u_int) idx >= ARRAY_LENGTH(&data->list)) |
if (input_len > 0) |
|
data->input_str[input_len - 1] = '\0'; |
|
window_choose_redraw_screen(wp); |
|
break; |
|
case MODEKEYCHOICE_STARTNUMBERPREFIX: |
|
if (key < '0' && key > '9') |
break; |
break; |
data->selected = idx; |
|
|
|
item = &ARRAY_ITEM(&data->list, data->selected); |
/* |
window_choose_fire_callback(wp, item->wcd); |
* If there's less than ten items (0-9) then pressing a number |
window_pane_reset_mode(wp); |
* will automatically select that item; otherwise, prompt for |
|
* the item to go to. |
|
*/ |
|
if (ARRAY_LENGTH(&data->list) - 1 <= 9) { |
|
idx = window_choose_index_key(key); |
|
if (idx < 0 || (u_int) idx >= ARRAY_LENGTH(&data->list)) |
|
break; |
|
data->selected = idx; |
|
|
|
item = &ARRAY_ITEM(&data->list, data->selected); |
|
window_choose_fire_callback(wp, item->wcd); |
|
window_pane_reset_mode(wp); |
|
} else { |
|
window_choose_prompt_input( |
|
WINDOW_CHOOSE_GOTO_ITEM, "Goto item", wp, key); |
|
} |
break; |
break; |
|
default: |
|
break; |
} |
} |
} |
} |
|
|
|
|
struct options *oo = &wp->window->options; |
struct options *oo = &wp->window->options; |
struct screen *s = &data->screen; |
struct screen *s = &data->screen; |
struct grid_cell gc; |
struct grid_cell gc; |
int utf8flag, key; |
size_t last, xoff = 0; |
|
char hdr[32]; |
|
int utf8flag; |
|
|
if (data->callbackfn == NULL) |
if (data->callbackfn == NULL) |
fatalx("called before callback assigned"); |
fatalx("called before callback assigned"); |
|
|
|
last = screen_size_y(s) - 1; |
utf8flag = options_get_number(&wp->window->options, "utf8"); |
utf8flag = options_get_number(&wp->window->options, "utf8"); |
memcpy(&gc, &grid_default_cell, sizeof gc); |
memcpy(&gc, &grid_default_cell, sizeof gc); |
if (data->selected == data->top + py) { |
if (data->selected == data->top + py) |
colour_set_fg(&gc, options_get_number(oo, "mode-fg")); |
window_mode_attrs(&gc, oo); |
colour_set_bg(&gc, options_get_number(oo, "mode-bg")); |
|
gc.attr |= options_get_number(oo, "mode-attr"); |
|
} |
|
|
|
screen_write_cursormove(ctx, 0, py); |
screen_write_cursormove(ctx, 0, py); |
if (data->top + py < ARRAY_LENGTH(&data->list)) { |
if (data->top + py < ARRAY_LENGTH(&data->list)) { |
item = &ARRAY_ITEM(&data->list, data->top + py); |
item = &ARRAY_ITEM(&data->list, data->top + py); |
key = window_choose_key_index(data, data->top + py); |
screen_write_nputs(ctx, screen_size_x(s) - 1, |
if (key != -1) { |
&gc, utf8flag, "(%*d) %s", data->width, |
screen_write_nputs(ctx, screen_size_x(s) - 1, |
item->pos, item->name); |
&gc, utf8flag, "(%c) %s", key, item->name); |
|
} else { |
|
screen_write_nputs(ctx, screen_size_x(s) - 1, |
|
&gc, utf8flag, " %s", item->name); |
|
} |
|
|
|
} |
} |
while (s->cx < screen_size_x(s)) |
while (s->cx < screen_size_x(s)) |
screen_write_putc(ctx, &gc, ' '); |
screen_write_putc(ctx, &gc, ' '); |
} |
|
|
|
int |
if (data->input_type != WINDOW_CHOOSE_NORMAL) { |
window_choose_key_index(struct window_choose_mode_data *data, u_int idx) |
window_mode_attrs(&gc, oo); |
{ |
|
static const char keys[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
|
const char *ptr; |
|
int mkey; |
|
|
|
for (ptr = keys; *ptr != '\0'; ptr++) { |
xoff = xsnprintf(hdr, sizeof hdr, |
mkey = mode_key_lookup(&data->mdata, *ptr); |
"%s: %s", data->input_prompt, data->input_str); |
if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) |
screen_write_cursormove(ctx, 0, last); |
continue; |
screen_write_puts(ctx, &gc, "%s", hdr); |
if (idx-- == 0) |
screen_write_cursormove(ctx, xoff, py); |
return (*ptr); |
memcpy(&gc, &grid_default_cell, sizeof gc); |
} |
} |
return (-1); |
|
} |
} |
|
|
int |
int |
window_choose_index_key(struct window_choose_mode_data *data, int key) |
window_choose_index_key(int key) |
{ |
{ |
static const char keys[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
static const char keys[] = "0123456789"; |
const char *ptr; |
const char *ptr; |
int mkey; |
|
u_int idx = 0; |
u_int idx = 0; |
|
|
for (ptr = keys; *ptr != '\0'; ptr++) { |
for (ptr = keys; *ptr != '\0'; ptr++) { |
mkey = mode_key_lookup(&data->mdata, *ptr); |
|
if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) |
|
continue; |
|
if (key == *ptr) |
if (key == *ptr) |
return (idx); |
return (idx); |
idx++; |
idx++; |
|
|
|
|
struct window_choose_data * |
struct window_choose_data * |
window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx, |
window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx, |
struct session *s, const char *template, char *action, u_int idx) |
struct session *s, const char *template, char *action, u_int idx) |
{ |
{ |
struct window_choose_data *wcd; |
struct window_choose_data *wcd; |
|
|
|
|
|
|
struct window_choose_data * |
struct window_choose_data * |
window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx, |
window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx, |
struct session *s, struct winlink *wl, const char *template, |
struct session *s, struct winlink *wl, const char *template, |
char *action, u_int idx) |
char *action, u_int idx) |
{ |
{ |
struct window_choose_data *wcd; |
struct window_choose_data *wcd; |
char *action_data; |
char *action_data; |