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