fltk  1.3.5-source
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X.
  Fossies Dox: fltk-1.3.5-source.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_Menu.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // Menu code for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2015 by Bill Spitzak and others.
7 //
8 // This library is free software. Distribution and use rights are outlined in
9 // the file "COPYING" which should have been included with this file. If this
10 // file is missing or damaged, see the license at:
11 //
12 // http://www.fltk.org/COPYING.php
13 //
14 // Please report all bugs and problems on the following page:
15 //
16 // http://www.fltk.org/str.php
17 //
18 
19 // Warning: this menu code is quite a mess!
20 
21 // This file contains code for implementing Fl_Menu_Item, and for
22 // methods for bringing up popup menu hierarchies without using the
23 // Fl_Menu_ widget.
24 
25 #include <FL/Fl.H>
26 #include <FL/Fl_Menu_Window.H>
27 #include <FL/Fl_Menu_.H>
28 #include <FL/fl_draw.H>
29 #include <stdio.h>
30 #include "flstring.h"
31 
58 int Fl_Menu_Item::size() const {
59  const Fl_Menu_Item* m = this;
60  int nest = 0;
61  for (;;) {
62  if (!m->text) {
63  if (!nest) return (int) (m-this+1);
64  nest--;
65  } else if (m->flags & FL_SUBMENU) {
66  nest++;
67  }
68  m++;
69  }
70 }
71 
72 // Advance a pointer to next visible or invisible item of a menu array,
73 // skipping the contents of submenus.
75  int nest = 0;
76  do {
77  if (!m->text) {
78  if (!nest) return m;
79  nest--;
80  } else if (m->flags&FL_SUBMENU) {
81  nest++;
82  }
83  m++;
84  }
85  while (nest);
86  return m;
87 }
88 
94 const Fl_Menu_Item* Fl_Menu_Item::next(int n) const {
95  if (n < 0) return 0; // this is so selected==-1 returns NULL
96  const Fl_Menu_Item* m = this;
97  if (!m->visible()) n++;
98  while (n) {
99  m = next_visible_or_not(m);
100  if (m->visible() || !m->text) n--;
101  }
102  return m;
103 }
104 
105 // appearance of current menus are pulled from this parent widget:
106 static const Fl_Menu_* button=0;
107 
109 
110 // tiny window for title of menu:
111 class menutitle : public Fl_Menu_Window {
112  void draw();
113 public:
115  menutitle(int X, int Y, int W, int H, const Fl_Menu_Item*);
116 };
117 
118 // each vertical menu has one of these:
119 class menuwindow : public Fl_Menu_Window {
120  void draw();
121  void drawentry(const Fl_Menu_Item*, int i, int erase);
122 public:
124  int handle(int);
125 #if defined (__APPLE__) || defined (USE_X11)
126  int early_hide_handle(int);
127 #endif
128  int itemheight; // zero == menubar
129  int numitems;
130  int selected;
131  int drawn_selected; // last redraw has this selected
134  menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H,
135  const Fl_Menu_Item* picked, const Fl_Menu_Item* title,
136  int menubar = 0, int menubar_title = 0, int right_edge = 0);
137  ~menuwindow();
138  void set_selected(int);
139  int find_selected(int mx, int my);
140  int titlex(int);
141  void autoscroll(int);
142  void position(int x, int y);
143  int is_inside(int x, int y);
144 };
145 
146 #define LEADING 4 // extra vertical leading
147 
148 extern char fl_draw_shortcut;
149 
154 int Fl_Menu_Item::measure(int* hp, const Fl_Menu_* m) const {
155  Fl_Label l;
156  l.value = text;
157  l.image = 0;
158  l.deimage = 0;
159  l.type = labeltype_;
160  l.font = labelsize_ || labelfont_ ? labelfont_ : (m ? m->textfont() : FL_HELVETICA);
161  l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE;
162  l.color = FL_FOREGROUND_COLOR; // this makes no difference?
163  fl_draw_shortcut = 1;
164  int w = 0; int h = 0;
165  l.measure(w, hp ? *hp : h);
166  fl_draw_shortcut = 0;
168  return w;
169 }
170 
172 void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m,
173  int selected) const {
174  Fl_Label l;
175  l.value = text;
176  l.image = 0;
177  l.deimage = 0;
178  l.type = labeltype_;
179  l.font = labelsize_ || labelfont_ ? labelfont_ : (m ? m->textfont() : FL_HELVETICA);
180  l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE;
182  if (!active()) l.color = fl_inactive((Fl_Color)l.color);
183  Fl_Color color = m ? m->color() : FL_GRAY;
184  if (selected) {
186  Fl_Boxtype b = m && m->down_box() ? m->down_box() : FL_FLAT_BOX;
187  if (fl_contrast(r,color)!=r) { // back compatibility boxtypes
188  if (selected == 2) { // menu title
189  r = color;
190  b = m ? m->box() : FL_UP_BOX;
191  } else {
192  r = (Fl_Color)(FL_COLOR_CUBE-1); // white
194  }
195  } else {
197  }
198  if (selected == 2) { // menu title
199  fl_draw_box(b, x, y, w, h, r);
200  x += 3;
201  w -= 8;
202  } else {
203  fl_draw_box(b, x+1, y-(LEADING-2)/2, w-2, h+(LEADING-2), r);
204  }
205  }
206 
208  int d = (h - FL_NORMAL_SIZE + 1) / 2;
209  int W = h - 2 * d;
210 
211  if (flags & FL_MENU_RADIO) {
213  if (value()) {
214  int tW = (W - Fl::box_dw(FL_ROUND_DOWN_BOX)) / 2 + 1;
215  if ((W - tW) & 1) tW++; // Make sure difference is even to center
216  int td = (W - tW) / 2;
217  if (Fl::is_scheme("gtk+")) {
219  tW --;
220  fl_pie(x + td + 1, y + d + td - 1, tW + 3, tW + 3, 0.0, 360.0);
222  } else fl_color(labelcolor_);
223 
224  switch (tW) {
225  // Larger circles draw fine...
226  default :
227  fl_pie(x + td + 2, y + d + td, tW, tW, 0.0, 360.0);
228  break;
229 
230  // Small circles don't draw well on many systems...
231  case 6 :
232  fl_rectf(x + td + 4, y + d + td, tW - 4, tW);
233  fl_rectf(x + td + 3, y + d + td + 1, tW - 2, tW - 2);
234  fl_rectf(x + td + 2, y + d + td + 2, tW, tW - 4);
235  break;
236 
237  case 5 :
238  case 4 :
239  case 3 :
240  fl_rectf(x + td + 3, y + d + td, tW - 2, tW);
241  fl_rectf(x + td + 2, y + d + td + 1, tW, tW - 2);
242  break;
243 
244  case 2 :
245  case 1 :
246  fl_rectf(x + td + 2, y + d + td, tW, tW);
247  break;
248  }
249 
250  if (Fl::is_scheme("gtk+")) {
252  fl_arc(x + td + 2, y + d + td, tW + 1, tW + 1, 60.0, 180.0);
253  }
254  }
255  } else {
257  if (value()) {
258  if (Fl::is_scheme("gtk+")) {
260  } else {
262  }
263  int tx = x + 5;
264  int tw = W - 6;
265  int d1 = tw/3;
266  int d2 = tw-d1;
267  int ty = y + d + (W+d2)/2-d1-2;
268  for (int n = 0; n < 3; n++, ty++) {
269  fl_line(tx, ty, tx+d1, ty+d1);
270  fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
271  }
272  }
273  }
274  x += W + 3;
275  w -= W + 3;
276  }
277 
279  l.draw(x+3, y, w>6 ? w-6 : 0, h, FL_ALIGN_LEFT);
280  fl_draw_shortcut = 0;
281 }
282 
283 menutitle::menutitle(int X, int Y, int W, int H, const Fl_Menu_Item* L) :
284  Fl_Menu_Window(X, Y, W, H, 0) {
285  end();
286  set_modal();
287  clear_border();
288  set_menu_window();
289  menu = L;
291 }
292 
293 menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
294  const Fl_Menu_Item* picked, const Fl_Menu_Item* t,
295  int menubar, int menubar_title, int right_edge)
296  : Fl_Menu_Window(X, Y, Wp, Hp, 0)
297 {
298  int scr_x, scr_y, scr_w, scr_h;
299  int tx = X, ty = Y;
300 
301  Fl::screen_work_area(scr_x, scr_y, scr_w, scr_h);
302  if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w;
303 
304  end();
305  set_modal();
306  clear_border();
307  set_menu_window();
308  menu = m;
309  if (m) m = m->first(); // find the first item that needs to be rendered
310  drawn_selected = -1;
311  if (button) {
312  box(button->box());
313  if (box() == FL_NO_BOX || box() == FL_FLAT_BOX) box(FL_UP_BOX);
314  } else {
315  box(FL_UP_BOX);
316  }
317  color(button && !Fl::scheme() ? button->color() : FL_GRAY);
318  selected = -1;
319  {
320  int j = 0;
321  if (m) for (const Fl_Menu_Item* m1=m; ; m1 = m1->next(), j++) {
322  if (picked) {
323  if (m1 == picked) {selected = j; picked = 0;}
324  else if (m1 > picked) {selected = j-1; picked = 0; Wp = Hp = 0;}
325  }
326  if (!m1->text) break;
327  }
328  numitems = j;}
329 
330  if (menubar) {
331  itemheight = 0;
332  title = 0;
333  return;
334  }
335 
336  itemheight = 1;
337 
338  int hotKeysw = 0;
339  int hotModsw = 0;
340  int Wtitle = 0;
341  int Htitle = 0;
342  if (t) Wtitle = t->measure(&Htitle, button) + 12;
343  int W = 0;
344  if (m) for (; m->text; m = m->next()) {
345  int hh;
346  int w1 = m->measure(&hh, button);
347  if (hh+LEADING>itemheight) itemheight = hh+LEADING;
349  w1 += FL_NORMAL_SIZE;
350  if (w1 > W) W = w1;
351  // calculate the maximum width of all shortcuts
352  if (m->shortcut_) {
353  // s is a pointer to the UTF-8 string for the entire shortcut
354  // k points only to the key part (minus the modifier keys)
355  const char *k, *s = fl_shortcut_label(m->shortcut_, &k);
356  if (fl_utf_nb_char((const unsigned char*)k, (int) strlen(k))<=4) {
357  // a regular shortcut has a right-justified modifier followed by a left-justified key
358  w1 = int(fl_width(s, (int) (k-s)));
359  if (w1 > hotModsw) hotModsw = w1;
360  w1 = int(fl_width(k))+4;
361  if (w1 > hotKeysw) hotKeysw = w1;
362  } else {
363  // a shortcut with a long modifier is right-justified to the menu
364  w1 = int(fl_width(s))+4;
365  if (w1 > (hotModsw+hotKeysw)) {
366  hotModsw = w1-hotKeysw;
367  }
368  }
369  }
371  }
372  shortcutWidth = hotKeysw;
373  if (selected >= 0 && !Wp) X -= W/2;
374  int BW = Fl::box_dx(box());
375  W += hotKeysw+hotModsw+2*BW+7;
376  if (Wp > W) W = Wp;
377  if (Wtitle > W) W = Wtitle;
378 
379  if (X < scr_x) X = scr_x;
380  // this change improves popup submenu positioning at right screen edge,
381  // but it makes right_edge argument useless
382  //if (X > scr_x+scr_w-W) X = right_edge-W;
383  if (X > scr_x+scr_w-W) X = scr_x+scr_w-W;
384  x(X); w(W);
385  h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3);
386  if (selected >= 0) {
387  Y = Y+(Hp-itemheight)/2-selected*itemheight-BW;
388  } else {
389  Y = Y+Hp;
390  // if the menu hits the bottom of the screen, we try to draw
391  // it above the menubar instead. We will not adjust any menu
392  // that has a selected item.
393  if (Y+h()>scr_y+scr_h && Y-h()>=scr_y) {
394  if (Hp>1) {
395  // if we know the height of the Fl_Menu_, use it
396  Y = Y-Hp-h();
397  } else if (t) {
398  // assume that the menubar item height relates to the first
399  // menuitem as well
400  Y = Y-itemheight-h()-Fl::box_dh(box());
401  } else {
402  // draw the menu to the right
403  Y = Y-h()+itemheight+Fl::box_dy(box());
404  }
405  }
406  }
407  if (m) y(Y); else {y(Y-2); w(1); h(1);}
408 
409  if (t) {
410  if (menubar_title) {
411  int dy = Fl::box_dy(button->box())+1;
412  int ht = button->h()-dy*2;
413  title = new menutitle(tx, ty-ht-dy, Wtitle, ht, t);
414  } else {
415  int dy = 2;
416  int ht = Htitle+2*BW+3;
417  title = new menutitle(X, Y-ht-dy, Wtitle, ht, t);
418  }
419  } else {
420  title = 0;
421  }
422 }
423 
425  hide();
426  delete title;
427 }
428 
429 void menuwindow::position(int X, int Y) {
430  if (title) {title->position(X, title->y()+Y-y());}
432  // x(X); y(Y); // don't wait for response from X
433 }
434 
435 // scroll so item i is visible on screen
437  int scr_y, scr_h;
438  int Y = y()+Fl::box_dx(box())+2+n*itemheight;
439 
440  int xx, ww;
441  Fl::screen_work_area(xx, scr_y, ww, scr_h);
442  if (Y <= scr_y) Y = scr_y-Y+10;
443  else {
444  Y = Y+itemheight-scr_h-scr_y;
445  if (Y < 0) return;
446  Y = -Y-10;
447  }
449  // y(y()+Y); // don't wait for response from X
450 }
451 
453 
454 void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) {
455  if (!m) return; // this happens if -1 is selected item and redrawn
456 
457  int BW = Fl::box_dx(box());
458  int xx = BW;
459  int W = w();
460  int ww = W-2*BW-1;
461  int yy = BW+1+n*itemheight;
462  int hh = itemheight - LEADING;
463 
464  if (eraseit && n != selected) {
465  fl_push_clip(xx+1, yy-(LEADING-2)/2, ww-2, hh+(LEADING-2));
466  draw_box(box(), 0, 0, w(), h(), button ? button->color() : color());
467  fl_pop_clip();
468  }
469 
470  m->draw(xx, yy, ww, hh, button, n==selected);
471 
472  // the shortcuts and arrows assume fl_color() was left set by draw():
473  if (m->submenu()) {
474  int sz = (hh-7)&-2;
475  int y1 = yy+(hh-sz)/2;
476  int x1 = xx+ww-sz-3;
477  fl_polygon(x1+2, y1, x1+2, y1+sz, x1+sz/2+2, y1+sz/2);
478  } else if (m->shortcut_) {
479  Fl_Font f = m->labelsize_ || m->labelfont_ ? (Fl_Font)m->labelfont_ :
481  fl_font(f, m->labelsize_ ? m->labelsize_ :
483  const char *k, *s = fl_shortcut_label(m->shortcut_, &k);
484  if (fl_utf_nb_char((const unsigned char*)k, (int) strlen(k))<=4) {
485  // right-align the modifiers and left-align the key
486  char *buf = (char*)malloc(k-s+1);
487  memcpy(buf, s, k-s); buf[k-s] = 0;
488  fl_draw(buf, xx, yy, ww-shortcutWidth, hh, FL_ALIGN_RIGHT);
489  fl_draw( k, xx+ww-shortcutWidth, yy, shortcutWidth, hh, FL_ALIGN_LEFT);
490  free(buf);
491  } else {
492  // right-align to the menu
493  fl_draw(s, xx, yy, ww-4, hh, FL_ALIGN_RIGHT);
494  }
495  }
496 
497  if (m->flags & FL_MENU_DIVIDER) {
499  fl_xyline(BW-1, yy+hh+(LEADING-2)/2, W-2*BW+2);
501  fl_xyline(BW-1, yy+hh+((LEADING-2)/2+1), W-2*BW+2);
502  }
503 }
504 
506  menu->draw(0, 0, w(), h(), button, 2);
507 }
508 
510  if (damage() != FL_DAMAGE_CHILD) { // complete redraw
511  fl_draw_box(box(), 0, 0, w(), h(), button ? button->color() : color());
512  if (menu) {
513  const Fl_Menu_Item* m; int j;
514  for (m=menu->first(), j=0; m->text; j++, m = m->next()) drawentry(m, j, 0);
515  }
516  } else {
517  if (damage() & FL_DAMAGE_CHILD && selected!=drawn_selected) { // change selection
520  }
521  }
523 }
524 
526  if (n != selected) {selected = n; damage(FL_DAMAGE_CHILD);}
527 }
528 
530 
531 int menuwindow::find_selected(int mx, int my) {
532  if (!menu || !menu->text) return -1;
533  mx -= x();
534  my -= y();
535  if (my < 0 || my >= h()) return -1;
536  if (!itemheight) { // menubar
537  int xx = 3; int n = 0;
538  const Fl_Menu_Item* m = menu ? menu->first() : 0;
539  for (; ; m = m->next(), n++) {
540  if (!m->text) return -1;
541  xx += m->measure(0, button) + 16;
542  if (xx > mx) break;
543  }
544  return n;
545  }
546  if (mx < Fl::box_dx(box()) || mx >= w()) return -1;
547  int n = (my-Fl::box_dx(box())-1)/itemheight;
548  if (n < 0 || n>=numitems) return -1;
549  return n;
550 }
551 
552 // return horizontal position for item n in a menubar:
553 int menuwindow::titlex(int n) {
554  const Fl_Menu_Item* m;
555  int xx = 3;
556  for (m=menu->first(); n--; m = m->next()) xx += m->measure(0, button) + 16;
557  return xx;
558 }
559 
560 // return 1, if the given root coordinates are inside the window
561 int menuwindow::is_inside(int mx, int my) {
562  if ( mx < x_root() || mx >= x_root() + w() ||
563  my < y_root() || my >= y_root() + h()) {
564  return 0;
565  }
566  if (itemheight == 0 && find_selected(mx, my) == -1) {
567  // in the menubar but out from any menu header
568  return 0;
569  }
570  return 1;
571 }
572 
574 // Fl_Menu_Item::popup(...)
575 
576 // Because Fl::grab() is done, all events go to one of the menu windows.
577 // But the handle method needs to look at all of them to find out
578 // what item the user is pointing at. And it needs a whole lot
579 // of other state variables to determine what is going on with
580 // the currently displayed menus.
581 // So the main loop (handlemenu()) puts all the state in a structure
582 // and puts a pointer to it in a static location, so the handle()
583 // on menus can refer to it and alter it. The handle() method
584 // changes variables in this state to indicate what item is
585 // picked, but does not actually alter the display, instead the
586 // main loop does that. This is because the X mapping and unmapping
587 // of windows is slow, and we don't want to fall behind the events.
588 
589 // values for menustate.state:
590 #define INITIAL_STATE 0 // no mouse up or down since popup() called
591 #define PUSH_STATE 1 // mouse has been pushed on a normal item
592 #define DONE_STATE 2 // exit the popup, the current item was picked
593 #define MENU_PUSH_STATE 3 // mouse has been pushed on a menu title
594 
595 struct menustate {
596  const Fl_Menu_Item* current_item; // what mouse is pointing at
597  int menu_number; // which menu it is in
598  int item_number; // which item in that menu, -1 if none
599  menuwindow* p[20]; // pointers to menus
600  int nummenus;
601  int menubar; // if true p[0] is a menubar
602  int state;
603  menuwindow* fakemenu; // kludge for buttons in menubar
604  int is_inside(int mx, int my);
605 };
606 static menustate* p=0;
607 
608 // return 1 if the coordinates are inside any of the menuwindows
609 int menustate::is_inside(int mx, int my) {
610  int i;
611  for (i=nummenus-1; i>=0; i--) {
612  if (p[i]->is_inside(mx, my))
613  return 1;
614  }
615  return 0;
616 }
617 
618 static inline void setitem(const Fl_Menu_Item* i, int m, int n) {
619  p->current_item = i;
620  p->menu_number = m;
621  p->item_number = n;
622 }
623 
624 static void setitem(int m, int n) {
625  menustate &pp = *p;
626  pp.current_item = (n >= 0) ? pp.p[m]->menu->next(n) : 0;
627  pp.menu_number = m;
628  pp.item_number = n;
629 }
630 
631 static int forward(int menu) { // go to next item in menu menu if possible
632  menustate &pp = *p;
633  // Fl_Menu_Button can generate menu=-1. This line fixes it and selectes the first item.
634  if (menu==-1)
635  menu = 0;
636  menuwindow &m = *(pp.p[menu]);
637  int item = (menu == pp.menu_number) ? pp.item_number : m.selected;
638  while (++item < m.numitems) {
639  const Fl_Menu_Item* m1 = m.menu->next(item);
640  if (m1->activevisible()) {setitem(m1, menu, item); return 1;}
641  }
642  return 0;
643 }
644 
645 static int backward(int menu) { // previous item in menu menu if possible
646  menustate &pp = *p;
647  menuwindow &m = *(pp.p[menu]);
648  int item = (menu == pp.menu_number) ? pp.item_number : m.selected;
649  if (item < 0) item = m.numitems;
650  while (--item >= 0) {
651  const Fl_Menu_Item* m1 = m.menu->next(item);
652  if (m1->activevisible()) {setitem(m1, menu, item); return 1;}
653  }
654  return 0;
655 }
656 
657 int menuwindow::handle(int e) {
658 #if defined (__APPLE__) || defined (USE_X11)
659  // This off-route takes care of the "detached menu" bug on OS X.
660  // Apple event handler requires that we hide all menu windows right
661  // now, so that Carbon can continue undisturbed with handling window
662  // manager events, like dragging the application window.
663  int ret = early_hide_handle(e);
664  menustate &pp = *p;
665  if (pp.state == DONE_STATE) {
666  hide();
667  if (pp.fakemenu) {
668  pp.fakemenu->hide();
669  if (pp.fakemenu->title)
670  pp.fakemenu->title->hide();
671  }
672  int i = pp.nummenus;
673  while (i>0) {
674  menuwindow *mw = pp.p[--i];
675  if (mw) {
676  mw->hide();
677  if (mw->title)
678  mw->title->hide();
679  }
680  }
681  }
682  return ret;
683 }
684 
685 int menuwindow::early_hide_handle(int e) {
686 #endif
687  menustate &pp = *p;
688  switch (e) {
689  case FL_KEYBOARD:
690  switch (Fl::event_key()) {
691  case FL_BackSpace:
692  BACKTAB:
693  if (!backward(pp.menu_number)) {pp.item_number = -1;backward(pp.menu_number);}
694  return 1;
695  case FL_Up:
696  if (pp.menubar && pp.menu_number == 0) {
697  // Do nothing...
698  } else if (backward(pp.menu_number)) {
699  // Do nothing...
700  } else if (pp.menubar && pp.menu_number==1) {
701  setitem(0, pp.p[0]->selected);
702  }
703  return 1;
704  case FL_Tab:
705  if (Fl::event_shift()) goto BACKTAB;
706  case FL_Down:
707  if (pp.menu_number || !pp.menubar) {
708  if (!forward(pp.menu_number) && Fl::event_key()==FL_Tab) {
709  pp.item_number = -1;
710  forward(pp.menu_number);
711  }
712  } else if (pp.menu_number < pp.nummenus-1) {
713  forward(pp.menu_number+1);
714  }
715  return 1;
716  case FL_Right:
717  if (pp.menubar && (pp.menu_number<=0 || (pp.menu_number==1 && pp.nummenus==2)))
718  forward(0);
719  else if (pp.menu_number < pp.nummenus-1) forward(pp.menu_number+1);
720  return 1;
721  case FL_Left:
722  if (pp.menubar && pp.menu_number<=1) backward(0);
723  else if (pp.menu_number>0)
724  setitem(pp.menu_number-1, pp.p[pp.menu_number-1]->selected);
725  return 1;
726  case FL_Enter:
727  case FL_KP_Enter:
728  case ' ':
729  pp.state = DONE_STATE;
730  return 1;
731  case FL_Escape:
732  setitem(0, -1, 0);
733  pp.state = DONE_STATE;
734  return 1;
735  }
736  break;
737  case FL_SHORTCUT:
738  {
739  for (int mymenu = pp.nummenus; mymenu--;) {
740  menuwindow &mw = *(pp.p[mymenu]);
741  int item; const Fl_Menu_Item* m = mw.menu->find_shortcut(&item);
742  if (m) {
743  setitem(m, mymenu, item);
744  if (!m->submenu()) pp.state = DONE_STATE;
745  return 1;
746  }
747  }
748  }
749  break;
750  case FL_MOVE:
751 #if ! (defined(WIN32) || defined(__APPLE__))
752  if (pp.state == DONE_STATE) {
753  return 1; // Fix for STR #2619
754  }
755  /* FALLTHROUGH */
756 #endif
757  case FL_ENTER:
758  case FL_PUSH:
759  case FL_DRAG:
760  {
761  int mx = Fl::event_x_root();
762  int my = Fl::event_y_root();
763  int item=0; int mymenu = pp.nummenus-1;
764  // Clicking or dragging outside menu cancels it...
765  if ((!pp.menubar || mymenu) && !pp.is_inside(mx, my)) {
766  setitem(0, -1, 0);
767  if (e==FL_PUSH)
768  pp.state = DONE_STATE;
769  return 1;
770  }
771  for (mymenu = pp.nummenus-1; ; mymenu--) {
772  item = pp.p[mymenu]->find_selected(mx, my);
773  if (item >= 0)
774  break;
775  if (mymenu <= 0) {
776  // buttons in menubars must be deselected if we move outside of them!
777  if (pp.menu_number==-1 && e==FL_PUSH) {
778  pp.state = DONE_STATE;
779  return 1;
780  }
781  if (pp.current_item && pp.menu_number==0 && !pp.current_item->submenu()) {
782  if (e==FL_PUSH)
783  pp.state = DONE_STATE;
784  setitem(0, -1, 0);
785  return 1;
786  }
787  // all others can stay selected
788  return 0;
789  }
790  }
791  if (my == 0 && item > 0) setitem(mymenu, item - 1);
792  else setitem(mymenu, item);
793  if (e == FL_PUSH) {
794  if (pp.current_item && pp.current_item->submenu() // this is a menu title
795  && item != pp.p[mymenu]->selected // and it is not already on
796  && !pp.current_item->callback_) // and it does not have a callback
797  pp.state = MENU_PUSH_STATE;
798  else
799  pp.state = PUSH_STATE;
800  }
801  }
802  return 1;
803  case FL_RELEASE:
804  // Mouse must either be held down/dragged some, or this must be
805  // the second click (not the one that popped up the menu):
806  if ( !Fl::event_is_click()
807  || pp.state == PUSH_STATE
808  || (pp.menubar && pp.current_item && !pp.current_item->submenu()) // button
809  ) {
810 #if 0 // makes the check/radio items leave the menu up
811  const Fl_Menu_Item* m = pp.current_item;
812  if (m && button && (m->flags & (FL_MENU_TOGGLE|FL_MENU_RADIO))) {
813  ((Fl_Menu_*)button)->picked(m);
814  pp.p[pp.menu_number]->redraw();
815  } else
816 #endif
817  // do nothing if they try to pick inactive items
818  if (!pp.current_item || pp.current_item->activevisible())
819  pp.state = DONE_STATE;
820  }
821  return 1;
822  }
823  return Fl_Window::handle(e);
824 }
825 
837  int X, int Y, int W, int H,
838  const Fl_Menu_Item* initial_item,
839  const Fl_Menu_* pbutton,
840  const Fl_Menu_Item* t,
841  int menubar) const {
842  Fl_Group::current(0); // fix possible user error...
843 
844  // track the Fl_Menu_ widget to make sure we notice if it gets
845  // deleted while the menu is open (STR #3503)
846  Fl_Widget_Tracker wp((Fl_Widget *)pbutton);
847 
848  button = pbutton;
849  if (pbutton && pbutton->window()) {
850  for (Fl_Window* w = pbutton->window(); w; w = w->window()) {
851  X += w->x();
852  Y += w->y();
853  }
854  } else {
855  X += Fl::event_x_root()-Fl::event_x();
857  }
858  menuwindow mw(this, X, Y, W, H, initial_item, t, menubar);
859  Fl::grab(mw);
860  menustate pp; p = &pp;
861  pp.p[0] = &mw;
862  pp.nummenus = 1;
863  pp.menubar = menubar;
864  pp.state = INITIAL_STATE;
865  pp.fakemenu = 0; // kludge for buttons in menubar
866 
867  // preselected item, pop up submenus if necessary:
868  if (initial_item && mw.selected >= 0) {
869  setitem(0, mw.selected);
870  goto STARTUP;
871  }
872 
873  pp.current_item = 0; pp.menu_number = 0; pp.item_number = -1;
874  if (menubar) {
875  // find the initial menu
876  if (!mw.handle(FL_DRAG)) {
877  Fl::grab(0);
878  return 0;
879  }
880  }
881  initial_item = pp.current_item;
882  if (initial_item) goto STARTUP;
883 
884  // the main loop: runs until p.state goes to DONE_STATE or the menu
885  // widget is deleted (e.g. from a timer callback, see STR #3503):
886  for (;;) {
887 
888  // make sure all the menus are shown:
889  {
890  for (int k = menubar; k < pp.nummenus; k++) {
891  if (!pp.p[k]->shown()) {
892  if (pp.p[k]->title) pp.p[k]->title->show();
893  pp.p[k]->show();
894  }
895  }
896  }
897 
898  // get events:
899  {
900  const Fl_Menu_Item* oldi = pp.current_item;
901  Fl::wait();
902  if (pbutton && wp.deleted()) // menu widget has been deleted (STR #3503)
903  break;
904  if (pp.state == DONE_STATE) break; // done.
905  if (pp.current_item == oldi) continue;
906  }
907 
908  // only do rest if item changes:
909  if(pp.fakemenu) {delete pp.fakemenu; pp.fakemenu = 0;} // turn off "menubar button"
910 
911  if (!pp.current_item) { // pointing at nothing
912  // turn off selection in deepest menu, but don't erase other menus:
913  pp.p[pp.nummenus-1]->set_selected(-1);
914  continue;
915  }
916 
917  if(pp.fakemenu) {delete pp.fakemenu; pp.fakemenu = 0;}
918  initial_item = 0; // stop the startup code
919  pp.p[pp.menu_number]->autoscroll(pp.item_number);
920 
921  STARTUP:
922  menuwindow& cw = *pp.p[pp.menu_number];
923  const Fl_Menu_Item* m = pp.current_item;
924  if (!m->activevisible()) { // pointing at inactive item
925  cw.set_selected(-1);
926  initial_item = 0; // turn off startup code
927  continue;
928  }
929  cw.set_selected(pp.item_number);
930 
931  if (m==initial_item) initial_item=0; // stop the startup code if item found
932  if (m->submenu()) {
933  const Fl_Menu_Item* title = m;
934  const Fl_Menu_Item* menutable;
935  if (m->flags&FL_SUBMENU) menutable = m+1;
936  else menutable = (Fl_Menu_Item*)(m)->user_data_;
937  // figure out where new menu goes:
938  int nX, nY;
939  if (!pp.menu_number && pp.menubar) { // menu off a menubar:
940  nX = cw.x() + cw.titlex(pp.item_number);
941  nY = cw.y() + cw.h();
942  initial_item = 0;
943  } else {
944  nX = cw.x() + cw.w();
945  nY = cw.y() + pp.item_number * cw.itemheight;
946  title = 0;
947  }
948  if (initial_item) { // bring up submenu containing initial item:
949  menuwindow* n = new menuwindow(menutable,X,Y,W,H,initial_item,title,0,0,cw.x());
950  pp.p[pp.nummenus++] = n;
951  // move all earlier menus to line up with this new one:
952  if (n->selected>=0) {
953  int dy = n->y()-nY;
954  int dx = n->x()-nX;
955  int waX, waY, waW, waH;
956  Fl::screen_work_area(waX, waY, waW, waH, X, Y);
957  for (int menu = 0; menu <= pp.menu_number; menu++) {
958  menuwindow* tt = pp.p[menu];
959  int nx = tt->x()+dx; if (nx < waX) {nx = waX; dx = -tt->x() + waX;}
960  int ny = tt->y()+dy; if (ny < waY) {ny = waY; dy = -tt->y() + waY;}
961  tt->position(nx, ny);
962  }
963  setitem(pp.nummenus-1, n->selected);
964  goto STARTUP;
965  }
966  } else if (pp.nummenus > pp.menu_number+1 &&
967  pp.p[pp.menu_number+1]->menu == menutable) {
968  // the menu is already up:
969  while (pp.nummenus > pp.menu_number+2) delete pp.p[--pp.nummenus];
970  pp.p[pp.nummenus-1]->set_selected(-1);
971  } else {
972  // delete all the old menus and create new one:
973  while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus];
974  pp.p[pp.nummenus++]= new menuwindow(menutable, nX, nY,
975  title?1:0, 0, 0, title, 0, menubar,
976  (title ? 0 : cw.x()) );
977  }
978  } else { // !m->submenu():
979  while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus];
980  if (!pp.menu_number && pp.menubar) {
981  // kludge so "menubar buttons" turn "on" by using menu title:
982  pp.fakemenu = new menuwindow(0,
983  cw.x()+cw.titlex(pp.item_number),
984  cw.y()+cw.h(), 0, 0,
985  0, m, 0, 1);
986  pp.fakemenu->title->show();
987  }
988  }
989  }
990  const Fl_Menu_Item* m = (pbutton && wp.deleted()) ? NULL : pp.current_item;
991  delete pp.fakemenu;
992  while (pp.nummenus>1) delete pp.p[--pp.nummenus];
993  mw.hide();
994  Fl::grab(0);
995  return m;
996 }
997 
1021  int X, int Y,
1022  const char* title,
1023  const Fl_Menu_Item* picked,
1024  const Fl_Menu_* button
1025  ) const {
1026  static Fl_Menu_Item dummy; // static so it is all zeros
1027  dummy.text = title;
1028  return pulldown(X, Y, 0, 0, picked, button, title ? &dummy : 0);
1029 }
1030 
1043 const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip, const bool require_alt) const {
1044  const Fl_Menu_Item* m = this;
1045  if (m) for (int ii = 0; m->text; m = next_visible_or_not(m), ii++) {
1046  if (m->active()) {
1048  || Fl_Widget::test_shortcut(m->text, require_alt)) {
1049  if (ip) *ip=ii;
1050  return m;
1051  }
1052  }
1053  }
1054  return 0;
1055 }
1056 
1057 // Recursive search of all submenus for anything with this key as a
1058 // shortcut. Only uses the shortcut field, ignores &x in the labels:
1068  const Fl_Menu_Item* m = this;
1069  const Fl_Menu_Item* ret = 0;
1070  if (m) for (; m->text; m = next_visible_or_not(m)) {
1071  if (m->active()) {
1072  // return immediately any match of an item in top level menu:
1073  if (Fl::test_shortcut(m->shortcut_)) return m;
1074  // if (Fl_Widget::test_shortcut(m->text)) return m;
1075  // only return matches from lower menu if nothing found in top menu:
1076  if (!ret && m->submenu()) {
1077  const Fl_Menu_Item* s =
1078  (m->flags&FL_SUBMENU) ? m+1:(const Fl_Menu_Item*)m->user_data_;
1079  ret = s->test_shortcut();
1080  }
1081  }
1082  }
1083  return ret;
1084 }
1085 
1086 //
1087 // End of "$Id$".
1088 //
menuwindow::draw
void draw()
Definition: Fl_Menu.cxx:509
LEADING
#define LEADING
Definition: Fl_Menu.cxx:146
fl_font
void fl_font(Fl_Font face, Fl_Fontsize fsize)
Definition: fl_draw.H:509
FL_Up
#define FL_Up
The up arrow key.
Definition: Enumerations.H:481
FL_MENU_RADIO
Item is a radio button (one checkbox of many can be on)
Definition: Fl_Menu_Item.H:36
fl_width
FL_EXPORT double fl_width(const char *txt)
Definition: fl_font.cxx:65
menuwindow::menuwindow
menuwindow(const Fl_Menu_Item *m, int X, int Y, int W, int H, const Fl_Menu_Item *picked, const Fl_Menu_Item *title, int menubar=0, int menubar_title=0, int right_edge=0)
Definition: Fl_Menu.cxx:293
FL_ALIGN_LEFT
const Fl_Align FL_ALIGN_LEFT
Definition: Enumerations.H:839
Fl_Widget::y
int y() const
Definition: Fl_Widget.H:289
Fl_Window::y_root
int y_root() const
Definition: Fl_Window.cxx:159
FL_Enter
#define FL_Enter
The enter key.
Definition: Enumerations.H:471
Fl.H
Fl_Menu_Item::find_shortcut
const Fl_Menu_Item * find_shortcut(int *ip=0, const bool require_alt=false) const
Definition: Fl_Menu.cxx:1043
buf
static char * buf
Definition: fl_encoding_mac_roman.cxx:76
fl_line
void fl_line(int x, int y, int x1, int y1)
Definition: fl_draw.H:223
fl_rectf
void fl_rectf(int x, int y, int w, int h)
Definition: fl_draw.H:206
FL_NO_LABEL
does nothing
Definition: Enumerations.H:765
menuwindow::titlex
int titlex(int)
Definition: Fl_Menu.cxx:553
Fl_Menu_Item::flags
int flags
menu item flags like FL_MENU_TOGGLE, FL_MENU_RADIO
Definition: Fl_Menu_Item.H:117
INITIAL_STATE
#define INITIAL_STATE
Definition: Fl_Menu.cxx:590
FL_BackSpace
#define FL_BackSpace
The backspace key.
Definition: Enumerations.H:468
Fl_Widget::draw_box
void draw_box() const
Definition: fl_boxtype.cxx:442
menustate::item_number
int item_number
Definition: Fl_Menu.cxx:598
Fl_Window::set_menu_window
void set_menu_window()
Definition: Fl_Window.H:354
Fl_Color
unsigned int Fl_Color
Definition: Enumerations.H:934
fl_shortcut_label
const FL_EXPORT char * fl_shortcut_label(unsigned int shortcut)
Definition: fl_shortcut.cxx:199
Fl_Group::end
void end()
Definition: Fl_Group.cxx:75
Fl_Menu_Item::active
int active() const
Definition: Fl_Menu_Item.H:340
Fl_Menu_Item::value
int value() const
Definition: Fl_Menu_Item.H:318
FL_SUBMENU_POINTER
Indicates user_data() is a pointer to another menu array.
Definition: Fl_Menu_Item.H:38
menuwindow::selected
int selected
Definition: Fl_Menu.cxx:130
Fl::box_dx
static int box_dx(Fl_Boxtype)
Definition: fl_boxtype.cxx:360
menustate::state
int state
Definition: Fl_Menu.cxx:602
menuwindow::handle
int handle(int)
Definition: Fl_Menu.cxx:657
Fl_Boxtype
Fl_Boxtype
Definition: Enumerations.H:603
menuwindow::set_selected
void set_selected(int)
Definition: Fl_Menu.cxx:525
menuwindow
Definition: Fl_Menu.cxx:119
FL_WHITE
const Fl_Color FL_WHITE
Definition: Enumerations.H:971
menutitle
Definition: Fl_Menu.cxx:111
Fl_Menu_Item::test_shortcut
const Fl_Menu_Item * test_shortcut() const
Definition: Fl_Menu.cxx:1067
Fl_Menu_Window::hide
void hide()
Definition: Fl_Menu_Window.cxx:90
menustate::current_item
const Fl_Menu_Item * current_item
Definition: Fl_Menu.cxx:596
fl_color
void fl_color(Fl_Color c)
Definition: fl_draw.H:52
fl_draw_shortcut
char fl_draw_shortcut
Definition: fl_draw.cxx:36
Fl_Widget::window
Fl_Window * window() const
Definition: Fl_Window.cxx:118
FL_DRAG
Definition: Enumerations.H:268
Fl::event_is_click
static int event_is_click()
Definition: Fl.H:661
FL_ROUND_DOWN_BOX
#define FL_ROUND_DOWN_BOX
Definition: Enumerations.H:665
Fl_Label::type
uchar type
Definition: Fl_Widget.H:81
free
void free()
H
static int H
Definition: Fl_Tooltip.cxx:76
FL_SUBMENU
This item is a submenu to other items.
Definition: Fl_Menu_Item.H:39
FL_KP_Enter
#define FL_KP_Enter
The enter key on the keypad, same as Fl_KP+'\r'.
Definition: Enumerations.H:493
Fl_Menu_Item::labelfont_
Fl_Font labelfont_
which font for this menu item text
Definition: Fl_Menu_Item.H:119
setitem
static void setitem(const Fl_Menu_Item *i, int m, int n)
Definition: Fl_Menu.cxx:618
Fl_Menu_Window::erase
void erase()
Definition: Fl_Menu_Window.cxx:79
Fl_Widget::x
int x() const
Definition: Fl_Widget.H:284
NULL
#define NULL
Definition: forms.H:34
fl_draw
FL_EXPORT void fl_draw(const char *str, int x, int y)
Definition: fl_font.cxx:70
Fl_Label::draw
void draw(int, int, int, int, Fl_Align) const
Definition: fl_labeltype.cxx:77
Fl_Label::color
Fl_Color color
Definition: Fl_Widget.H:77
fl_contrast
Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg)
Definition: fl_color.cxx:435
Fl::event_key
static int event_key()
Definition: Fl.H:723
Fl_Label::image
Fl_Image * image
Definition: Fl_Widget.H:69
Fl_Menu_Item::labeltype_
uchar labeltype_
how the menu item text looks like
Definition: Fl_Menu_Item.H:118
backward
static int backward(int menu)
Definition: Fl_Menu.cxx:645
Fl_Menu_Item::size
int size() const
Definition: Fl_Menu.cxx:58
dummy
int dummy
Definition: fl_call_main.c:128
b
long b
Definition: jpegint.h:397
menustate::fakemenu
menuwindow * fakemenu
Definition: Fl_Menu.cxx:603
menustate::menubar
int menubar
Definition: Fl_Menu.cxx:601
Fl_Widget_Tracker::deleted
int deleted()
Definition: Fl.H:1396
FL_MENU_TOGGLE
Item is a checkbox toggle (shows checkbox for on/off state)
Definition: Fl_Menu_Item.H:34
menustate::menu_number
int menu_number
Definition: Fl_Menu.cxx:597
Fl::event_x
static int event_x()
Definition: Fl.H:598
Fl_Menu_Item::pulldown
const Fl_Menu_Item * pulldown(int X, int Y, int W, int H, const Fl_Menu_Item *picked=0, const Fl_Menu_ *=0, const Fl_Menu_Item *title=0, int menubar=0) const
Definition: Fl_Menu.cxx:836
Fl::box_dh
static int box_dh(Fl_Boxtype)
Definition: fl_boxtype.cxx:397
menuwindow::drawentry
void drawentry(const Fl_Menu_Item *, int i, int erase)
Definition: Fl_Menu.cxx:454
FL_Down
#define FL_Down
The down arrow key.
Definition: Enumerations.H:483
Fl_Widget::w
int w() const
Definition: Fl_Widget.H:294
Fl_Label::deimage
Fl_Image * deimage
Definition: Fl_Widget.H:71
FL_FOREGROUND_COLOR
const Fl_Color FL_FOREGROUND_COLOR
the default foreground color (0) used for labels and text
Definition: Enumerations.H:937
Fl_Menu_Item::submenu
int submenu() const
Definition: Fl_Menu_Item.H:298
Fl::box_dw
static int box_dw(Fl_Boxtype)
Definition: fl_boxtype.cxx:391
menuwindow::shortcutWidth
int shortcutWidth
Definition: Fl_Menu.cxx:132
Fl_Menu_Item::first
const Fl_Menu_Item * first() const
Definition: Fl_Menu_Item.H:135
Fl_Widget::color
Fl_Color color() const
Definition: Fl_Widget.H:378
Fl::test_shortcut
static int test_shortcut(Fl_Shortcut)
Definition: fl_shortcut.cxx:54
menustate
Definition: Fl_Menu.cxx:595
p
static menustate * p
Definition: Fl_Menu.cxx:606
FL_Left
#define FL_Left
The left arrow key.
Definition: Enumerations.H:480
Fl_Widget::position
void position(int X, int Y)
Definition: Fl_Widget.H:332
Fl_Widget::w
void w(int v)
Definition: Fl_Widget.H:143
FL_Right
#define FL_Right
The right arrow key.
Definition: Enumerations.H:482
Fl::box_dy
static int box_dy(Fl_Boxtype)
Definition: fl_boxtype.cxx:385
Fl_Menu_::textfont
Fl_Font textfont() const
Definition: Fl_Menu_.H:155
menuwindow::itemheight
int itemheight
Definition: Fl_Menu.cxx:128
Fl_Widget::selection_color
Fl_Color selection_color() const
Definition: Fl_Widget.H:396
Fl_Widget::x
void x(int v)
Definition: Fl_Widget.H:139
FL_COLOR_CUBE
#define FL_COLOR_CUBE
Definition: Enumerations.H:979
FL_FLAT_BOX
a flat box
Definition: Enumerations.H:606
FL_Tab
#define FL_Tab
The tab key.
Definition: Enumerations.H:469
FL_MOVE
Definition: Enumerations.H:335
fl_xyline
void fl_xyline(int x, int y, int x1)
Definition: fl_draw.H:255
DONE_STATE
#define DONE_STATE
Definition: Fl_Menu.cxx:592
FL_UP_BOX
see figure 1
Definition: Enumerations.H:607
menuwindow::menu
const Fl_Menu_Item * menu
Definition: Fl_Menu.cxx:133
fl_draw.H
utility header to pull drawing functions together
FL_HELVETICA
const Fl_Font FL_HELVETICA
Helvetica (or Arial) normal (0)
Definition: Enumerations.H:879
FL_DOWN_BOX
see figure 1
Definition: Enumerations.H:608
Fl_Label
Definition: Fl_Widget.H:65
Fl::event_y_root
static int event_y_root()
Definition: Fl.H:617
fl_inactive
Fl_Color fl_inactive(Fl_Color c)
Definition: fl_color.cxx:423
Fl_Window::set_modal
void set_modal()
Definition: Fl_Window.H:289
Fl_Menu_Item::draw
void draw(int x, int y, int w, int h, const Fl_Menu_ *, int t=0) const
Definition: Fl_Menu.cxx:172
Fl_Label::size
Fl_Fontsize size
Definition: Fl_Widget.H:75
Fl_Window
Definition: Fl_Window.H:57
menustate::is_inside
int is_inside(int mx, int my)
Definition: Fl_Menu.cxx:609
menutitle::menutitle
menutitle(int X, int Y, int W, int H, const Fl_Menu_Item *)
Definition: Fl_Menu.cxx:283
menustate::p
menuwindow * p[20]
Definition: Fl_Menu.cxx:599
fl_arc
void fl_arc(int x, int y, int w, int h, double a1, double a2)
Definition: fl_draw.H:304
Fl_Menu_Item::user_data_
void * user_data_
menu item user_data for the menu's callback
Definition: Fl_Menu_Item.H:116
Fl_Menu_::down_box
Fl_Boxtype down_box() const
Definition: Fl_Menu_.H:173
Fl_Menu_Window::show
void show()
Definition: Fl_Menu_Window.cxx:44
Fl_Menu_Item::callback_
Fl_Callback * callback_
menu item callback
Definition: Fl_Menu_Item.H:115
Fl_Menu_::textcolor
Fl_Color textcolor() const
Definition: Fl_Menu_.H:163
FL_PUSH
Definition: Enumerations.H:236
Fl_Widget::damage
uchar damage() const
Definition: Fl_Widget.H:917
Fl_Widget::test_shortcut
int test_shortcut()
Definition: fl_shortcut.cxx:494
fl_push_clip
void fl_push_clip(int x, int y, int w, int h)
Definition: fl_draw.H:82
fl_pie
void fl_pie(int x, int y, int w, int h, double a1, double a2)
Definition: fl_draw.H:317
Fl_Menu_::textsize
Fl_Fontsize textsize() const
Definition: Fl_Menu_.H:159
Fl_Menu_.H
Fl::screen_work_area
static void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my)
Definition: screen_xywh.cxx:290
Fl_Widget::redraw
void redraw()
Definition: Fl.cxx:1782
FL_NORMAL_SIZE
Fl_Fontsize FL_NORMAL_SIZE
normal font size
Definition: Fl_Widget.cxx:117
Fl_Widget
Definition: Fl_Widget.H:101
Fl_Group::current
static Fl_Group * current()
Definition: Fl_Group.cxx:84
Fl_Menu_
Definition: Fl_Menu_.H:51
FL_LIGHT3
const Fl_Color FL_LIGHT3
Definition: Enumerations.H:952
FL_NO_BOX
nothing is drawn at all, this box is invisible
Definition: Enumerations.H:605
menuwindow::find_selected
int find_selected(int mx, int my)
Definition: Fl_Menu.cxx:531
Fl_Widget::box
Fl_Boxtype box() const
Definition: Fl_Widget.H:363
Fl_Widget::h
int h() const
Definition: Fl_Widget.H:299
Fl_Window::shown
int shown()
Definition: Fl_Window.H:485
menustate::nummenus
int nummenus
Definition: Fl_Menu.cxx:600
Fl::event_y
static int event_y()
Definition: Fl.H:603
Fl_Widget_Tracker
Definition: Fl.H:1371
FL_KEYBOARD
Definition: Enumerations.H:315
PUSH_STATE
#define PUSH_STATE
Definition: Fl_Menu.cxx:591
fl_draw_box
FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color)
Definition: fl_boxtype.cxx:436
Fl::event_x_root
static int event_x_root()
Definition: Fl.H:610
Fl_Widget::h
void h(int v)
Definition: Fl_Widget.H:145
menuwindow::is_inside
int is_inside(int x, int y)
Definition: Fl_Menu.cxx:561
FL_SELECTION_COLOR
const Fl_Color FL_SELECTION_COLOR
the default selection/highlight color
Definition: Enumerations.H:940
Fl_Label::measure
void measure(int &w, int &h) const
Definition: fl_labeltype.cxx:86
color
void color(int n)
Definition: gl2opengl.h:29
Fl_Widget::y
void y(int v)
Definition: Fl_Widget.H:141
Fl_Menu_Item::visible
int visible() const
Definition: Fl_Menu_Item.H:331
Fl_Menu_Window::clear_overlay
void clear_overlay()
Definition: Fl_Menu_Window.H:45
FL_MENU_DIVIDER
Creates divider line below this item. Also ends a group of radio buttons.
Definition: Fl_Menu_Item.H:40
Fl_Window::handle
virtual int handle(int)
Definition: Fl.cxx:1684
fl_utf_nb_char
int fl_utf_nb_char(const unsigned char *buf, int len)
Definition: fl_utf8.cxx:167
Fl_Menu_Item::shortcut_
int shortcut_
menu item shortcut
Definition: Fl_Menu_Item.H:114
fl_pop_clip
void fl_pop_clip()
Definition: fl_draw.H:103
menuwindow::autoscroll
void autoscroll(int)
Definition: Fl_Menu.cxx:436
x
int x
Definition: test.c:73
Fl_Font
int Fl_Font
Definition: Enumerations.H:877
Fl::wait
static int wait()
Definition: Fl.cxx:666
Fl_Menu_Item::popup
const Fl_Menu_Item * popup(int X, int Y, const char *title=0, const Fl_Menu_Item *picked=0, const Fl_Menu_ *=0) const
Definition: Fl_Menu.cxx:1020
FL_BACKGROUND2_COLOR
const Fl_Color FL_BACKGROUND2_COLOR
the default background color for text, list, and valuator widgets
Definition: Enumerations.H:938
Fl_Menu_Item::measure
int measure(int *h, const Fl_Menu_ *) const
Definition: Fl_Menu.cxx:154
FL_SHORTCUT
Definition: Enumerations.H:349
Fl_Label::value
const char * value
Definition: Fl_Widget.H:67
dy
uchar dy
Definition: fl_boxtype.cxx:286
Fl_Menu_Item
Definition: Fl_Menu_Item.H:112
y
int y
Definition: test.c:74
button
static const Fl_Menu_ * button
Definition: Fl_Menu.cxx:106
Fl_Label::font
Fl_Font font
Definition: Fl_Widget.H:73
Fl_Menu_Item::labelcolor_
Fl_Color labelcolor_
menu item text color
Definition: Fl_Menu_Item.H:121
FL_GRAY
#define FL_GRAY
Definition: Enumerations.H:978
menutitle::draw
void draw()
Definition: Fl_Menu.cxx:505
menuwindow::~menuwindow
~menuwindow()
Definition: Fl_Menu.cxx:424
f
Fl_Box_Draw_F * f
Definition: fl_boxtype.cxx:285
menuwindow::drawn_selected
int drawn_selected
Definition: Fl_Menu.cxx:131
malloc
voidp malloc()
Fl_Menu_Item::activevisible
int activevisible() const
Definition: Fl_Menu_Item.H:350
Fl::is_scheme
static int is_scheme(const char *name)
Definition: Fl.H:368
Y
static int Y
Definition: Fl_Tooltip.cxx:76
Fl::event_shift
static int event_shift()
Definition: Fl.H:1139
Fl_Menu_Item::text
const char * text
menu item text, returned by label()
Definition: Fl_Menu_Item.H:113
flstring.h
Fl_Window::i
Fl_X * i
Definition: Fl_Window.H:97
title
static const char * title
Definition: Fl_arg.cxx:55
Fl::scheme
static const char * scheme()
Definition: Fl.H:339
menutitle::menu
const Fl_Menu_Item * menu
Definition: Fl_Menu.cxx:114
FL_ALIGN_RIGHT
const Fl_Align FL_ALIGN_RIGHT
Definition: Enumerations.H:841
Fl_Window::x_root
int x_root() const
Definition: Fl_Window.cxx:153
Fl_Menu_Item::labelsize_
Fl_Fontsize labelsize_
size of menu item text
Definition: Fl_Menu_Item.H:120
menuwindow::title
menutitle * title
Definition: Fl_Menu.cxx:123
FL_RELEASE
Definition: Enumerations.H:244
fl_color_average
Fl_Color fl_color_average(Fl_Color c1, Fl_Color c2, float weight)
Definition: fl_color.cxx:402
Fl_Menu_Window
Definition: Fl_Menu_Window.H:33
next_visible_or_not
static const Fl_Menu_Item * next_visible_or_not(const Fl_Menu_Item *m)
Definition: Fl_Menu.cxx:74
Fl::grab
static Fl_Window * grab()
Definition: Fl.H:555
FL_DAMAGE_CHILD
Definition: Enumerations.H:1106
FL_ENTER
Definition: Enumerations.H:253
dx
uchar dx
Definition: fl_boxtype.cxx:286
FL_Escape
#define FL_Escape
The escape key.
Definition: Enumerations.H:474
menuwindow::position
void position(int x, int y)
Definition: Fl_Menu.cxx:429
BW
#define BW
Definition: fl_rounded_box.cxx:30
Fl_Menu_Window.H
fl_polygon
void fl_polygon(int x, int y, int x1, int y1, int x2, int y2)
Definition: fl_draw.H:244
Fl_Menu_Item::next
const Fl_Menu_Item * next(int=1) const
Definition: Fl_Menu.cxx:94
Fl_Window::clear_border
void clear_border()
Definition: Fl_Window.H:274
menuwindow::numitems
int numitems
Definition: Fl_Menu.cxx:129
MENU_PUSH_STATE
#define MENU_PUSH_STATE
Definition: Fl_Menu.cxx:593
forward
static int forward(int menu)
Definition: Fl_Menu.cxx:631
FL_DARK3
const Fl_Color FL_DARK3
Definition: Enumerations.H:946