1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 |
|
---|
10 | #ifdef _MANGLE_INC
|
---|
11 | #include "LIST_~LE.HH"
|
---|
12 | #else
|
---|
13 | #include "list_pick.hh"
|
---|
14 | #endif
|
---|
15 | #include "menu/menuitem.hh"
|
---|
16 | #include "image/image.hh"
|
---|
17 | #ifdef _MANGLE_INC
|
---|
18 | #include "gui/SCROL~OK.HH"
|
---|
19 | #else
|
---|
20 | #include "gui/scroll_bar.hh"
|
---|
21 | #endif
|
---|
22 |
|
---|
23 | i4_list_pick::i4_list_pick(w16 width, w16 height,
|
---|
24 | w32 total_items,
|
---|
25 | i4_menu_item_class **items,
|
---|
26 | w32 scroll_event_id,
|
---|
27 | i4_color background,
|
---|
28 | i4_bool free_items)
|
---|
29 |
|
---|
30 | : i4_parent_window_class(width, height),
|
---|
31 | total_items(total_items),
|
---|
32 | items(items),
|
---|
33 | background(background),
|
---|
34 | scroll_event_id(scroll_event_id),
|
---|
35 | free_items(free_items)
|
---|
36 | {
|
---|
37 | need_draw_all=i4_T;
|
---|
38 | start=0;
|
---|
39 | end=-1;
|
---|
40 | for (w32 i=0; i<total_items; i++)
|
---|
41 | {
|
---|
42 | if (items[i]->width()>length)
|
---|
43 | length=items[i]->width();
|
---|
44 | }
|
---|
45 | length+=8;
|
---|
46 | reposition_start(0);
|
---|
47 | }
|
---|
48 |
|
---|
49 |
|
---|
50 |
|
---|
51 |
|
---|
52 | i4_list_pick::~i4_list_pick()
|
---|
53 | {
|
---|
54 | if (free_items)
|
---|
55 | {
|
---|
56 | for (w32 i=0; i<total_items; i++)
|
---|
57 | delete items[i];
|
---|
58 | i4_free(items);
|
---|
59 | }
|
---|
60 |
|
---|
61 | }
|
---|
62 |
|
---|
63 | void i4_list_pick::reposition_start(w32 new_start)
|
---|
64 | {
|
---|
65 | sw32 old_end=end,old_start=start,i;
|
---|
66 | i4_coord x1=x(),y1=y(),x2=x()+width(),y2=y()+height();
|
---|
67 |
|
---|
68 | if (new_start!=start)
|
---|
69 | need_draw_all=i4_T;
|
---|
70 |
|
---|
71 | i4_window_class *c;
|
---|
72 |
|
---|
73 | for (i=new_start; x1<x2 && i<total_items;)
|
---|
74 | {
|
---|
75 | c=items[i];
|
---|
76 |
|
---|
77 |
|
---|
78 | if (c->height()+y1>=y2)
|
---|
79 | {
|
---|
80 | x1+=length;
|
---|
81 | y1=y();
|
---|
82 | }
|
---|
83 |
|
---|
84 | if (i>=end || i<start)
|
---|
85 | {
|
---|
86 | // i4_warning("add %d",i);
|
---|
87 | add_child(x1,y1,c);
|
---|
88 | }
|
---|
89 | else
|
---|
90 | {
|
---|
91 | // i4_warning("move %d",i);
|
---|
92 | c->move(x1-c->x(),y1-c->y());
|
---|
93 | }
|
---|
94 |
|
---|
95 | y1+=c->height();
|
---|
96 | i++;
|
---|
97 | }
|
---|
98 |
|
---|
99 | start=new_start;
|
---|
100 | end=i;
|
---|
101 |
|
---|
102 | if (old_start<start && old_end>=start)
|
---|
103 | {
|
---|
104 | for (i=old_start; i<start; i++)
|
---|
105 | {
|
---|
106 | // i4_warning("remove %d",i);
|
---|
107 | remove_child(items[i]);
|
---|
108 | }
|
---|
109 | }
|
---|
110 |
|
---|
111 | if (old_start<=end && old_end>end)
|
---|
112 | {
|
---|
113 | for (i=end; i<old_end; i++)
|
---|
114 | {
|
---|
115 | // i4_warning("remove %d",i);
|
---|
116 | remove_child(items[i]);
|
---|
117 | }
|
---|
118 | }
|
---|
119 |
|
---|
120 |
|
---|
121 | if (old_end<start || old_start>end)
|
---|
122 | {
|
---|
123 | for (i=old_start; i<old_end; i++)
|
---|
124 | {
|
---|
125 | // i4_warning("remove %d",i);
|
---|
126 | remove_child(items[i]);
|
---|
127 | }
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | void i4_list_pick::parent_draw(i4_draw_context_class &context)
|
---|
132 | {
|
---|
133 | if (need_draw_all)
|
---|
134 | {
|
---|
135 | local_image->add_dirty(0,0, width()-1, height()-1, context);
|
---|
136 | local_image->clear(background,context);
|
---|
137 | need_draw_all=i4_F;
|
---|
138 | }
|
---|
139 | else
|
---|
140 | {
|
---|
141 | i4_rect_list_class child_clip(&context.clip,0,0);
|
---|
142 | child_clip.intersect_list(&undrawn_area);
|
---|
143 |
|
---|
144 | child_clip.swap(&context.clip);
|
---|
145 |
|
---|
146 | local_image->clear(background,context);
|
---|
147 |
|
---|
148 | child_clip.swap(&context.clip);
|
---|
149 | }
|
---|
150 | }
|
---|
151 |
|
---|
152 |
|
---|
153 | void i4_list_pick::receive_event(i4_event *ev)
|
---|
154 | {
|
---|
155 | if (ev->type()==i4_event::USER_MESSAGE)
|
---|
156 | {
|
---|
157 | CAST_PTR(uev, i4_user_message_event_class, ev);
|
---|
158 | if (uev->sub_type==scroll_event_id)
|
---|
159 | {
|
---|
160 | CAST_PTR(sc_msg, i4_scroll_message, ev);
|
---|
161 | reposition_start(sc_msg->amount*total_items/sc_msg->scroll_total);
|
---|
162 | }
|
---|
163 | else i4_parent_window_class::receive_event(ev);
|
---|
164 | }
|
---|
165 | else i4_parent_window_class::receive_event(ev);
|
---|
166 | }
|
---|
167 |
|
---|
168 |
|
---|
169 |
|
---|
170 | // draw should redraw supplied area of self
|
---|
171 | void i4_list_pick::draw(i4_draw_context_class &context)
|
---|
172 | {
|
---|
173 | if (!undrawn_area.empty() || redraw_flag)
|
---|
174 | {
|
---|
175 | redraw_flag=i4_F;
|
---|
176 | parent_draw(context);
|
---|
177 | undrawn_area.delete_list();
|
---|
178 | }
|
---|
179 |
|
---|
180 |
|
---|
181 | if (child_need_redraw)
|
---|
182 | {
|
---|
183 | child_need_redraw=i4_F;
|
---|
184 | win_iter c=children.begin();
|
---|
185 | for (;c!=children.end();++c)
|
---|
186 | {
|
---|
187 | if (c->need_redraw())
|
---|
188 | {
|
---|
189 | // copy the clip list, and move it to local coordinates
|
---|
190 | i4_rect_list_class child_clip(&context.clip,
|
---|
191 | -(c->x()-x()),
|
---|
192 | -(c->y()-y()));
|
---|
193 |
|
---|
194 | // intersect the clip with what our area is supposed to be
|
---|
195 | child_clip.intersect_area(0,0,
|
---|
196 | c->width()-1,
|
---|
197 | c->height()-1);
|
---|
198 |
|
---|
199 | sw16 old_xoff=context.xoff,old_yoff=context.yoff; // save the old context xoff and yoff
|
---|
200 | context.xoff+=(c->x()-x()); // move the context offset to the child's x,y
|
---|
201 | context.yoff+=(c->y()-y());
|
---|
202 |
|
---|
203 | child_clip.swap(&context.clip);
|
---|
204 |
|
---|
205 | c->draw(context); // the child is ready to draw
|
---|
206 |
|
---|
207 | context.xoff=old_xoff; // restore the context's x & y offsets
|
---|
208 | context.yoff=old_yoff;
|
---|
209 |
|
---|
210 |
|
---|
211 | child_clip.swap(&context.clip); // restore the old clip list
|
---|
212 | }
|
---|
213 | }
|
---|
214 | }
|
---|
215 | }
|
---|