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 | #include "menu/pull.hh"
|
---|
10 | #include "window/win_evt.hh"
|
---|
11 | #include "device/device.hh"
|
---|
12 | #include "device/keys.hh"
|
---|
13 |
|
---|
14 | i4_pull_menu_class::i4_pull_menu_class(i4_graphical_style_class *style,
|
---|
15 | i4_parent_window_class *root_window)
|
---|
16 | : i4_menu_class(i4_F),
|
---|
17 | menu_colors(*style->color_hint),
|
---|
18 | root(root_window),
|
---|
19 | style(style)
|
---|
20 | {
|
---|
21 | active_top=0;
|
---|
22 | active_sub=0;
|
---|
23 | sub_focused=i4_F;
|
---|
24 | watching_mouse=i4_F;
|
---|
25 |
|
---|
26 | menu_colors.selected_text_foreground=i4_read_color_from_resource("selected_menu_foreground");
|
---|
27 | menu_colors.selected_text_background=i4_read_color_from_resource("selected_menu_background");
|
---|
28 | }
|
---|
29 |
|
---|
30 | void i4_pull_menu_class::watch()
|
---|
31 | {
|
---|
32 | if (!watching_mouse)
|
---|
33 | {
|
---|
34 | watching_mouse=i4_T;
|
---|
35 | i4_kernel.request_events(this,
|
---|
36 | i4_device_class::FLAG_KEY_PRESS |
|
---|
37 | i4_device_class::FLAG_KEY_RELEASE |
|
---|
38 | i4_device_class::FLAG_MOUSE_BUTTON_DOWN |
|
---|
39 | i4_device_class::FLAG_MOUSE_BUTTON_UP);
|
---|
40 |
|
---|
41 | }
|
---|
42 | }
|
---|
43 |
|
---|
44 | void i4_pull_menu_class::unwatch()
|
---|
45 | {
|
---|
46 | if (watching_mouse)
|
---|
47 | {
|
---|
48 | i4_kernel.unrequest_events(this,
|
---|
49 | i4_device_class::FLAG_KEY_PRESS |
|
---|
50 | i4_device_class::FLAG_KEY_RELEASE |
|
---|
51 | i4_device_class::FLAG_MOUSE_BUTTON_DOWN |
|
---|
52 | i4_device_class::FLAG_MOUSE_BUTTON_UP);
|
---|
53 |
|
---|
54 | watching_mouse=i4_F;
|
---|
55 | }
|
---|
56 | }
|
---|
57 |
|
---|
58 | i4_pull_menu_class::~i4_pull_menu_class()
|
---|
59 | {
|
---|
60 | unwatch();
|
---|
61 | hide_active();
|
---|
62 |
|
---|
63 | sub_menus.destroy_all();
|
---|
64 | }
|
---|
65 |
|
---|
66 |
|
---|
67 | void i4_pull_menu_class::show_active(i4_menu_item_class *who)
|
---|
68 | {
|
---|
69 | win_iter name=children.begin(), sub=sub_menus.begin(), last=sub_menus.end();
|
---|
70 | while (who!=&*name)
|
---|
71 | {
|
---|
72 | last=sub;
|
---|
73 | ++name;
|
---|
74 | ++sub;
|
---|
75 | }
|
---|
76 |
|
---|
77 | sw32 px,py;
|
---|
78 |
|
---|
79 | py=who->y()+who->height();
|
---|
80 | px=who->x();
|
---|
81 |
|
---|
82 | i4_menu_class *m=((i4_menu_class *)(&*sub));
|
---|
83 |
|
---|
84 | if (last==sub_menus.end())
|
---|
85 | sub_menus.erase();
|
---|
86 | else
|
---|
87 | sub_menus.erase_after(last);
|
---|
88 |
|
---|
89 |
|
---|
90 | m->show(root, px-root->x(), py-root->y());
|
---|
91 |
|
---|
92 | if (sub->height()+sub->y()>root->height())
|
---|
93 | {
|
---|
94 | m->hide();
|
---|
95 | py=who->y()-sub->height();
|
---|
96 | m->show(root, px-root->x(), py-root->y());
|
---|
97 | }
|
---|
98 |
|
---|
99 |
|
---|
100 | if (sub->width()+sub->x()>root->width())
|
---|
101 | {
|
---|
102 | m->hide();
|
---|
103 | px=root->width()-sub->width();
|
---|
104 | m->show(root, px-root->x(), py-root->y());
|
---|
105 | }
|
---|
106 |
|
---|
107 | active_top=who;
|
---|
108 | active_sub=m;
|
---|
109 | watch();
|
---|
110 | }
|
---|
111 |
|
---|
112 | void i4_pull_menu_class::note_reaction_sent(i4_menu_item_class *who, // this is who sent it
|
---|
113 | i4_event_reaction_class *ev, // who it was to
|
---|
114 | i4_menu_item_class::reaction_type type)
|
---|
115 | {
|
---|
116 | i4_menu_class::note_reaction_sent(who, ev, type);
|
---|
117 |
|
---|
118 | if (type==i4_menu_item_class::PRESSED)
|
---|
119 | {
|
---|
120 | who->do_depress();
|
---|
121 | if (!active_sub)
|
---|
122 | show_active(who);
|
---|
123 | } else if (type==i4_menu_item_class::ACTIVATED)
|
---|
124 | {
|
---|
125 | if (active_sub)
|
---|
126 | {
|
---|
127 | hide_active();
|
---|
128 | show_active(who);
|
---|
129 | }
|
---|
130 |
|
---|
131 | active_top=who;
|
---|
132 | } else if (type==i4_menu_item_class::DEACTIVATED)
|
---|
133 | {
|
---|
134 | if (active_sub)
|
---|
135 | who->do_activate();
|
---|
136 | }
|
---|
137 | }
|
---|
138 |
|
---|
139 | void i4_pull_menu_class::hide_active()
|
---|
140 | {
|
---|
141 | if (active_sub)
|
---|
142 | {
|
---|
143 | active_sub->hide();
|
---|
144 |
|
---|
145 | if ((i4_window_class *)active_top==&*children.begin())
|
---|
146 | sub_menus.insert(*active_sub);
|
---|
147 | else
|
---|
148 | {
|
---|
149 | win_iter s=sub_menus.begin(), t=children.begin();
|
---|
150 | ++t;
|
---|
151 | for (;(*&t)!=active_top;)
|
---|
152 | {
|
---|
153 | ++s;
|
---|
154 | ++t;
|
---|
155 | }
|
---|
156 | sub_menus.insert_after(s, *active_sub);
|
---|
157 | }
|
---|
158 | unwatch();
|
---|
159 | }
|
---|
160 |
|
---|
161 | if (active_top)
|
---|
162 | active_top->do_deactivate();
|
---|
163 |
|
---|
164 | active_top=0;
|
---|
165 | active_sub=0;
|
---|
166 | }
|
---|
167 |
|
---|
168 | void i4_pull_menu_class::receive_event(i4_event *ev)
|
---|
169 | {
|
---|
170 | if (ev->type()==i4_event::OBJECT_MESSAGE)
|
---|
171 | {
|
---|
172 | CAST_PTR(lev, i4_menu_focus_event_class, ev);
|
---|
173 |
|
---|
174 | if (lev->focus_state==i4_menu_focus_event_class::lost_focus)
|
---|
175 | sub_focused=i4_F;
|
---|
176 | else
|
---|
177 | sub_focused=i4_T;
|
---|
178 | }
|
---|
179 | else if (ev->type()==i4_event::WINDOW_MESSAGE)
|
---|
180 | {
|
---|
181 | CAST_PTR(wev, i4_window_message_class, ev);
|
---|
182 | if (wev->sub_type==i4_window_message_class::LOST_MOUSE_FOCUS)
|
---|
183 | focused=i4_F;
|
---|
184 | else if (wev->sub_type==i4_window_message_class::GOT_MOUSE_FOCUS)
|
---|
185 | focused=i4_T;
|
---|
186 |
|
---|
187 | i4_menu_class::receive_event(ev);
|
---|
188 | }
|
---|
189 | else if (ev->type()==i4_event::MOUSE_BUTTON_DOWN ||
|
---|
190 | ev->type()==i4_event::MOUSE_BUTTON_UP)
|
---|
191 | {
|
---|
192 | if (!focused && !sub_focused)
|
---|
193 | hide_active();
|
---|
194 |
|
---|
195 | if (focused)
|
---|
196 | i4_menu_class::receive_event(ev);
|
---|
197 | }
|
---|
198 | else if (ev->type()==i4_event::KEY_PRESS)
|
---|
199 | {
|
---|
200 | CAST_PTR(kev, i4_key_press_event_class, ev);
|
---|
201 | if (kev->key_code==I4_ESC)
|
---|
202 | hide_active();
|
---|
203 | else
|
---|
204 | i4_menu_class::receive_event(ev);
|
---|
205 | }
|
---|
206 | else if (focused)
|
---|
207 | i4_menu_class::receive_event(ev);
|
---|
208 | }
|
---|
209 |
|
---|
210 |
|
---|
211 | void i4_pull_menu_class::parent_draw(i4_draw_context_class &context)
|
---|
212 | {
|
---|
213 | i4_rect_list_class child_clip(&context.clip,0,0);
|
---|
214 | child_clip.intersect_list(&undrawn_area);
|
---|
215 |
|
---|
216 | child_clip.swap(&context.clip);
|
---|
217 |
|
---|
218 | style->deco_neutral_fill(local_image, 0,0, width()-1, height()-1, context);
|
---|
219 |
|
---|
220 |
|
---|
221 | // local_image->clear(menu_colors.text_background,context);
|
---|
222 |
|
---|
223 | child_clip.swap(&context.clip);
|
---|
224 | i4_parent_window_class::parent_draw(context);
|
---|
225 | }
|
---|
226 |
|
---|
227 | void i4_pull_menu_class::add_sub_menu(i4_menu_item_class *name,
|
---|
228 | i4_menu_class *sub_menu)
|
---|
229 | {
|
---|
230 | add_item(name);
|
---|
231 | name->set_menu_parent(this);
|
---|
232 | sub_menu->notify_focus_change(this);
|
---|
233 |
|
---|
234 | sub_menus.insert_end(*sub_menu);
|
---|
235 |
|
---|
236 | reparent(local_image, parent);
|
---|
237 | }
|
---|
238 |
|
---|
239 | void i4_pull_menu_class::reparent(i4_image_class *draw_area, i4_parent_window_class *parent)
|
---|
240 | {
|
---|
241 | i4_parent_window_class::reparent(draw_area, parent);
|
---|
242 | if (parent)
|
---|
243 | {
|
---|
244 | resize(parent->width(), 0);
|
---|
245 | arrange_right_down();
|
---|
246 |
|
---|
247 | w32 max_h=0;
|
---|
248 | for (win_iter c=children.begin(); c!=children.end(); ++c)
|
---|
249 | if (c->y()-y()+c->height()>max_h)
|
---|
250 | max_h=c->y()-y()+c->height();
|
---|
251 |
|
---|
252 | resize(parent->width(), max_h);
|
---|
253 | }
|
---|
254 | }
|
---|
255 |
|
---|
256 | void i4_pull_menu_class::resize(w16 new_width, w16 new_height)
|
---|
257 | {
|
---|
258 | i4_window_class::resize(new_width, new_height);
|
---|
259 | arrange_right_down();
|
---|
260 | }
|
---|
261 |
|
---|
262 |
|
---|
263 |
|
---|
264 | void i4_pull_menu_class::hide()
|
---|
265 | {
|
---|
266 | if (parent)
|
---|
267 | {
|
---|
268 | parent->remove_child(this);
|
---|
269 | hide_active();
|
---|
270 | }
|
---|
271 | parent=0;
|
---|
272 | }
|
---|