]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/DropDown.C
removed most uses of toupper and friends, removed <config.h> from headers and added...
[lyx.git] / src / frontends / xforms / DropDown.C
1 /**
2  * \file DropDown.C
3  * Copyright 2001 the LyX Team
4  * Read the file COPYING
5  *
6  * \author John Levon <moz@compsoc.man.ac.uk>
7  */
8
9 #include <config.h>
10
11 #include "DropDown.h"
12
13 #include <iostream>
14  
15 extern "C" void C_DropDownCompletedCB(FL_OBJECT * ob, long)
16 {
17         DropDown * d = static_cast<DropDown*>(ob->form->u_vdata);
18         d->completed();
19 }
20
21  
22 extern "C" int C_DropDownPeekEventCB(FL_FORM * form, void *xev)
23 {
24         DropDown * d = static_cast<DropDown*>(form->u_vdata);
25         return d->peek(static_cast<XEvent*>(xev));
26 }
27  
28  
29 DropDown::DropDown(LyXView * lv, FL_OBJECT * ob)
30         : lv_(lv)
31 {
32         form_ = fl_bgn_form(FL_NO_BOX, ob->w, 100);
33         fl_add_box(FL_UP_BOX, 0, 0, ob->w, 100, "");
34         browser_ = fl_add_browser(FL_SELECT_BROWSER, 0, 0, ob->w, 100, "");
35         form_->u_vdata = this;
36         fl_set_browser_dblclick_callback(browser_, C_DropDownCompletedCB, 0);
37         fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_DropDownPeekEventCB);
38         fl_end_form();
39 }
40
41  
42 DropDown::~DropDown()
43 {
44         if (form_->visible) 
45                 fl_hide_form(form_);
46         fl_free_form(form_);
47 }
48  
49
50 void DropDown::select(std::vector<string> const & choices, int x, int y, int w)
51 {
52         fl_set_form_geometry(form_, x, y, w, 100);
53         fl_clear_browser(browser_);
54         for (std::vector<string>::const_iterator cit = choices.begin();
55                 cit != choices.end(); ++cit) {
56                 fl_add_browser_line(browser_, cit->c_str());
57         }
58         fl_show_form(form_, FL_PLACE_POSITION, FL_NOBORDER, "");
59         XGrabPointer(fl_get_display(), form_->window, false,
60                      ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
61                      GrabModeAsync, GrabModeAsync, 0, 0, 0);
62         XFlush(fl_get_display());
63 }
64
65
66 void DropDown::line_up()
67 {
68         if (fl_get_browser(browser_) > 1)
69                 fl_select_browser_line(browser_, fl_get_browser(browser_) - 1);
70         if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
71                 fl_get_browser_screenlines(browser_))
72                         fl_set_browser_topline(browser_, fl_get_browser(browser_)
73                                 - fl_get_browser_screenlines(browser_) + 1);
74         if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
75                 fl_set_browser_topline(browser_, fl_get_browser(browser_));
76 }
77
78
79 void DropDown::line_down()
80 {
81         if (fl_get_browser(browser_) < fl_get_browser_maxline(browser_))
82                 fl_select_browser_line(browser_, fl_get_browser(browser_) + 1);
83         if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
84                 fl_get_browser_screenlines(browser_))
85                         fl_set_browser_topline(browser_, fl_get_browser(browser_)
86                                 - fl_get_browser_screenlines(browser_) + 1);
87         if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
88                 fl_set_browser_topline(browser_, fl_get_browser(browser_));
89 }
90  
91
92 int DropDown::peek(XEvent * xev)
93 {
94         int x,y;
95         unsigned int keymask;
96
97         fl_get_mouse(&x, &y, &keymask);
98  
99         if (xev->type == ButtonPress) {
100                 if (!(x >= form_->x && x <= (form_->x + form_->w) &&
101                         y >= form_->y && y << (form_->y + form_->h))) {
102                         fl_hide_form(form_);
103                         return 1;
104                 }
105                 XUngrabPointer(fl_get_display(), CurrentTime);
106         } else if (xev->type == KeyPress) {
107                 char s_r[10]; s_r[9] = '\0';
108                 KeySym keysym_return;
109                 XLookupString(&xev->xkey, s_r, 10, &keysym_return, 0);
110                 switch (keysym_return) {
111                         case XK_Down:
112                                 line_down();
113                                 return 1;
114                         case XK_Up:
115                                 line_up();
116                                 return 1;
117                         case XK_Return:
118                                 completed(); 
119                                 return 1;
120                         case XK_Escape:
121                                 fl_select_browser_line(browser_, 0);
122                                 completed();
123                                 return 1;
124                         default:
125                                 // FIXME: if someone has a got a way to
126                                 // convince the event to fall back to the
127                                 // minibuffer, I'm glad to hear it.
128                                 // fl_XPutBackEvent() doesn't work. 
129                                 fl_select_browser_line(browser_, 0);
130                                 completed();
131                                 return 1;
132                 }
133         }
134         return 0; 
135 }
136
137  
138 void DropDown::completed()
139 {
140         XUngrabPointer(fl_get_display(), CurrentTime);
141         string selection;
142         int i = fl_get_browser(browser_);
143         if (i < 1)
144                 selection = "";
145         else
146                 selection = fl_get_browser_line(browser_, i); 
147         fl_hide_form(form_);
148
149         result.emit(selection);
150 }