summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-25 11:13:18 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-25 11:13:18 +0000
commit137d900672cf15df2d5f3cf5988aff20d33620f7 (patch)
treeee5e26fe0d672f0cfa3c1faf5a4fda4d31ff5840 /crawl-ref
parentc5ab08484a85c0f7f25bd8199d0e1c688e08eba3 (diff)
downloadcrawl-ref-137d900672cf15df2d5f3cf5988aff20d33620f7.tar.gz
crawl-ref-137d900672cf15df2d5f3cf5988aff20d33620f7.zip
[1801838] Use a menu to show mutation list so long lists don't scroll off the end of the terminal.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3331 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/cio.h2
-rw-r--r--crawl-ref/source/command.cc44
-rw-r--r--crawl-ref/source/format.cc11
-rw-r--r--crawl-ref/source/format.h5
-rw-r--r--crawl-ref/source/libutil.cc6
-rw-r--r--crawl-ref/source/libutil.h3
-rw-r--r--crawl-ref/source/menu.cc131
-rw-r--r--crawl-ref/source/menu.h17
-rw-r--r--crawl-ref/source/mon-util.cc10
-rw-r--r--crawl-ref/source/mutation.cc9
10 files changed, 170 insertions, 68 deletions
diff --git a/crawl-ref/source/cio.h b/crawl-ref/source/cio.h
index 93e6471df4..75e9ca048d 100644
--- a/crawl-ref/source/cio.h
+++ b/crawl-ref/source/cio.h
@@ -184,7 +184,6 @@ enum KEYS
// Mouse codes.
CK_MOUSE_MOVE = 10001,
-#ifdef USE_TILE
CK_MOUSE_DONE,
CK_MOUSE_B1,
CK_MOUSE_B2,
@@ -193,7 +192,6 @@ enum KEYS
CK_MOUSE_B5,
CK_MOUSE_B1ITEM,
CK_MOUSE_B2ITEM,
-#endif
CK_MOUSE_CLICK
};
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index c8ef7a641b..d94af8de8d 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -1318,19 +1318,58 @@ static int keyhelp_keyfilter(int ch)
return ch;
}
+///////////////////////////////////////////////////////////////////////////
+// Manual menu highlighter.
+
+class help_highlighter : public MenuHighlighter
+{
+public:
+ help_highlighter();
+ int entry_colour(const MenuEntry *entry) const;
+private:
+ text_pattern pattern;
+ std::string get_species_key() const;
+};
+
+help_highlighter::help_highlighter()
+ : pattern(get_species_key())
+{
+}
+
+int help_highlighter::entry_colour(const MenuEntry *entry) const
+{
+ return !pattern.empty() && pattern.matches(entry->text)? WHITE : -1;
+}
+
+// to highlight species in aptitudes list ('?%')
+std::string help_highlighter::get_species_key() const
+{
+ if (player_genus(GENPC_DRACONIAN) && you.experience_level < 7)
+ return "";
+
+ std::string result = species_name(you.species, you.experience_level);
+ if (player_genus(GENPC_DRACONIAN))
+ strip_tag(result,
+ species_name(you.species, you.experience_level, true));
+
+ result += " ";
+ return (result);
+}
+////////////////////////////////////////////////////////////////////////////
+
static void show_keyhelp_menu(const std::vector<formatted_string> &lines,
bool with_manual, bool easy_exit = false,
int hotkey = 0)
{
formatted_scroller cmd_help;
-
+
// Set flags, and use easy exit if necessary.
int flags = MF_NOSELECT | MF_ALWAYS_SHOW_MORE | MF_NOWRAP;
if (easy_exit)
flags |= MF_EASY_EXIT;
cmd_help.set_flags(flags, false);
cmd_help.set_tag("help");
-
+
// FIXME: Allow for hiding Page down when at the end of the listing, ditto
// for page up at start of listing.
cmd_help.set_more( formatted_string::parse_string(
@@ -1339,6 +1378,7 @@ static void show_keyhelp_menu(const std::vector<formatted_string> &lines,
if ( with_manual )
{
+ cmd_help.set_highlighter(new help_highlighter);
cmd_help.f_keyfilter = keyhelp_keyfilter;
column_composer cols(2, 40);
diff --git a/crawl-ref/source/format.cc b/crawl-ref/source/format.cc
index 33bb2a47d1..7d529315a3 100644
--- a/crawl-ref/source/format.cc
+++ b/crawl-ref/source/format.cc
@@ -31,6 +31,12 @@ int formatted_string::get_colour(const std::string &tag)
return (colour != -1? colour : LIGHTGREY);
}
+// Parses a formatted string in much the same way as parse_string, but
+// handles EOL by moving the cursor down to the next line instead of
+// using a literal EOL. This is important if the text is not supposed
+// to clobber existing text to the right of the lines being displayed
+// (some of the tutorial messages need this).
+//
formatted_string formatted_string::parse_block(
const std::string &s,
bool eol_ends_format,
@@ -208,6 +214,11 @@ std::string formatted_string::html_dump() const
return s;
}
+bool formatted_string::operator < (const formatted_string &other) const
+{
+ return std::string(*this) < std::string(other);
+}
+
const formatted_string &
formatted_string::operator += (const formatted_string &other)
{
diff --git a/crawl-ref/source/format.h b/crawl-ref/source/format.h
index 6376849b27..700f958af6 100644
--- a/crawl-ref/source/format.h
+++ b/crawl-ref/source/format.h
@@ -40,6 +40,7 @@ public:
std::string::size_type length() const;
std::string html_dump() const;
+ bool operator < ( const formatted_string &other ) const;
const formatted_string &operator += (const formatted_string &other);
public:
@@ -59,7 +60,6 @@ private:
int find_last_colour() const;
public:
-
struct fs_op
{
fs_op_type type;
@@ -89,7 +89,8 @@ public:
void display() const;
};
- std::vector<fs_op> ops;
+ typedef std::vector<fs_op> oplist;
+ oplist ops;
};
int count_linebreaks(const formatted_string& fs);
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index ac78351bc2..62d7d9374e 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -466,6 +466,12 @@ std::string &trim_string( std::string &str )
return (str);
}
+std::string &trim_string_right( std::string &str )
+{
+ str.erase( str.find_last_not_of( " \t\n\r" ) + 1 );
+ return (str);
+}
+
static void add_segment(std::vector<std::string> &segs,
std::string s,
bool trim,
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 4c64be32e6..11087ffd11 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -91,7 +91,8 @@ typedef void *(*p_compile)(const char *pattern, bool ignore_case);
typedef void (*p_free)(void *cp);
typedef bool (*p_match)(void *compiled_pattern, const char *text, int length);
-std::string & trim_string( std::string &str );
+std::string &trim_string( std::string &str );
+std::string &trim_string_right( std::string &str );
std::string trimmed_string( std::string s );
inline bool starts_with(const std::string &s, const std::string &prefix)
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index c69380419c..81a16be254 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -18,29 +18,87 @@
#include "initfile.h"
Menu::Menu( int _flags, const std::string& tagname )
- : f_selitem(NULL),
- f_drawitem(NULL),
- f_keyfilter(NULL),
- title(NULL),
- flags(_flags),
- tag(tagname),
- first_entry(0),
- y_offset(0),
- pagesize(0),
- max_pagesize(0),
- more("-more-", true),
- items(),
- sel(),
- select_filter(),
- highlighter(new MenuHighlighter),
- num(-1),
- lastch(0),
- alive(false),
- last_selected(-1)
+ : f_selitem(NULL), f_drawitem(NULL), f_keyfilter(NULL), title(NULL),
+ flags(_flags), tag(tagname), first_entry(0), y_offset(0),
+ pagesize(0), max_pagesize(0), more("-more-", true), items(),
+ sel(), select_filter(), highlighter(new MenuHighlighter), num(-1),
+ lastch(0), alive(false), last_selected(-1)
{
set_flags(flags);
}
+Menu::Menu( const formatted_string &fs )
+ : f_selitem(NULL), f_drawitem(NULL), f_keyfilter(NULL), title(NULL),
+
+ // This is a text-viewer menu, init flags to be easy on the user.
+ flags(MF_NOSELECT | MF_EASY_EXIT),
+
+ tag(), first_entry(0), y_offset(0), pagesize(0),
+ max_pagesize(0), more("-more-", true), items(), sel(),
+ select_filter(), highlighter(new MenuHighlighter), num(-1),
+ lastch(0), alive(false), last_selected(-1)
+{
+ int colour = LIGHTGREY;
+ int last_text_colour = LIGHTGREY;
+ std::string line;
+ for (formatted_string::oplist::const_iterator i = fs.ops.begin();
+ i != fs.ops.end(); ++i)
+ {
+ const formatted_string::fs_op &op(*i);
+ switch (op.type)
+ {
+ case FSOP_COLOUR:
+ colour = op.x;
+ break;
+ case FSOP_TEXT:
+ line += op.text;
+ if (op.text.find_first_not_of(" \t\r\n") != std::string::npos)
+ last_text_colour = colour;
+ check_add_formatted_line(last_text_colour, line, true);
+ break;
+ default:
+ break;
+ }
+ }
+ check_add_formatted_line(colour, line, false);
+}
+
+void Menu::check_add_formatted_line(int col, std::string &line, bool check_eol)
+{
+ if (line.empty())
+ return;
+
+ if (check_eol && line.find(EOL) == std::string::npos)
+ return;
+
+ std::vector<std::string> lines = split_string(EOL, line, false, true);
+ int size = lines.size();
+
+ // If we have stuff after EOL, leave that in the line variable and
+ // don't add an entry for it, unless the caller told us not to
+ // check EOL sanity.
+ if (check_eol && !ends_with(line, EOL))
+ line = lines[--size];
+ else
+ line.clear();
+
+ for (int i = 0; i < size; ++i)
+ {
+ std::string &s(lines[i]);
+
+ trim_string_right(s);
+
+ MenuEntry *me = new MenuEntry(s);
+ me->colour = col;
+ if (!title)
+ set_title(me);
+ else
+ add_entry(me);
+ }
+
+ line.clear();
+}
+
Menu::~Menu()
{
for (int i = 0, count = items.size(); i < count; ++i)
@@ -176,16 +234,12 @@ bool Menu::process_key( int keyin )
case CK_ENTER:
return false;
case CK_ESCAPE:
-#ifdef USE_TILE
case CK_MOUSE_B2:
-#endif
sel.clear();
lastch = keyin;
return false;
case ' ': case CK_PGDN: case '>': case '\'':
-#ifdef USE_TILE
case CK_MOUSE_B1:
-#endif
nav = true;
repaint = page_down();
if (!repaint && !is_set(MF_EASY_EXIT) && !is_set(MF_NOWRAP))
@@ -579,42 +633,11 @@ void Menu::update_title()
gotoxy(x, y);
}
-// to highlight species in aptitudes list ('?%')
-static std::string get_species_key()
-{
- if (player_genus(GENPC_DRACONIAN) && you.experience_level < 7)
- return "";
-
- std::string result = "";
- switch (you.species)
- {
- case SP_RED_DRACONIAN: result = "Red"; break;
- case SP_WHITE_DRACONIAN: result = "White"; break;
- case SP_GREEN_DRACONIAN: result = "Green"; break;
- case SP_GOLDEN_DRACONIAN: result = "Yellow"; break;
- case SP_GREY_DRACONIAN: result = "Grey"; break;
- case SP_BLACK_DRACONIAN: result = "Black"; break;
- case SP_PURPLE_DRACONIAN: result = "Purple"; break;
- case SP_MOTTLED_DRACONIAN: result = "Mottled"; break;
- case SP_PALE_DRACONIAN: result = "Pale"; break;
- default:
- result = species_name(you.species, 1);
- }
- result += " ";
- return (result);
-}
-
int Menu::item_colour(int, const MenuEntry *entry) const
{
int icol = -1;
if (highlighter)
icol = highlighter->entry_colour(entry);
- else
- {
- text_pattern tp(get_species_key());
- if (!tp.empty() && tp.matches(entry->text))
- icol = WHITE;
- }
return (icol == -1? entry->colour : icol);
}
diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h
index 86bdc4f246..88c1d00d0d 100644
--- a/crawl-ref/source/menu.h
+++ b/crawl-ref/source/menu.h
@@ -177,10 +177,26 @@ enum MenuFlag
// you pass in MUST be allocated with new, or Crawl will crash.
#define NUMBUFSIZ 10
+
+// FIXME: MenuEntry is a large object, and shouldn't be used for
+// showing text files.
+
class Menu
{
public:
Menu( int flags = MF_MULTISELECT, const std::string& tagname = "" );
+
+ // Initializes a Menu from a formatted_string as follows:
+ //
+ // 1) Splits the formatted_string on EOL (this is not necessarily \n).
+ // 2) Picks the most recently used non-whitespace colour as the colour
+ // for the next line (so it can't do multiple colours on one line).
+ // 3) Ignores all cursor movement ops in the formatted_string.
+ //
+ // These are limitations that should be fixed eventually.
+ //
+ Menu( const formatted_string &fs );
+
virtual ~Menu();
// Remove all items from the Menu, leave title intact.
@@ -257,6 +273,7 @@ protected:
int last_selected;
protected:
+ void check_add_formatted_line(int col, std::string &line, bool check_eol);
void do_menu();
virtual void draw_select_count(int count, bool force = false);
virtual void draw_item( int index ) const;
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 9bf5b9cb22..c34626ca91 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -3945,9 +3945,13 @@ void monsters::load_spells(mon_spellbook_type book)
}
}
#if DEBUG_DIAGNOSTICS
- for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; i++)
- mprf( MSGCH_DIAGNOSTICS, "Spell #%d: %d (%s)",
- i, spells[i], spell_title(spells[i]) );
+ // Only for ghosts, too spammy to use for all monsters.
+ if (book == MST_GHOST)
+ {
+ for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; i++)
+ mprf( MSGCH_DIAGNOSTICS, "Spell #%d: %d (%s)",
+ i, spells[i], spell_title(spells[i]) );
+ }
#endif
}
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index c2cc554230..57b8549a9e 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -38,6 +38,7 @@
#include "format.h"
#include "itemprop.h"
#include "macro.h"
+#include "menu.h"
#include "notes.h"
#include "ouch.h"
#include "player.h"
@@ -1333,10 +1334,10 @@ void display_mutations()
{
clrscr();
gotoxy(1,1);
- describe_mutations().display();
-
- if (getch() == 0)
- getch();
+
+ const formatted_string mutation_fs = describe_mutations();
+ Menu mutation_menu(mutation_fs);
+ mutation_menu.show();
}
static int calc_mutation_amusement_value(mutation_type which_mutation)