summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/menu.h
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-22 08:41:20 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-22 08:41:20 +0000
commit1d0f57cbceb778139ca215cc4fcfd1584951f6dd (patch)
treecafd60c944c51fcce778aa5d6912bc548c518339 /crawl-ref/source/menu.h
parent6f5e187a9e5cd348296dba2fd89d2e206e775a01 (diff)
downloadcrawl-ref-1d0f57cbceb778139ca215cc4fcfd1584951f6dd.tar.gz
crawl-ref-1d0f57cbceb778139ca215cc4fcfd1584951f6dd.zip
Merged stone_soup r15:451 into trunk.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@452 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/menu.h')
-rw-r--r--crawl-ref/source/menu.h251
1 files changed, 222 insertions, 29 deletions
diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h
index 05e4796383..441685e11a 100644
--- a/crawl-ref/source/menu.h
+++ b/crawl-ref/source/menu.h
@@ -5,6 +5,7 @@
#include <vector>
#include <algorithm>
#include "AppHdr.h"
+#include "externs.h"
#include "defines.h"
#include "libutil.h"
@@ -33,7 +34,8 @@ struct menu_letter
return *this;
}
- menu_letter operator ++ (int postfix)
+ // dummy postfix argument unnamed to stop gcc from complaining
+ menu_letter operator ++ (int)
{
menu_letter copy = *this;
this->operator++();
@@ -41,6 +43,77 @@ struct menu_letter
}
};
+class formatted_string
+{
+public:
+ formatted_string() : ops() { }
+ formatted_string(const std::string &s, bool init_style = false);
+
+ operator std::string() const;
+ void display(int start = 0, int end = -1) const;
+ std::string tostring(int start = 0, int end = -1) const;
+
+ void cprintf(const char *s, ...);
+ void cprintf(const std::string &s);
+ void gotoxy(int x, int y);
+ void movexy(int delta_x, int delta_y);
+ void textcolor(int color);
+
+ void clear();
+
+ std::string::size_type length() const;
+
+ const formatted_string &operator += (const formatted_string &other);
+
+public:
+ static formatted_string parse_string(
+ const std::string &s,
+ bool eol_ends_format = true,
+ bool (*process_tag)(const std::string &tag) = NULL );
+
+private:
+ enum fs_op_type
+ {
+ FSOP_COLOUR,
+ FSOP_CURSOR,
+ FSOP_TEXT
+ };
+
+ static int get_colour(const std::string &tag);
+
+private:
+ struct fs_op
+ {
+ fs_op_type type;
+ int x, y;
+ bool relative;
+ std::string text;
+
+ fs_op(int color)
+ : type(FSOP_COLOUR), x(color), y(-1), relative(false), text()
+ {
+ }
+
+ fs_op(int cx, int cy, bool rel = false)
+ : type(FSOP_CURSOR), x(cx), y(cy), relative(rel), text()
+ {
+ }
+
+ fs_op(const std::string &s)
+ : type(FSOP_TEXT), x(-1), y(-1), relative(false), text(s)
+ {
+ }
+
+ operator fs_op_type () const
+ {
+ return type;
+ }
+ void display() const;
+ };
+
+ std::vector<fs_op> ops;
+};
+
struct item_def;
struct MenuEntry
{
@@ -51,7 +124,7 @@ struct MenuEntry
MenuEntryLevel level;
void *data;
- MenuEntry( const std::string &txt = std::string(""),
+ MenuEntry( const std::string &txt = std::string(),
MenuEntryLevel lev = MEL_ITEM,
int qty = 0,
int hotk = 0 ) :
@@ -66,6 +139,10 @@ struct MenuEntry
}
virtual ~MenuEntry() { }
+ bool operator<( const MenuEntry& rhs ) const {
+ return text < rhs.text;
+ }
+
void add_hotkey( int key )
{
if (key && !is_hotkey(key))
@@ -91,8 +168,7 @@ struct MenuEntry
"%c - %s", hotkeys[0], text.c_str());
return std::string(buf);
}
- return std::string(level == MEL_SUBTITLE? " " :
- level == MEL_ITEM? "" : " ") + text;
+ return text;
}
virtual bool selected() const
@@ -118,15 +194,19 @@ public:
enum MenuFlag
{
- MF_NOSELECT = 0, // No selection is permitted
- MF_SINGLESELECT = 1, // Select just one item
- MF_MULTISELECT = 2, // Select multiple items
- MF_NO_SELECT_QTY = 4, // Disallow partial selections
- MF_ANYPRINTABLE = 8, // Any printable character is valid, and
- // closes the menu.
- MF_SELECT_ANY_PAGE = 16, // Allow selections to occur on any page.
-
- MF_EASY_EXIT = 64
+ MF_NOSELECT = 0x0000, // No selection is permitted
+ MF_SINGLESELECT = 0x0001, // Select just one item
+ MF_MULTISELECT = 0x0002, // Select multiple items
+ MF_NO_SELECT_QTY = 0x0004, // Disallow partial selections
+ MF_ANYPRINTABLE = 0x0008, // Any printable character is valid, and
+ // closes the menu.
+ MF_SELECT_BY_PAGE = 0x0010, // Allow selections to occur only on
+ // currently visible page.
+
+ MF_ALWAYS_SHOW_MORE = 0x0020, // Always show the -more- footer
+ MF_NOWRAP = 0x0040, // Paging past the end will not wrap back.
+
+ MF_EASY_EXIT = 0x1000
};
///////////////////////////////////////////////////////////////////////
@@ -142,18 +222,28 @@ public:
Menu( int flags = MF_MULTISELECT );
virtual ~Menu();
- void set_flags( int new_flags ) { this->flags = new_flags; }
+ // Remove all items from the Menu, leave title intact.
+ void clear();
+
+ // Sets menu flags to new_flags. If use_options is true, game options may
+ // override options.
+ void set_flags(int new_flags, bool use_options = true);
int get_flags() const { return flags; }
- bool is_set( int flag ) const;
+ virtual bool is_set( int flag ) const;
bool draw_title_suffix( const std::string &s, bool titlefirst = true );
void update_title();
+
+ // Sets a replacement for the --more-- string.
+ void set_more(const formatted_string &more);
void set_highlighter( MenuHighlighter *h );
void set_title( MenuEntry *e );
void add_entry( MenuEntry *entry );
void get_selected( std::vector<MenuEntry*> *sel ) const;
+ void set_maxpagesize(int max);
+
void set_select_filter( std::vector<text_pattern> filter )
{
select_filter = filter;
@@ -162,22 +252,31 @@ public:
unsigned char getkey() const { return lastch; }
void reset();
- std::vector<MenuEntry *> show();
+ std::vector<MenuEntry *> show(bool reuse_selections = false);
+ std::vector<MenuEntry *> selected_entries() const;
+
+ size_t item_count() const { return items.size(); }
public:
typedef std::string (*selitem_tfn)( const std::vector<MenuEntry*> *sel );
+ typedef void (*drawitem_tfn)(int index, const MenuEntry *me);
+ typedef int (*keyfilter_tfn)(int keyin);
- selitem_tfn selitem_text;
+ selitem_tfn f_selitem;
+ drawitem_tfn f_drawitem;
+ keyfilter_tfn f_keyfilter;
protected:
MenuEntry *title;
int flags;
int first_entry, y_offset;
- int pagesize;
+ int pagesize, max_pagesize;
+
+ formatted_string more;
std::vector<MenuEntry*> items;
- std::vector<MenuEntry*> *sel;
+ std::vector<MenuEntry*> sel;
std::vector<text_pattern> select_filter;
// Class that is queried to colour menu entries.
@@ -189,28 +288,122 @@ protected:
bool alive;
- void do_menu( std::vector<MenuEntry*> *selected );
- virtual void draw_select_count( int count );
- void draw_item( int index ) const;
+protected:
+ void do_menu();
+ virtual void draw_select_count(int count, bool force = false);
+ virtual void draw_item( int index ) const;
+ virtual void draw_item(int index, const MenuEntry *me) const;
+ virtual void draw_stock_item(int index, const MenuEntry *me) const;
+
virtual void draw_title();
- void draw_menu( std::vector<MenuEntry*> *selected );
- bool page_down();
- bool line_down();
- bool page_up();
- bool line_up();
+ virtual void write_title();
+ virtual void draw_menu();
+ virtual bool page_down();
+ virtual bool line_down();
+ virtual bool page_up();
+ virtual bool line_up();
+
+ virtual int pre_process(int key);
+ virtual int post_process(int key);
+
+ bool in_page(int index) const;
void deselect_all(bool update_view = true);
- void select_items( int key, int qty = -1 );
+ virtual void select_items( int key, int qty = -1 );
void select_index( int index, int qty = -1 );
bool is_hotkey(int index, int key );
bool is_selectable(int index) const;
- int item_colour(const MenuEntry *me) const;
+ virtual int item_colour(int index, const MenuEntry *me) const;
virtual bool process_key( int keyin );
};
+// Uses a sliding selector rather than hotkeyed selection.
+class slider_menu : public Menu
+{
+public:
+ // Multiselect would be awkward to implement.
+ slider_menu(int flags = MF_SINGLESELECT);
+ void display();
+ std::vector<MenuEntry *> show();
+
+ void set_search(const std::string &search);
+ void set_limits(int starty, int endy);
+ const MenuEntry *selected_entry() const;
+
+protected:
+ int item_colour(int index, const MenuEntry *me) const;
+ void draw_stock_item(int index, const MenuEntry *me) const;
+ void draw_menu();
+
+ void new_selection(int nsel);
+ bool move_selection(int nsel);
+
+ bool page_down();
+ bool line_down();
+ bool page_up();
+ bool line_up();
+
+ bool is_set(int flag) const;
+ void select_items( int key, int qty );
+ bool fix_entry();
+ bool process_key( int keyin );
+
+ int post_process(int key);
+
+ void select_search(const std::string &search);
+
+protected:
+ formatted_string less;
+ int starty, endy;
+ int selected;
+ std::string search;
+};
+
+// This is only tangentially related to menus, but what the heck.
+// Note, column margins start on 1, not 0.
+class column_composer
+{
+public:
+ // Number of columns and left margins for 2nd, 3rd, ... nth column.
+ column_composer(int ncols, ...);
+
+ void clear();
+ void add_formatted(int ncol,
+ const std::string &tagged_text,
+ bool add_separator = true,
+ bool eol_ends_format = true,
+ bool (*text_filter)(const std::string &tag) = NULL,
+ int margin = -1);
+
+ std::vector<formatted_string> formatted_lines() const;
+
+ void set_pagesize(int pagesize);
+
+private:
+ struct column;
+ void compose_formatted_column(
+ const std::vector<formatted_string> &lines,
+ int start_col,
+ int margin);
+ void strip_blank_lines(std::vector<formatted_string> &) const;
+
+private:
+ struct column
+ {
+ int margin;
+ int lines;
+
+ column(int marg = 1) : margin(marg), lines(0) { }
+ };
+
+ int ncols, pagesize;
+ std::vector<column> columns;
+ std::vector<formatted_string> flines;
+};
+
int menu_colour(const std::string &itemtext);
#endif