/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
struct screen *window_choose_init(struct window_pane *);
void window_choose_free(struct window_pane *);
void window_choose_resize(struct window_pane *, u_int, u_int);
void window_choose_key(struct window_pane *, struct session *, int);
void window_choose_mouse(
struct window_pane *, struct session *, struct mouse_event *);
void window_choose_fire_callback(
struct window_pane *, struct window_choose_data *);
void window_choose_redraw_screen(struct window_pane *);
void window_choose_write_line(
struct window_pane *, struct screen_write_ctx *, u_int);
void window_choose_scroll_up(struct window_pane *);
void window_choose_scroll_down(struct window_pane *);
void window_choose_collapse(struct window_pane *, struct session *);
void window_choose_expand(struct window_pane *, struct session *, u_int);
void window_choose_collapse_all(struct window_pane *);
void window_choose_expand_all(struct window_pane *);
enum window_choose_input_type {
WINDOW_CHOOSE_NORMAL = -1,
WINDOW_CHOOSE_GOTO_ITEM,
};
const struct window_mode window_choose_mode = {
window_choose_init,
window_choose_free,
window_choose_resize,
window_choose_key,
window_choose_mouse,
NULL,
};
struct window_choose_mode_data {
struct screen screen;
struct mode_key_data mdata;
ARRAY_DECL(, struct window_choose_mode_item) list;
ARRAY_DECL(, struct window_choose_mode_item) old_list;
int width;
u_int top;
u_int selected;
enum window_choose_input_type input_type;
const char *input_prompt;
char *input_str;
void (*callbackfn)(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(struct window_choose_mode_data *, int);
void window_choose_prompt_input(enum window_choose_input_type,
const char *, struct window_pane *, int);
void
window_choose_add(struct window_pane *wp, struct window_choose_data *wcd)
{
struct window_choose_mode_data *data = wp->modedata;
struct window_choose_mode_item *item;
char tmp[10];
ARRAY_EXPAND(&data->list, 1);
item = &ARRAY_LAST(&data->list);
item->name = format_expand(wcd->ft, wcd->ft_template);
item->wcd = wcd;
item->pos = ARRAY_LENGTH(&data->list) - 1;
item->state = 0;
data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos);
}
void
window_choose_ready(struct window_pane *wp, u_int cur,
void (*callbackfn)(struct window_choose_data *),
void (*freefn)(struct window_choose_data *))
{
struct window_choose_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
data->selected = cur;
if (data->selected > screen_size_y(s) - 1)
data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s);
data->callbackfn = callbackfn;
data->freefn = freefn;
ARRAY_CONCAT(&data->old_list, &data->list);
window_choose_collapse_all(wp);
window_choose_redraw_screen(wp);
}
struct screen *
window_choose_init(struct window_pane *wp)
{
struct window_choose_mode_data *data;
struct screen *s;
int keys;
wp->modedata = data = xmalloc(sizeof *data);
data->callbackfn = 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->old_list);
data->top = 0;
s = &data->screen;
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;