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.10
Committed: Mon Feb 7 19:19:39 2011 UTC (15 years, 8 months ago) by sf-pippijn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +8 -0 lines
Log Message:
inventory_widget: implement home and end keys

Jonathan Neuschäfer <j.neuschaefer@gmx.net>

File Contents

# Content
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 #include "deliantra/data/inventory.h"
8
9 #include "adt/reverse.h"
10 #include "adt/slice.h"
11
12 #include <ndk/pen.hh>
13
14 #include <algorithm>
15 #include <cassert>
16 #include <cstring>
17
18 static char const indices[] = " 123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
19 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 inventory_widget::update (data::inventory const &inv, std::string const &title)
37 {
38 this->inv = &inv;
39 set_title (title);
40
41 int const inv_size = this->inv->size ();
42 if (at > inv_size - 2)
43 at = std::max (inv_size - 2, 0);
44
45 visualize ();
46 }
47
48 bool
49 inventory_widget::draw (ndk::pen &pen, int at, int maxinv, int row, data::item const &item)
50 {
51 return_val_unless (pen.move (1, row), false);
52
53 // previous page
54 if (at > 0 && row == 1)
55 {
56 pen.write ("%c: more…", indices[row]);
57 return true;
58 }
59
60 // next page
61 if (row >= maxinv)
62 {
63 pen.write ("%c: more…", indices[row]);
64 return false;
65 }
66
67 pen.write ("%c: [", indices[row]);
68 write (pen, data::glyphs[item.face]);
69 pen.write ("] ");
70
71 if (item.nrof < 2)
72 pen.write (item.singular);
73 else
74 pen.write ("%d %s", item.nrof, item.plural.c_str ());
75
76 if (item.flags & F_OPEN) pen.write (" (open)");
77 if (item.flags & F_APPLIED) pen.write (" (applied)");
78 if (item.flags & F_UNPAID) pen.write (" (unpaid)");
79 if (item.flags & F_MAGIC) pen.write (" (magic)");
80 if (item.flags & F_CURSED) pen.write (" (cursed)");
81 if (item.flags & F_DAMNED) pen.write (" (damned)");
82 if (item.flags & F_LOCKED) pen.write (" *");
83
84 return true;
85 }
86
87 template<typename ContainerT>
88 void
89 inventory_widget::draw (ndk::pen &pen, ContainerT const &items)
90 {
91 int row = 0;
92 foreach (data::item const &item, items)
93 if (!draw (pen, at, maxinv (), ++row, item))
94 break;
95 }
96
97 void
98 inventory_widget::draw ()
99 {
100 frame::draw ();
101
102 if (!inv || inv->empty ())
103 return;
104
105 ndk::pen pen (*this);
106
107 if (title () == "Floor")
108 draw (pen, reverse (slice (*inv, at)));
109 else
110 draw (pen, slice (*inv, at));
111 }
112
113 ndk::event::result
114 inventory_widget::at_keyboard (ndk::keyboard const &ev)
115 {
116 if (!inv)
117 return ndk::event::ignored;
118
119 int const inv_size = inv->size ();
120
121 switch (ev.code ())
122 {
123 case ndk::key::up:
124 case ndk::key::k:
125 if (at > 0)
126 --at;
127 else
128 return ndk::event::ignored;
129 break;
130
131 case ndk::key::down:
132 case ndk::key::j:
133 if (at < inv_size - 2)
134 ++at;
135 else
136 return ndk::event::ignored;
137 break;
138
139 case ndk::key::pg_up:
140 up: at -= std::min (maxinv () - 2, int (at));
141 break;
142
143 case ndk::key::pg_dn:
144 if (inv_size <= 1)
145 break;
146 down: at += std::min (maxinv () - 2, inv_size - at - 2);
147 break;
148
149 case ndk::key::home:
150 at = 0;
151 break;
152
153 case ndk::key::end:
154 at = (inv_size > maxinv ())? (inv_size - maxinv () + 1) : 0;
155 break;
156
157 default:
158 if (char const *const iptr = std::strchr (indices, int (ev.code ())))
159 {
160 int const index = iptr - indices;
161 if (index > maxinv () || at + index > inv_size)
162 return ndk::event::ignored;
163
164 if (index == 1)
165 goto up;
166
167 if (index == maxinv ())
168 goto down;
169 }
170 return ndk::event::ignored;
171 }
172
173 draw ();
174
175 return ndk::event::accepted;
176 }