2013-12-08 04:43:40 +08:00
|
|
|
/** \file pager.h
|
|
|
|
Pager support
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "complete.h"
|
|
|
|
#include "screen.h"
|
2014-01-27 16:56:13 +08:00
|
|
|
#include "reader.h"
|
2013-12-08 04:43:40 +08:00
|
|
|
|
2014-01-27 18:17:31 +08:00
|
|
|
#define PAGER_SELECTION_NONE ((size_t)(-1))
|
|
|
|
|
2013-12-08 04:43:40 +08:00
|
|
|
/* Represents rendering from the pager */
|
2014-01-18 04:04:03 +08:00
|
|
|
class page_rendering_t
|
2013-12-08 04:43:40 +08:00
|
|
|
{
|
2014-04-01 01:01:39 +08:00
|
|
|
public:
|
2014-01-18 04:04:03 +08:00
|
|
|
int term_width;
|
|
|
|
int term_height;
|
|
|
|
size_t rows;
|
|
|
|
size_t cols;
|
2014-01-22 06:35:18 +08:00
|
|
|
size_t row_start;
|
|
|
|
size_t row_end;
|
2014-01-18 04:04:03 +08:00
|
|
|
size_t selected_completion_idx;
|
2013-12-08 04:43:40 +08:00
|
|
|
screen_data_t screen_data;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-23 09:45:27 +08:00
|
|
|
size_t remaining_to_disclose;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
bool search_field_shown;
|
|
|
|
editable_line_t search_field_line;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-18 04:04:03 +08:00
|
|
|
/* Returns a rendering with invalid data, useful to indicate "no rendering" */
|
|
|
|
page_rendering_t();
|
2013-12-08 04:43:40 +08:00
|
|
|
};
|
|
|
|
|
2014-01-20 08:41:26 +08:00
|
|
|
/* The space between adjacent completions */
|
|
|
|
#define PAGER_SPACER_STRING L" "
|
|
|
|
#define PAGER_SPACER_STRING_WIDTH 2
|
|
|
|
|
2014-01-23 09:45:27 +08:00
|
|
|
/* How many rows we will show in the "initial" pager */
|
|
|
|
#define PAGER_UNDISCLOSED_MAX_ROWS 4
|
|
|
|
|
2013-12-08 04:43:40 +08:00
|
|
|
typedef std::vector<completion_t> completion_list_t;
|
|
|
|
page_rendering_t render_completions(const completion_list_t &raw_completions, const wcstring &prefix);
|
2014-01-14 08:41:22 +08:00
|
|
|
|
|
|
|
class pager_t
|
|
|
|
{
|
2014-01-23 09:45:27 +08:00
|
|
|
int available_term_width;
|
|
|
|
int available_term_height;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
size_t selected_completion_idx;
|
2014-01-22 06:35:18 +08:00
|
|
|
size_t suggested_row_start;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-23 09:45:27 +08:00
|
|
|
/* Fully disclosed means that we show all completions */
|
|
|
|
bool fully_disclosed;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-26 16:41:30 +08:00
|
|
|
/* Whether we show the search field */
|
|
|
|
bool search_field_shown;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-20 08:41:26 +08:00
|
|
|
/* Returns the index of the completion that should draw selected, using the given number of columns */
|
|
|
|
size_t visual_selected_completion_index(size_t rows, size_t cols) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-14 08:41:22 +08:00
|
|
|
/** Data structure describing one or a group of related completions */
|
2014-04-01 01:01:39 +08:00
|
|
|
public:
|
2014-01-14 08:41:22 +08:00
|
|
|
struct comp_t
|
|
|
|
{
|
|
|
|
/** The list of all completin strings this entry applies to */
|
|
|
|
wcstring_list_t comp;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-14 08:41:22 +08:00
|
|
|
/** The description */
|
|
|
|
wcstring desc;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-25 07:59:18 +08:00
|
|
|
/** The representative completion */
|
|
|
|
completion_t representative;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-14 08:41:22 +08:00
|
|
|
/** On-screen width of the completion string */
|
|
|
|
int comp_width;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-14 08:41:22 +08:00
|
|
|
/** On-screen width of the description information */
|
|
|
|
int desc_width;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-25 07:59:18 +08:00
|
|
|
/** Preferred total width */
|
2014-01-14 08:41:22 +08:00
|
|
|
int pref_width;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-14 08:41:22 +08:00
|
|
|
/** Minimum acceptable width */
|
|
|
|
int min_width;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-25 07:59:18 +08:00
|
|
|
comp_t() : comp(), desc(), representative(L""), comp_width(0), desc_width(0), pref_width(0), min_width(0)
|
2014-01-14 08:41:22 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
2014-04-01 01:01:39 +08:00
|
|
|
|
|
|
|
private:
|
2014-01-14 08:41:22 +08:00
|
|
|
typedef std::vector<comp_t> comp_info_list_t;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* The filtered list of completion infos */
|
2014-01-14 08:41:22 +08:00
|
|
|
comp_info_list_t completion_infos;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* The unfiltered list. Note there's a lot of duplication here. */
|
|
|
|
comp_info_list_t unfiltered_completion_infos;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
wcstring prefix;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-25 08:51:52 +08:00
|
|
|
bool completion_try_print(size_t cols, const wcstring &prefix, const comp_info_list_t &lst, page_rendering_t *rendering, size_t suggested_start_row) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-14 08:41:22 +08:00
|
|
|
void recalc_min_widths(comp_info_list_t * lst) const;
|
|
|
|
void measure_completion_infos(std::vector<comp_t> *infos, const wcstring &prefix) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
bool completion_info_passes_filter(const comp_t &info) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-22 06:35:18 +08:00
|
|
|
void completion_print(size_t cols, int *width_per_column, size_t row_start, size_t row_stop, const wcstring &prefix, const comp_info_list_t &lst, page_rendering_t *rendering) const;
|
2014-01-16 10:21:38 +08:00
|
|
|
line_t completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, size_t column, int width, bool secondary, bool selected, page_rendering_t *rendering) const;
|
2014-01-14 08:41:22 +08:00
|
|
|
|
2014-04-01 01:01:39 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* The text of the search field */
|
|
|
|
editable_line_t search_field_line;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Sets the set of completions */
|
2014-01-14 08:41:22 +08:00
|
|
|
void set_completions(const completion_list_t &comp);
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Sets the prefix */
|
|
|
|
void set_prefix(const wcstring &pref);
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Sets the terminal width and height */
|
2014-01-14 08:41:22 +08:00
|
|
|
void set_term_size(int w, int h);
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 18:17:31 +08:00
|
|
|
/* Changes the selected completion in the given direction according to the layout of the given rendering. Returns true if the selection changed. */
|
|
|
|
bool select_next_completion_in_direction(selection_direction_t direction, const page_rendering_t &rendering);
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-20 08:41:26 +08:00
|
|
|
/* Returns the currently selected completion for the given rendering */
|
|
|
|
const completion_t *selected_completion(const page_rendering_t &rendering) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-25 07:59:18 +08:00
|
|
|
/* Indicates the row and column for the given rendering. Returns -1 if no selection. */
|
|
|
|
size_t get_selected_row(const page_rendering_t &rendering) const;
|
|
|
|
size_t get_selected_column(const page_rendering_t &rendering) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Produces a rendering of the completions, at the given term size */
|
2014-01-14 08:41:22 +08:00
|
|
|
page_rendering_t render() const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-18 04:04:03 +08:00
|
|
|
/* Updates the rendering if it's stale */
|
|
|
|
void update_rendering(page_rendering_t *rendering) const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Indicates if there are no completions, and therefore nothing to render */
|
|
|
|
bool empty() const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Clears all completions and the prefix */
|
|
|
|
void clear();
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* Updates the completions list per the filter */
|
|
|
|
void refilter_completions();
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* Sets whether the search field is shown */
|
|
|
|
void set_search_field_shown(bool flag);
|
|
|
|
|
|
|
|
/* Gets whether the search field shown */
|
|
|
|
bool is_search_field_shown() const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* Indicates if we are navigating our contents */
|
|
|
|
bool is_navigating_contents() const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-02-21 05:30:26 +08:00
|
|
|
/* Become fully disclosed */
|
|
|
|
void set_fully_disclosed(bool flag);
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-27 16:56:13 +08:00
|
|
|
/* Position of the cursor */
|
|
|
|
size_t cursor_position() const;
|
2014-04-01 01:01:39 +08:00
|
|
|
|
2014-01-16 10:21:38 +08:00
|
|
|
/* Constructor */
|
|
|
|
pager_t();
|
2014-01-14 08:41:22 +08:00
|
|
|
};
|