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.8
Committed: Fri Jan 21 21:56:36 2011 UTC (15 years, 9 months ago) by sf-pippijn
Branch: MAIN
Changes since 1.7: +2 -0 lines
Log Message:
add some hjkl controls

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

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 sf-pippijn 1.7 #include <ndk/pen.hh>
13 sf-pippijn 1.1
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.6 bool
49     inventory_widget::draw (ndk::pen &pen, int at, int maxinv, int row, data::item const &item)
50 sf-pippijn 1.1 {
51 sf-pippijn 1.6 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 sf-pippijn 1.1
60 sf-pippijn 1.6 // next page
61     if (row >= maxinv)
62 sf-pippijn 1.1 {
63 sf-pippijn 1.6 pen.write ("%c: more…", indices[row]);
64     return false;
65     }
66 sf-pippijn 1.1
67 sf-pippijn 1.6 pen.write ("%c: [", indices[row]);
68     write (pen, data::glyphs[item.face]);
69     pen.write ("] ");
70 sf-pippijn 1.1
71 sf-pippijn 1.6 if (item.nrof < 2)
72     pen.write (item.singular);
73     else
74     pen.write ("%d %s", item.nrof, item.plural.c_str ());
75 sf-pippijn 1.1
76 sf-pippijn 1.6 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 sf-pippijn 1.1
84 sf-pippijn 1.6 return true;
85     }
86 sf-pippijn 1.1
87 sf-pippijn 1.6 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 sf-pippijn 1.1 }
96    
97 sf-pippijn 1.5 void
98     inventory_widget::draw ()
99     {
100     frame::draw ();
101    
102     if (!inv || inv->empty ())
103     return;
104    
105 sf-pippijn 1.6 ndk::pen pen (*this);
106    
107 sf-pippijn 1.5 if (title () == "Floor")
108 sf-pippijn 1.6 draw (pen, reverse (slice (*inv, at)));
109 sf-pippijn 1.5 else
110 sf-pippijn 1.6 draw (pen, slice (*inv, at));
111 sf-pippijn 1.5 }
112    
113 sf-pippijn 1.1 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 sf-pippijn 1.8 case ndk::key::k:
125 sf-pippijn 1.1 if (at > 0)
126     --at;
127 sf-pippijn 1.3 else
128     return ndk::event::ignored;
129 sf-pippijn 1.1 break;
130    
131     case ndk::key::down:
132 sf-pippijn 1.8 case ndk::key::j:
133 sf-pippijn 1.1 if (at < inv_size - 2)
134     ++at;
135 sf-pippijn 1.3 else
136     return ndk::event::ignored;
137 sf-pippijn 1.1 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     down: at += std::min (maxinv () - 2, inv_size - at - 2);
145     break;
146    
147     default:
148     if (char const *const iptr = std::strchr (indices, int (ev.code ())))
149     {
150     int const index = iptr - indices;
151     if (index > maxinv () || at + index > inv_size)
152     return ndk::event::ignored;
153    
154     if (index == 1)
155     goto up;
156    
157     if (index == maxinv ())
158     goto down;
159     }
160     return ndk::event::ignored;
161     }
162    
163     draw ();
164    
165     return ndk::event::accepted;
166     }