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.1
Committed: Sun Oct 17 08:15:12 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Log Message:
initial import

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    
8     #include "adt/slice.h"
9    
10     #include <ndk++/pen.hh>
11    
12     #include <algorithm>
13     #include <cassert>
14     #include <cstring>
15    
16     static char const indices[] = " 123456789abcdefghijklmnopqrstuvwxyz";
17     static __attribute__ ((__const__)) int maxidx () { return sizeof indices - 2; }
18    
19     inventory_widget::inventory_widget (ndk::panel *parent)
20     : frame ("inventory", parent)
21     , inv (nullptr)
22     , at (0)
23     {
24     events ()->on_keyboard (slot (&inventory_widget::at_keyboard, this));
25     }
26    
27     int __attribute__ ((__pure__))
28     inventory_widget::maxinv () const
29     {
30     return std::min (height () - 2, maxidx ());
31     }
32    
33     void
34     inventory_widget::update (std::vector<data::item> const &items, std::string const &title)
35     {
36     inv = &items;
37     set_title (title);
38    
39     int const inv_size = inv->size ();
40     if (at > inv_size - 2)
41     at = std::max (inv_size - 2, 0);
42     }
43    
44     void
45     inventory_widget::draw ()
46     {
47     frame::draw ();
48    
49     if (!inv || inv->empty ())
50     return;
51    
52     ndk::pen pen (*this);
53    
54     int i = 0;
55     for (data::item const &item : slice (*inv, at))
56     {
57     ++i;
58     pen.move (1, i);
59    
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     ndk::event::result
94     inventory_widget::at_keyboard (ndk::keyboard const &ev)
95     {
96     if (!inv)
97     return ndk::event::ignored;
98    
99     int const inv_size = inv->size ();
100    
101     switch (ev.code ())
102     {
103     case ndk::key::up:
104     if (at > 0)
105     --at;
106     break;
107    
108     case ndk::key::down:
109     if (at < inv_size - 2)
110     ++at;
111     break;
112    
113     case ndk::key::pg_up:
114     up: at -= std::min (maxinv () - 2, int (at));
115     break;
116    
117     case ndk::key::pg_dn:
118     down: at += std::min (maxinv () - 2, inv_size - at - 2);
119     break;
120    
121     default:
122     if (char const *const iptr = std::strchr (indices, int (ev.code ())))
123     {
124     int const index = iptr - indices;
125     if (index > maxinv () || at + index > inv_size)
126     return ndk::event::ignored;
127    
128     if (index == 1)
129     goto up;
130    
131     if (index == maxinv ())
132     goto down;
133     }
134     return ndk::event::ignored;
135     }
136    
137     draw ();
138    
139     return ndk::event::accepted;
140     }