ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/frontend/client/widgets/inventory_widget.cpp
Revision: 1.5
Committed: Wed Oct 20 08:33:43 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Changes since 1.4: +18 -7 lines
Log Message:
2 glyphs / map space

File Contents

# User Rev Content
1 sf-pippijn 1.1 #include "dclient/widgets/inventory.h"
2     #include "dclient/render_glyph.h"
3    
4     #include "deliantra/data/constants.h"
5     #include "deliantra/data/glyph.h"
6     #include "deliantra/data/item.h"
7 sf-pippijn 1.2 #include "deliantra/data/inventory.h"
8 sf-pippijn 1.1
9 sf-pippijn 1.5 #include "adt/reverse.h"
10 sf-pippijn 1.1 #include "adt/slice.h"
11    
12     #include <ndk++/pen.hh>
13    
14     #include <algorithm>
15     #include <cassert>
16     #include <cstring>
17    
18 sf-pippijn 1.4 static char const indices[] = " 123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
19 sf-pippijn 1.1 static __attribute__ ((__const__)) int maxidx () { return sizeof indices - 2; }
20    
21     inventory_widget::inventory_widget (ndk::panel *parent)
22     : frame ("inventory", parent)
23     , inv (nullptr)
24     , at (0)
25     {
26     events ()->on_keyboard (slot (&inventory_widget::at_keyboard, this));
27     }
28    
29     int __attribute__ ((__pure__))
30     inventory_widget::maxinv () const
31     {
32     return std::min (height () - 2, maxidx ());
33     }
34    
35     void
36 sf-pippijn 1.2 inventory_widget::update (data::inventory const &inv, std::string const &title)
37 sf-pippijn 1.1 {
38 sf-pippijn 1.2 this->inv = &inv;
39 sf-pippijn 1.1 set_title (title);
40    
41 sf-pippijn 1.2 int const inv_size = this->inv->size ();
42 sf-pippijn 1.1 if (at > inv_size - 2)
43     at = std::max (inv_size - 2, 0);
44 sf-pippijn 1.2
45     visualize ();
46 sf-pippijn 1.1 }
47    
48 sf-pippijn 1.5 template<typename ContainerT>
49 sf-pippijn 1.1 void
50 sf-pippijn 1.5 inventory_widget::draw (ContainerT const &items)
51 sf-pippijn 1.1 {
52     ndk::pen pen (*this);
53    
54     int i = 0;
55 sf-pippijn 1.5 foreach (data::item const &item, items)
56 sf-pippijn 1.1 {
57     ++i;
58 sf-pippijn 1.3 return_unless (pen.move (1, i));
59 sf-pippijn 1.1
60     // previous page
61     if (at > 0 && i == 1)
62     {
63     pen.write ("%c: more…", indices[i]);
64     continue;
65     }
66    
67     // next page
68     if (i >= maxinv ())
69     {
70     pen.write ("%c: more…", indices[i]);
71     break;
72     }
73    
74     pen.write ("%c: [", indices[i]);
75     write (pen, data::glyphs[item.face]);
76     pen.write ("] ");
77    
78     if (item.nrof < 2)
79     pen.write (item.singular);
80     else
81     pen.write ("%d %s", item.nrof, item.plural.c_str ());
82    
83     if (item.flags & F_OPEN) pen.write (" (open)");
84     if (item.flags & F_APPLIED) pen.write (" (applied)");
85     if (item.flags & F_UNPAID) pen.write (" (unpaid)");
86     if (item.flags & F_MAGIC) pen.write (" (magic)");
87     if (item.flags & F_CURSED) pen.write (" (cursed)");
88     if (item.flags & F_DAMNED) pen.write (" (damned)");
89     if (item.flags & F_LOCKED) pen.write (" *");
90     }
91     }
92    
93 sf-pippijn 1.5 void
94     inventory_widget::draw ()
95     {
96     frame::draw ();
97    
98     if (!inv || inv->empty ())
99     return;
100    
101     if (title () == "Floor")
102     draw (reverse (slice (*inv, at)));
103     else
104     draw (slice (*inv, at));
105     }
106    
107 sf-pippijn 1.1 ndk::event::result
108     inventory_widget::at_keyboard (ndk::keyboard const &ev)
109     {
110     if (!inv)
111     return ndk::event::ignored;
112    
113     int const inv_size = inv->size ();
114    
115     switch (ev.code ())
116     {
117     case ndk::key::up:
118     if (at > 0)
119     --at;
120 sf-pippijn 1.3 else
121     return ndk::event::ignored;
122 sf-pippijn 1.1 break;
123    
124     case ndk::key::down:
125     if (at < inv_size - 2)
126     ++at;
127 sf-pippijn 1.3 else
128     return ndk::event::ignored;
129 sf-pippijn 1.1 break;
130    
131     case ndk::key::pg_up:
132     up: at -= std::min (maxinv () - 2, int (at));
133     break;
134    
135     case ndk::key::pg_dn:
136     down: at += std::min (maxinv () - 2, inv_size - at - 2);
137     break;
138    
139     default:
140     if (char const *const iptr = std::strchr (indices, int (ev.code ())))
141     {
142     int const index = iptr - indices;
143     if (index > maxinv () || at + index > inv_size)
144     return ndk::event::ignored;
145    
146     if (index == 1)
147     goto up;
148    
149     if (index == maxinv ())
150     goto down;
151     }
152     return ndk::event::ignored;
153     }
154    
155     draw ();
156    
157     return ndk::event::accepted;
158     }