Menus in the console version should be unchanged. Let me know if this is not the case.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7258 c06c8d41-db1a-0410-9941-cceddc491573
MADTICUXDKQB7EKTXG7J2OIJGUM7A437FRWIBRA3BIVEKXEXHO6AC F3UFN3NCLA2WEQ5LX63MMEVXFWYHEV6ZYLDEB6DG7D2GRU3BPOPAC YHC3WZ5ATCJCQQ4CMWJA2IDPSY6FQZP7HJL6JI5WXETTY54BJU2AC ZGWMTQ4GG7W5HDVHPQCWJIUK4LK4PS3CDOOIQSFANTU33D45DCPAC Q3B3UVMYEVC4YJUPYVSNTR4DJH4E6J4JJDHZNT5LNOCHCPPMEMXAC PBTLQZHBQK5TAIO7SNSCKSHOQQ65CFFI55OTTETV7FG2FCJOXKHQC NDE6CROMCVOJRMRMEID7QISFPZKUK2VCV6ISP5OEQRBH7EIXUIEQC XKNRIFG2ULQLAAQ5GC4RBZPOERV73DLCNILEA5EP37JLIX5EP3OQC MV5USMLTBKVRWBAD67UFJ2BS4Y5HEOMYASRSB44DS24BBMRP75RQC 3SQQ4MM6YO4I37CQ6GIBIX6BXAEVHNVNHPVMR3PPBBNO454D6XWQC YOYZ4BX35Y63XVQGBYN3DL2PJ53H6Z5PHCOL5QTRH2ZKHZCGMD3QC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC UUF2MSD5MZSKPFENQNJA4QSXVTSEVME43FIY5BE2TDJQ3O3RYHKAC LDBTCT5WIPLJPZWXS2RUQ26QKISCUUTLO77M464WOE6VSYSNPKYAC P4V66RMIZAPCZJW23HDYDUAPMHN664U3KK4DYBYC7FZSWRGPVMPAC FCL7KOWXA5O3GLMDR22JCGMTHMZ57C4WQIJKBIIUQV3LI2CI3X7AC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC B7EE54F23AM4BECQ7GENNC4MHIPH6YVMOXOGZAQUZJKDJYGL7RAQC 25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC BK6MGPSEAEMU4URBAPKY3VTKK6JC6IZVN5CNOSN2UPTIOWQYEWLQC 2PAHDAPDO6PN4FNGB5N7CQNEGHSE3NOGPXYZMIAOJC4VW34FRVOAC YH23OR26YDA6C5K74QRWHROMTPGRNZHTHE4HJGPC3JVNAJ62CHGAC 3NUVKRHPHENI7JNHDDIHZ4FESSZ2Z5XJZVB56ZCXPGMP7O3JCM3QC IHOKNI4O7EEW4UBMKHP6XOZNEIQSW4AYOT4O3JXUIXNNR553IQAQC 2N5AKUYV6EUUT254C47WSHZKD7FGN65JKJ3RCKSDP74XJIHIFMDQC CV2Q7Y3P7SRU5ARIMVDLNVZV4VIMCBYOLIMS6HK6IK3WW4DGIIIAC AU3E5FTABBHFZAZHLGA3UUR5TCTRLDOEMAKTGGEWKCQVH77I3SYAC 3D6NWJ44UYHLZMD3BOQIWXJUEGITAVCHK6Z2WWDQONVQC4HSBRXQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC BWAQ3FHBBM6G3K3KYP75CRTR343RDQZJRYX5ZGYUEXYBAC3APDLAC GBLEVRUADUFICPSVEHPVBQAMWGQODKFYS2UAANEHKMUPZWMPLGNQC while (m_region_crt->ey + m_region_menu_inv->wy > m_windowsz.y){m_region_crt->resize(m_region_crt->mx, m_region_crt->my - 1);}while (m_region_crt->ex > m_windowsz.x){m_region_crt->resize(m_region_crt->mx - 1, m_region_crt->my);}m_region_menu_inv->place(0, m_region_crt->ey, margin);m_region_menu_inv->resize_to_fit(m_windowsz.x, m_windowsz.y -m_region_menu_inv->sy);// Depending on the font, the menu inventory may hold fewer items// than the crt menu can display. Decrease the lines if necessary.const int ex = 3;if (m_region_crt->my - ex > m_region_menu_inv->mx)m_region_crt->resize(m_region_crt->mx, m_region_menu_inv->mx + ex);
void TilesFramework::update_menu_inventory(unsigned int slot,const item_def &item,bool selected, char key){InventoryTile desc;_fill_item_info(desc, item);desc.key = key;desc.idx = (desc.flag & TILEI_FLAG_FLOOR) ? item.index() :letter_to_index(key);if (selected)desc.flag |= TILEI_FLAG_SELECT;m_region_menu_inv->update_slot(slot, desc);}
};class MenuEntry;class MenuRegion : public Region{public:MenuRegion(ImageManager *im, FTFont *entry);virtual int handle_mouse(MouseEvent &event);virtual void render();virtual void clear();int maxpagesize() const;void set_entry(int index, const std::string &s, int colour, const MenuEntry *me);void set_offset(int lines);void set_more(const formatted_string &more);protected:virtual void on_resize();virtual void place_entries();int mouse_entry(int x, int y);struct MenuRegionEntry{formatted_string text;int tile;TextureID texture;int sx, ex, sy, ey;bool selected;bool heading;char key;bool valid;};ImageManager *m_image;FTFont *m_font_entry;formatted_string m_more;int m_mouse_idx;bool m_dirty;std::vector<MenuRegionEntry> m_entries;ShapeBuffer m_shape_buf;LineBuffer m_line_buf;FontBuffer m_font_buf;TileBuffer m_tile_buf;
// TODO enne - clicking on menu items? We could probably// determine which items were clicked based on text size.
return 0;}MenuRegion::MenuRegion(ImageManager *im, FTFont *entry) :m_image(im), m_font_entry(entry), m_mouse_idx(-1),m_dirty(false), m_font_buf(entry), m_tile_buf(NULL){ASSERT(m_image);ASSERT(m_font_entry);dx = 1;dy = 1;m_entries.resize(128);}int MenuRegion::mouse_entry(int x, int y){if (m_dirty)place_entries();for (unsigned int i = 0; i < m_entries.size(); i++){if (!m_entries[i].valid)continue;if (x >= m_entries[i].sx && x <= m_entries[i].ex&& y >= m_entries[i].sy && y <= m_entries[i].ey){return i;}}return -1;}int MenuRegion::handle_mouse(MouseEvent &event){m_mouse_idx = -1;int x, y;if (!mouse_pos(event.px, event.py, x, y))return 0;if (event.event == MouseEvent::MOVE){int old_idx = m_mouse_idx;m_mouse_idx = mouse_entry(x, y);if (old_idx == m_mouse_idx)return 0;const VColour mouse_colour(160, 160, 160, 255);m_line_buf.clear();if (!m_entries[m_mouse_idx].heading && m_entries[m_mouse_idx].key){m_line_buf.add_square(m_entries[m_mouse_idx].sx-1,m_entries[m_mouse_idx].sy,m_entries[m_mouse_idx].ex+1,m_entries[m_mouse_idx].ey+1,mouse_colour);}return 0;}if (event.event == MouseEvent::PRESS){switch (event.button){case MouseEvent::LEFT:{int entry = mouse_entry(x, y);if (entry == -1)return 0;return m_entries[entry].key;}#if 0// TODO enne - these events are wonky on OS X.// TODO enne - fix menus so that mouse wheeling doesn't easy exitcase MouseEvent::SCROLL_UP:return CK_UP;case MouseEvent::SCROLL_DOWN:return CK_DOWN;#endifdefault:return 0;}}
const int heading_indent = 10;const int tile_ident = 20;const int text_indent = 58;const unsigned int max_tile_height = 32;const int column_width = mx / 2;const int entry_buffer = 1;const VColour selected_colour(50, 50, 10, 255);m_font_buf.clear();m_tile_buf.clear();m_shape_buf.clear();m_line_buf.clear();TextureID tex = TEX_MAX;int height = 2;bool mouse_selected = false;for (unsigned int i = 0; i < m_entries.size(); i++){if (!m_entries[i].valid){m_entries[i].sx = 0;m_entries[i].sy = 0;m_entries[i].ex = 0;m_entries[i].ey = 0;continue;}m_entries[i].sy = height;int text_start = 0;int text_height = height;if (m_entries[i].heading){mouse_selected = false;m_entries[i].sx = heading_indent;text_start = heading_indent;height += m_font_entry->char_height();}else if (m_entries[i].tile){m_entries[i].sx = tile_ident;text_start = text_indent;int entry_height =std::max(max_tile_height, m_font_entry->char_height());height += entry_height;text_height += (entry_height - m_font_entry->char_height()) / 2;ASSERT(m_entries[i].texture == tex || tex == TEX_MAX);tex = m_entries[i].texture;m_tile_buf.set_tex(&m_image->m_textures[tex]);m_tile_buf.add(m_entries[i].tile, m_entries[i].sx, m_entries[i].sy);}else{m_entries[i].sx = text_start + text_indent;height += m_font_entry->char_height();}std::string unfrm = m_entries[i].text.tostring();m_entries[i].ex = text_start + m_font_entry->string_width(unfrm.c_str());m_entries[i].ex = std::max(m_entries[i].ex, column_width);m_entries[i].ey = height;m_font_buf.add(m_entries[i].text, text_start, text_height);if (m_entries[i].selected){m_shape_buf.add(m_entries[i].sx-1, m_entries[i].sy-1,m_entries[i].ex+1, m_entries[i].ey+1,selected_colour);}height += entry_buffer;}int lines = count_linebreaks(m_more);int more_height = (lines + 1) * m_font_entry->char_height();m_font_buf.add(m_more, sx + ox, ey - oy - more_height);}void MenuRegion::render(){if (m_dirty)place_entries();glLoadIdentity();glTranslatef(sx + ox, sy + oy, 0);glScalef(dx, dy, 1);m_shape_buf.draw();m_line_buf.draw();m_tile_buf.draw();m_font_buf.draw();}void MenuRegion::clear(){m_shape_buf.clear();m_line_buf.clear();m_tile_buf.clear();m_font_buf.clear();m_more.clear();for (unsigned int i = 0; i < m_entries.size(); i++){m_entries[i].valid = false;}m_mouse_idx = -1;}void MenuRegion::set_entry(int idx, const std::string &str, int colour,const MenuEntry *me){if (idx >= (int)m_entries.size()){int new_size = m_entries.size();while (idx >= new_size)new_size *= 2;m_entries.resize(new_size);}MenuRegionEntry &e = m_entries[idx];e.valid = true;e.text.clear();e.text.textcolor(colour);e.text += formatted_string::parse_string(str);e.heading = (me->level == MEL_TITLE || me->level == MEL_SUBTITLE);e.selected = me->selected();e.key = me->hotkeys.size() > 0 ? me->hotkeys[0] : 0;e.sx = e.sy = e.ex = e.ey = 0;if (!me->tile(e.tile, e.texture))e.tile = 0;m_dirty = true;}void MenuRegion::on_resize(){m_dirty = true;}int MenuRegion::maxpagesize() const{// TODO enne - this could be much smarter. Also, columns?return my / 32 - 2;}void MenuRegion::set_offset(int lines){oy = (lines - 1) * m_font_entry->char_height();}void MenuRegion::set_more(const formatted_string &more){m_more.clear();m_more += more;m_dirty = true;}
{ 0, 0, 0}, // BLACK{ 0, 82, 255}, // BLUE{100, 185, 70}, // GREEN{ 0, 180, 180}, // CYAN{255, 48, 0}, // RED{238, 92, 238}, // MAGENTA{165, 91, 0}, // BROWN{162, 162, 162}, // LIGHTGREY{ 82, 82, 82}, // DARKGREY{ 82, 102, 255}, // LIGHTBLUE{ 82, 255, 82}, // LIGHTGREEN{ 82, 255, 255}, // LIGHTCYAN{255, 82, 82}, // LIGHTRED{255, 82, 255}, // LIGHTMAGENTA{255, 255, 82}, // YELLOW{255, 255, 255} // WHITE
VColour( 0, 0, 0), // BLACKVColour( 0, 82, 255), // BLUEVColour(100, 185, 70), // GREENVColour( 0, 180, 180), // CYANVColour(255, 48, 0), // REDVColour(238, 92, 238), // MAGENTAVColour(165, 91, 0), // BROWNVColour(162, 162, 162), // LIGHTGREYVColour( 82, 82, 82), // DARKGREYVColour( 82, 102, 255), // LIGHTBLUEVColour( 82, 255, 82), // LIGHTGREENVColour( 82, 255, 255), // LIGHTCYANVColour(255, 82, 82), // LIGHTREDVColour(255, 82, 255), // LIGHTMAGENTAVColour(255, 255, 82), // YELLOWVColour(255, 255, 255) // WHITE
verts[i].r = term_colours[box_colour][0];verts[i].g = term_colours[box_colour][1];verts[i].b = term_colours[box_colour][2];
verts[i].r = term_colours[box_colour].r;verts[i].g = term_colours[box_colour].g;verts[i].b = term_colours[box_colour].b;
void FTFont::store(FontBuffer &buf, float &x, float &y,const std::string &str, const VColour &col){for (unsigned int i = 0; i < str.size(); i++){char c = str[i];if (c == '\n'){y += m_max_advance.y;}else{store(buf, x, y, c, col);}}}void FTFont::store(FontBuffer &buf, float &x, float &y,const formatted_string &fs){int colour = LIGHTGREY;for (unsigned int i = 0; i < fs.ops.size(); i++){switch (fs.ops[i].type){case FSOP_COLOUR:// Only foreground colors for now...colour = fs.ops[i].x & 0xF;break;case FSOP_TEXT:store(buf, x, y, fs.ops[i].text, term_colours[colour]);break;default:case FSOP_CURSOR:break;}}}void FTFont::store(FontBuffer &buf, float &x, float &y,char c, const VColour &col){if (!m_glyphs[c].renderable){x += m_glyphs[c].advance;return;}int this_width = m_glyphs[c].width;float pos_sx = x + m_glyphs[c].offset;float pos_sy = y;float pos_ex = pos_sx + this_width;float pos_ey = y + m_max_advance.y;float tex_sx = (float)(c % 16) / 16.0f;float tex_sy = (float)(c / 16) / 16.0f;float tex_ex = tex_sx + (float)this_width / (float)m_tex.width();float tex_ey = tex_sy + (float)m_max_advance.y / (float)m_tex.height();{PTCVert &v = buf.get_next();v.col = col;v.pos_x = pos_sx;v.pos_y = pos_sy;v.tex_x = tex_sx;v.tex_y = tex_sy;}{PTCVert &v = buf.get_next();v.col = col;v.pos_x = pos_sx;v.pos_y = pos_ey;v.tex_x = tex_sx;v.tex_y = tex_ey;}{PTCVert &v = buf.get_next();v.col = col;v.pos_x = pos_ex;v.pos_y = pos_ey;v.tex_x = tex_ex;v.tex_y = tex_ey;}{PTCVert &v = buf.get_next();v.col = col;v.pos_x = pos_ex;v.pos_y = pos_sy;v.tex_x = tex_ex;v.tex_y = tex_sy;}x += m_glyphs[c].advance;}
/** File: tilebuf.h* Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC** Modified for Crawl Reference by $Author: ennewalker $ on $Date: 2008-03-07 $*/#ifndef TILEBUF_H#define TILEBUF_Hclass FTFont;class formatted_string;class GenericTexture;class TilesTexture;#include <vector>struct VColour{VColour() {}VColour(unsigned char _r, unsigned char _g, unsigned char _b,unsigned char _a = 255) : r(_r), g(_g), b(_b), a(_a) {}unsigned char r;unsigned char g;unsigned char b;unsigned char a;static VColour white;static VColour black;static VColour transparent;};struct PTCVert{float pos_x;float pos_y;float tex_x;float tex_y;VColour col;};struct PTVert{float pos_x;float pos_y;float tex_x;float tex_y;};struct PCVert{float pos_x;float pos_y;VColour col;};// V: vertex datatemplate<class V>class VertBuffer{public:VertBuffer(const GenericTexture *tex, int prim);void add(const V& vert);V& get_next();void draw() const;void clear();protected:std::vector<V> m_verts;const GenericTexture *m_tex;int m_prim;};class FontBuffer : public VertBuffer<PTCVert>{public:FontBuffer(FTFont *font);void add(const formatted_string &fs, float x, float y);void add(const std::string &s, const VColour &col, float x, float y);protected:FTFont *m_font;};class TileBuffer : public VertBuffer<PTVert>{public:TileBuffer(const TilesTexture *tex);void add(int idx, float x, float y);// Note: this could invalidate previous additions if they were// from a different texture.void set_tex(const TilesTexture *tex);};class ShapeBuffer : public VertBuffer<PCVert>{public:ShapeBuffer();void add(float sx, float sy, float ex, float ey, const VColour &c);};class LineBuffer : public VertBuffer<PCVert>{public:LineBuffer();void add(float sx, float sy, float ex, float ey, const VColour &c);void add_square(float sx, float sy, float ex, float ey, const VColour &c);};/////////////////////////////////////////////////////////////////////////////// template implementationtemplate<class V>inline VertBuffer<V>::VertBuffer(const GenericTexture *tex, int prim) :m_tex(tex), m_prim(prim){}template<class V>inline void VertBuffer<V>::add(const V& vert){m_verts.push_back(vert);}template<class V>inline V& VertBuffer<V>::get_next(){int last = m_verts.size();m_verts.resize(last + 1);return (m_verts[last]);}template<class V>inline void VertBuffer<V>::clear(){m_verts.clear();}#endif
/** File: tilebuf.cc* Summary: Vertex buffer implementaions** Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC** Modified for Crawl Reference by $Author: ennewalker $ on $Date: 2008-10-11 $*/#include "tilebuf.h"#include "tilefont.h"#include "tilesdl.h"#include <SDL.h>#include <SDL_opengl.h>/////////////////////////////////////////////////////////////////////////////// VColourVColour VColour::white(255, 255, 255, 255);VColour VColour::black(0, 0, 0, 255);VColour VColour::transparent(0, 0, 0, 0);/////////////////////////////////////////////////////////////////////////////// VertBufferstatic bool _valid(int num_verts, int prim){switch (prim){case GL_QUADS:return (num_verts % 4 == 0);case GL_TRIANGLES:return (num_verts % 3 == 0);case GL_LINES:return (num_verts % 2 == 0);case GL_POINTS:return (true);default:return (false);}}template<>void VertBuffer<PTVert>::draw() const{if (m_verts.size() == 0)return;ASSERT(_valid(m_verts.size(), m_prim));ASSERT(m_tex);GLState state;state.array_vertex = true;state.array_texcoord = true;state.blend = true;state.texture = true;GLStateManager::set(state);m_tex->bind();glVertexPointer(2, GL_FLOAT, sizeof(PTVert), &m_verts[0].pos_x);glTexCoordPointer(2, GL_FLOAT, sizeof(PTVert), &m_verts[0].tex_x);glDrawArrays(m_prim, 0, m_verts.size());}template<>void VertBuffer<PCVert>::draw() const{if (m_verts.size() == 0)return;ASSERT(_valid(m_verts.size(), m_prim));ASSERT(!m_tex);GLState state;state.array_vertex = true;state.array_colour = true;state.blend = true;state.texture = true;GLStateManager::set(state);glVertexPointer(2, GL_FLOAT, sizeof(PCVert), &m_verts[0].pos_x);glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PCVert), &m_verts[0].col);glDrawArrays(m_prim, 0, m_verts.size());}template<>void VertBuffer<PTCVert>::draw() const{if (m_verts.size() == 0)return;ASSERT(_valid(m_verts.size(), m_prim));ASSERT(m_tex);GLState state;state.array_vertex = true;state.array_texcoord = true;state.array_colour = true;state.blend = true;state.texture = true;GLStateManager::set(state);m_tex->bind();glVertexPointer(2, GL_FLOAT, sizeof(PTCVert), &m_verts[0].pos_x);glTexCoordPointer(2, GL_FLOAT, sizeof(PTCVert), &m_verts[0].tex_x);glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PTCVert), &m_verts[0].col);glDrawArrays(m_prim, 0, m_verts.size());}/////////////////////////////////////////////////////////////////////////////// FontBufferFontBuffer::FontBuffer(FTFont *font) :VertBuffer<PTCVert>(font->font_tex(), GL_QUADS), m_font(font){ASSERT(m_font);ASSERT(m_tex);}void FontBuffer::add(const formatted_string &fs, float x, float y){m_font->store(*this, x, y, fs);ASSERT(_valid(m_verts.size(), m_prim));}void FontBuffer::add(const std::string &s, const VColour &col, float x, float y){m_font->store(*this, x, y, s, col);ASSERT(_valid(m_verts.size(), m_prim));}/////////////////////////////////////////////////////////////////////////////// TileBufferTileBuffer::TileBuffer(const TilesTexture *t) : VertBuffer<PTVert>(t, GL_QUADS){}void TileBuffer::add(int idx, float x, float y){const tile_info &inf = ((TilesTexture*)m_tex)->get_info(idx);float pos_sx = x + inf.offset_x;float pos_sy = y + inf.offset_y;float pos_ex = pos_sx + (inf.ex - inf.sx);float pos_ey = pos_sy + (inf.ey - inf.sy);float fwidth = m_tex->width();float fheight = m_tex->height();float tex_sx = inf.sx / fwidth;float tex_sy = inf.sy / fheight;float tex_ex = inf.ex / fwidth;float tex_ey = inf.ey / fheight;{PTVert &v = get_next();v.pos_x = pos_sx;v.pos_y = pos_sy;v.tex_x = tex_sx;v.tex_y = tex_sy;}{PTVert &v = get_next();v.pos_x = pos_sx;v.pos_y = pos_ey;v.tex_x = tex_sx;v.tex_y = tex_ey;}{PTVert &v = get_next();v.pos_x = pos_ex;v.pos_y = pos_ey;v.tex_x = tex_ex;v.tex_y = tex_ey;}{PTVert &v = get_next();v.pos_x = pos_ex;v.pos_y = pos_sy;v.tex_x = tex_ex;v.tex_y = tex_sy;}ASSERT(_valid(m_verts.size(), m_prim));}void TileBuffer::set_tex(const TilesTexture *tex){ASSERT(tex);m_tex = tex;}/////////////////////////////////////////////////////////////////////////////// ShapeBufferShapeBuffer::ShapeBuffer() : VertBuffer<PCVert>(NULL, GL_QUADS){}void ShapeBuffer::add(float pos_sx, float pos_sy, float pos_ex, float pos_ey,const VColour &col){{PCVert &v = get_next();v.pos_x = pos_sx;v.pos_y = pos_sy;v.col = col;}{PCVert &v = get_next();v.pos_x = pos_sx;v.pos_y = pos_ey;v.col = col;}{PCVert &v = get_next();v.pos_x = pos_ex;v.pos_y = pos_ey;v.col = col;}{PCVert &v = get_next();v.pos_x = pos_ex;v.pos_y = pos_sy;v.col = col;}ASSERT(_valid(m_verts.size(), m_prim));}/////////////////////////////////////////////////////////////////////////////// LineBufferLineBuffer::LineBuffer() : VertBuffer<PCVert>(NULL, GL_LINES){}void LineBuffer::add(float pos_sx, float pos_sy, float pos_ex, float pos_ey,const VColour &col){{PCVert &v = get_next();v.pos_x = pos_sx;v.pos_y = pos_sy;v.col = col;}{PCVert &v = get_next();v.pos_x = pos_ex;v.pos_y = pos_ey;v.col = col;}ASSERT(_valid(m_verts.size(), m_prim));}void LineBuffer::add_square(float sx, float sy, float ex, float ey,const VColour &col){add(sx, sy, ex, sy, col);add(ex, sy, ex, ey, col);add(ex, ey, sx, ey, col);add(sx, ey, sx, sy, col);}
void draw_stock_item(int index, const MenuEntry *me) const{// Skip inventory draw function, as tiles code can't currently// handle drawing items that aren't in mitm or in inventory.Menu::draw_stock_item(index, me);}
class MenuDisplay{public:MenuDisplay(Menu *menu);virtual ~MenuDisplay() {}virtual void draw_stock_item(int index, const MenuEntry *me) = 0;virtual void set_offset(int lines) = 0;virtual void draw_more() = 0;protected:Menu *m_menu;};class MenuDisplayText : public MenuDisplay{public:MenuDisplayText(Menu *menu);virtual void draw_stock_item(int index, const MenuEntry *me);virtual void draw_more();virtual void set_offset(int lines) { m_starty = lines; }protected:int m_starty;};class MenuDisplayTile : public MenuDisplay{public:MenuDisplayTile(Menu *menu);virtual void draw_stock_item(int index, const MenuEntry *me);virtual void set_offset(int lines);virtual void draw_more();};
MenuDisplayText::MenuDisplayText(Menu *menu) : MenuDisplay(menu), m_starty(1){}void MenuDisplayText::draw_stock_item(int index, const MenuEntry *me){textattr(m_menu->item_colour(index, me));if (m_menu->get_flags() & MF_ALLOW_FORMATTING)formatted_string::parse_string(me->get_text()).display();else{std::string text = me->get_text();if ((int) text.length() > get_number_of_cols())text = text.substr(0, get_number_of_cols());cprintf("%s", text.c_str());}}void MenuDisplayText::draw_more(){cgotoxy(1, m_menu->get_y_offset() + m_menu->get_pagesize() -count_linebreaks(m_menu->get_more()));m_menu->get_more().display();}#ifdef USE_TILEMenuDisplayTile::MenuDisplayTile(Menu *menu) : MenuDisplay(menu){m_menu->set_maxpagesize(tiles.get_menu()->maxpagesize());}void MenuDisplayTile::draw_stock_item(int index, const MenuEntry *me){int colour = m_menu->item_colour(index, me);std::string text = me->get_text();tiles.get_menu()->set_entry(index, text, colour, me);}void MenuDisplayTile::set_offset(int lines){tiles.get_menu()->set_offset(lines);}void MenuDisplayTile::draw_more(){tiles.get_menu()->set_more(m_menu->get_more());}#endif
{cgotoxy( 1, y_offset + pagesize - count_linebreaks(more) );more.display();}
mdisplay->draw_more();
textattr( item_colour(index, items[index]) );if ( flags & MF_ALLOW_FORMATTING )formatted_string::parse_string(items[index]->get_text()).display();else{std::string text = items[index]->get_text();if ((int) text.length() > get_number_of_cols())text = text.substr(0, get_number_of_cols());cprintf( "%s", text.c_str() );}
mdisplay->draw_stock_item(index, me);
#ifdef USE_TILEconst InvEntry *ie = dynamic_cast<const InvEntry*>(me);if (ie && me->quantity > 0){char key = ie->hotkeys.size() > 0 ? ie->hotkeys[0] : 0;tiles.update_menu_inventory(get_entry_index(ie), *ie->item, ie->selected(), key);}#endif
if (quantity <= 0)return false;idx = tileidx_item(*item);tex = TEX_DEFAULT;