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