source: golgotha/src/i4/menu/pull.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 6.7 KB
Line 
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
14i4_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
30void 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
44void 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
58i4_pull_menu_class::~i4_pull_menu_class()
59{
60  unwatch();
61  hide_active();
62
63  sub_menus.destroy_all();
64}
65
66
67void 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
112void 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
139void 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
168void 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
211void 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
227void 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
239void 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
256void 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
264void i4_pull_menu_class::hide()
265{
266  if (parent)     
267  {
268    parent->remove_child(this);
269    hide_active();
270  }
271  parent=0;
272}
Note: See TracBrowser for help on using the repository browser.