source: golgotha/src/i4/menu/key_item.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: 8.0 KB
RevLine 
[80]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 "device/keys.hh"
10#include "menu/key_item.hh"
11#include "window/win_evt.hh"
12
13static i4_key_accel_watcher_class i4_key_accel_watcher_instance;
14
15enum { key_space=5 };
16
17i4_key_item_class::~i4_key_item_class()
18{
19  delete text;
20  if (use_key!=I4_NO_KEY)
21    i4_key_accel_watcher_instance.unwatch_key(this, use_key, key_modifiers);
22}
23
24i4_key_item_class::i4_key_item_class(const i4_const_str &_text,
25                                     i4_color_hint_class *color_hint,
26                                     i4_font_hint_class *font_hint,
27                                     i4_graphical_style_class *style,
28                                     w16 key,
29                                     w16 key_modifiers,
30                                     w16 pad_left_right,
31                                     w16 pad_up_down
32                                     )
33  : i4_menu_item_class(0,
34                       style,
35                       font_hint->normal_font->width(_text)+pad_left_right*2,
36                       font_hint->normal_font->height(_text)+pad_up_down*2,
37                       0,0,0,0),     
38    key_modifiers(key_modifiers),
39    color(color_hint),
40    font(font_hint),
41    text(new i4_str(_text,_text.length()+1)),
42    pad_lr(pad_left_right),
43    pad_ud(pad_up_down),
44    use_key(key)
45{
46  key_focused=i4_F;
47  valid=i4_T;
48 
49  w32 add_width=0;
50  i4_font_class *fnt=font_hint->normal_font;
51
52  if (key!=I4_NO_KEY)
53  {
54    i4_key_accel_watcher_instance.watch_key(this, key, key_modifiers);
55    i4_str *key_name=i4_key_name(key, key_modifiers);
56    add_width=fnt->width(*key_name)+key_space;
57    delete key_name;
58  }
59
60  resize(fnt->width(_text) + add_width + pad_left_right*2,
61         fnt->height(_text) + pad_up_down*2);
62}
63
64void i4_key_item_class::receive_event(i4_event *ev)
65{
66  if (ev->type()==i4_event::MOUSE_BUTTON_DOWN)
67  {
68    CAST_PTR(b,i4_mouse_button_down_event_class,ev);
69    if (b->but==i4_mouse_button_down_event_class::LEFT)
70    {
71      do_depress();
72      send_event(send.depress, PRESSED);
73      action();
74    }
75    else i4_menu_item_class::receive_event(ev);
76
77  } else if (ev->type()==i4_event::KEY_PRESS)
78  {
79    CAST_PTR(k,i4_key_press_event_class,ev);
80
81    if (k->modifiers & I4_MODIFIER_CTRL)
82      k->modifiers |= I4_MODIFIER_CTRL;
83    if (k->modifiers & I4_MODIFIER_ALT)
84      k->modifiers |= I4_MODIFIER_ALT;
85    if (k->modifiers & I4_MODIFIER_SHIFT)
86      k->modifiers |= I4_MODIFIER_SHIFT;
87     
88    if (k->key_code==use_key && k->modifiers==key_modifiers)
89      action();
90    else if (k->key==I4_ENTER)
91    {
92      do_depress();
93      send_event(send.depress, PRESSED);
94      action();
95    }
96    else if (k->key==I4_TAB)
97    {
98      i4_window_message_class nf(i4_window_message_class::REQUEST_NEXT_KEY_FOCUS,this);
99      i4_kernel.send_event(parent, &nf);
100    }
101    else if (k->key==I4_LEFT)
102    {
103      i4_window_message_class l(i4_window_message_class::REQUEST_LEFT_KEY_FOCUS,this);
104      i4_kernel.send_event(parent, &l);
105    }
106    else if (k->key==I4_RIGHT)
107    {
108      i4_window_message_class r(i4_window_message_class::REQUEST_RIGHT_KEY_FOCUS,this);
109      i4_kernel.send_event(parent, &r);
110    }
111    else if (k->key==I4_UP)
112    {
113      i4_window_message_class u(i4_window_message_class::REQUEST_UP_KEY_FOCUS,this);
114      i4_kernel.send_event(parent, &u);
115    }
116    else if (k->key==I4_DOWN)
117    {
118      i4_window_message_class d(i4_window_message_class::REQUEST_DOWN_KEY_FOCUS,this);
119      i4_kernel.send_event(parent, &d);
120    }
121    else
122      i4_menu_item_class::receive_event(ev);
123  }
124  else if (ev->type()==i4_event::WINDOW_MESSAGE)
125  {
126    CAST_PTR(wev, i4_window_message_class, ev);
127    if (wev->sub_type==i4_window_message_class::GOT_KEYBOARD_FOCUS)
128      key_focused=i4_T;
129    else if (wev->sub_type==i4_window_message_class::LOST_KEYBOARD_FOCUS)
130      key_focused=i4_F;
131    else if (wev->sub_type==i4_window_message_class::NOTIFY_RESIZE)
132    {
133      CAST_PTR(rev, i4_window_notify_resize_class, ev);
134      if (rev->from()==parent)
135      {
136        w32 nw=rev->new_width-(x()-parent->x())*2;
137        if (nw!=width())
138          resize(nw, height());
139      }
140    }
141
142    i4_menu_item_class::receive_event(ev);
143  }
144  else
145    i4_menu_item_class::receive_event(ev);
146}
147
148
149i4_key_accel_watcher_class::i4_key_accel_watcher_class()
150{
151  initialized=i4_F;
152  memset(user,0,sizeof(user));
153  total=0;
154}
155
156
157i4_key_item_class **i4_key_accel_watcher_class::
158   key_item_pointer_type::get_from_modifiers(w16 modifiers)
159{
160  int index=0;
161
162  if (modifiers & I4_MODIFIER_SHIFT)
163    index |= 1;
164
165  if (modifiers & I4_MODIFIER_CTRL)
166    index |= 2;
167   
168  if (modifiers & I4_MODIFIER_ALT)
169    index |= 3;
170
171  return &modkey[index];
172}
173
174void i4_key_accel_watcher_class::watch_key(i4_key_item_class *who, w16 key, w16 modifiers)
175{
176  if (!initialized)
177  {
178    i4_kernel.request_events(this, 
179                             i4_device_class::FLAG_KEY_PRESS |
180                             i4_device_class::FLAG_KEY_RELEASE);
181    initialized=i4_T;
182  }
183
184  I4_TEST(key<I4_NUM_KEYS, "Key out of range");
185  if (*user[key].get_from_modifiers(modifiers))
186  {
187    char name[80];
188    i4_warning("key alread has function [%s]\n", i4_get_key_name(key,modifiers,name));
189  }
190  else total++;
191
192  *user[key].get_from_modifiers(modifiers)=who;
193}
194
195void i4_key_accel_watcher_class::unwatch_key(i4_key_item_class *who, w16 key, w16 modifiers)
196{
197  if (*user[key].get_from_modifiers(modifiers)==who)
198  {
199    *user[key].get_from_modifiers(modifiers)=0;
200    total--;
201    if (total==0)
202    {     
203      i4_kernel.unrequest_events(this, 
204                                 i4_device_class::FLAG_KEY_PRESS |
205                                 i4_device_class::FLAG_KEY_RELEASE);
206      initialized=i4_F;
207    }
208  }
209}
210
211
212
213void i4_key_accel_watcher_class::receive_event(i4_event *ev)
214{
215  if (ev->type()==i4_event::KEY_PRESS)
216  {
217    CAST_PTR(kev, i4_key_press_event_class, ev);
218
219    // if the object has the keyboard focus, then it will get the key through
220    // normal window channels
221    i4_key_item_class *i=*(user[kev->key_code].get_from_modifiers(kev->modifiers));
222    if (i && !i->has_keyboard_focus())     
223      i4_kernel.send_event(i, ev);
224  }
225}
226
227
228
229void i4_key_item_class::parent_draw(i4_draw_context_class &context)
230{
231  local_image->add_dirty(0,0,width()-1,height()-1,context);
232
233  i4_color fg,bg;
234 
235
236  if (active)
237  {
238    fg=color->selected_text_foreground;
239    bg=color->selected_text_background;
240  }
241  else
242  {
243    fg=color->text_foreground;
244    bg=color->text_background;
245  }
246
247  i4_str *key_name;
248
249  if (use_key!=I4_NO_KEY)
250    key_name=i4_key_name(use_key, key_modifiers);
251  else key_name=0;
252
253  if (!active)
254    hint->deco_neutral_fill(local_image, 0,0, width()-1, height()-1, context);
255  else
256    local_image->clear(bg, context);
257
258  i4_font_class *fnt=font->normal_font;
259
260  if (!valid)
261  {
262    fg=color->window.passive.dark;
263
264    fnt->set_color(color->window.passive.bright);
265    fnt->put_string(local_image, pad_lr+1, pad_ud+1, *text,context);
266
267    if (key_name)
268      fnt->put_string(local_image, width() - pad_lr - fnt->width(*key_name) + 1,
269                      pad_ud + 1,
270                      *key_name, context);
271
272  }
273
274  if (valid || !active)
275  {
276    font->normal_font->set_color(fg);
277    font->normal_font->put_string(local_image, pad_lr, pad_ud, *text,context);
278    if (key_name)
279      fnt->put_string(local_image, width() - pad_lr - fnt->width(*key_name),
280                      pad_ud, *key_name, context);
281
282  }
283
284  if (key_name)
285    delete key_name;
286}
287
288
289
Note: See TracBrowser for help on using the repository browser.