]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/DropDown.C
Really dull and boring header shit
[lyx.git] / src / frontends / xforms / DropDown.C
1 /**
2  * \file DropDown.C
3  * Read the file COPYING
4  *
5  * \author John Levon
6  *
7  * Full author contact details are available in file CREDITS
8  */
9
10 #include <config.h>
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 #include "DropDown.h"
17 #include "xforms_helpers.h"
18
19 #include FORMS_H_LOCATION
20
21 #include <iostream>
22 #include <cctype>
23
24 #ifndef CXX_GLOBAL_CSTD
25 using std::isprint;
26 #endif
27
28 using std::vector;
29
30
31 namespace {
32
33 extern "C" void C_CompletedCB(FL_OBJECT * ob, long)
34 {
35         DropDown * d = static_cast<DropDown*>(ob->u_vdata);
36         d->completed();
37 }
38
39
40 extern "C" int C_PeekCB(FL_FORM * form, void *xev)
41 {
42         DropDown * d = static_cast<DropDown*>(form->u_vdata);
43         return d->peek(static_cast<XEvent*>(xev));
44 }
45
46 } // namespace anon
47
48
49 DropDown::DropDown(FL_OBJECT * ob)
50 {
51         form_ = fl_bgn_form(FL_NO_BOX, ob->w, 100);
52         fl_add_box(FL_UP_BOX, 0, 0, ob->w, 100, "");
53         browser_ = fl_add_browser(FL_SELECT_BROWSER, 0, 0, ob->w, 100, "");
54         form_->u_vdata = this;
55         browser_->u_vdata = this;
56         fl_set_object_callback(browser_, C_CompletedCB, 0);
57         fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_PeekCB);
58         fl_end_form();
59 }
60
61
62 DropDown::~DropDown()
63 {
64         if (form_->visible)
65                 fl_hide_form(form_);
66         fl_free_form(form_);
67 }
68
69
70 void DropDown::select(vector<string> const & choices, int x, int y, int w)
71 {
72         if (choices.empty())
73                 return;
74
75         fl_set_form_geometry(form_, x, y - 100, w, 100);
76         fl_clear_browser(browser_);
77
78         vector<string>::const_iterator cit = choices.begin();
79         vector<string>::const_iterator end = choices.end();
80         for (; cit != end; ++cit) {
81                 fl_add_browser_line(browser_, cit->c_str());
82         }
83         fl_select_browser_line(browser_, 1);
84         fl_show_form(form_, FL_PLACE_POSITION, FL_NOBORDER, "");
85         XGrabPointer(fl_get_display(), form_->window, false,
86                      ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
87                      GrabModeAsync, GrabModeAsync, 0, 0, 0);
88         XFlush(fl_get_display());
89 }
90
91
92 void DropDown::line_up()
93 {
94         if (fl_get_browser(browser_) > 1)
95                 fl_select_browser_line(browser_, fl_get_browser(browser_) - 1);
96         if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
97             fl_get_browser_screenlines(browser_))
98                 fl_set_browser_topline(browser_, fl_get_browser(browser_)
99                                        - fl_get_browser_screenlines(browser_) + 1);
100         if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
101                 fl_set_browser_topline(browser_, fl_get_browser(browser_));
102 }
103
104
105 void DropDown::line_down()
106 {
107         if (fl_get_browser(browser_) < fl_get_browser_maxline(browser_))
108                 fl_select_browser_line(browser_, fl_get_browser(browser_) + 1);
109         if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
110             fl_get_browser_screenlines(browser_))
111                 fl_set_browser_topline(browser_, fl_get_browser(browser_)
112                                        - fl_get_browser_screenlines(browser_) + 1);
113         if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
114                 fl_set_browser_topline(browser_, fl_get_browser(browser_));
115 }
116
117
118 int DropDown::peek(XEvent * xev)
119 {
120         int x,y;
121         unsigned int keymask;
122
123         fl_get_mouse(&x, &y, &keymask);
124
125         if (xev->type == ButtonPress) {
126                 if (!(x >= form_->x && x <= (form_->x + form_->w) &&
127                       y >= form_->y && y << (form_->y + form_->h))) {
128                         fl_hide_form(form_);
129                         return 1;
130                 }
131                 XUngrabPointer(fl_get_display(), CurrentTime);
132         } else if (xev->type == KeyPress) {
133                 char s_r[10]; s_r[9] = '\0';
134                 KeySym keysym_return;
135                 XLookupString(&xev->xkey, s_r, 10, &keysym_return, 0);
136                 switch (keysym_return) {
137                 case XK_Down:
138 #ifdef XK_KP_Down
139                 case XK_KP_Down:
140 #endif
141                         line_down();
142                         return 1;
143                 case XK_Up:
144 #ifdef XK_KP_Up
145                 case XK_KP_Up:
146 #endif
147                         line_up();
148                         return 1;
149                 case XK_Return:
150 #ifdef XK_KP_Enter
151                 case XK_KP_Enter:
152 #endif
153                         completed();
154                         return 1;
155                 case XK_Escape:
156                         fl_deselect_browser(browser_);
157                         completed();
158                         return 1;
159                 default:
160                         // FIXME: if someone has a got a way to
161                         // convince the event to fall back to the
162                         // minibuffer, I'm glad to hear it.
163                         // fl_XPutBackEvent() doesn't work.
164
165                         // This is a bit less elegant perhaps, but works
166                         // well enough. Angus 11 Jan 2002
167                         if (s_r[0] && isprint(s_r[0])) {
168                                 key_pressed(s_r[0]);
169                                 return 1;
170                         }
171                 }
172         }
173         return 0;
174 }
175
176
177 void DropDown::completed()
178 {
179         XUngrabPointer(fl_get_display(), CurrentTime);
180         fl_hide_form(form_);
181         result(getString(browser_));
182 }
183
184
185 void DropDown::key_pressed(char c)
186 {
187         XUngrabPointer(fl_get_display(), CurrentTime);
188         fl_hide_form(form_);
189         keypress(c);
190 }