]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/DropDown.C
John's completion stuff
[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 "DropDown.h"
10
11 #include <iostream>
12  
13 extern "C" void C_DropDownCompletedCB(FL_OBJECT * ob, long)
14 {
15         DropDown * d = static_cast<DropDown*>(ob->form->u_vdata);
16         d->completed();
17 }
18
19  
20 extern "C" int C_DropDownPeekEventCB(FL_FORM * form, void *xev)
21 {
22         DropDown * d = static_cast<DropDown*>(form->u_vdata);
23         return d->peek(static_cast<XEvent*>(xev));
24 }
25  
26  
27 DropDown::DropDown(LyXView * lv, FL_OBJECT * ob)
28         : lv_(lv)
29 {
30         form_ = fl_bgn_form(FL_NO_BOX, ob->w, 100);
31         fl_add_box(FL_UP_BOX, 0, 0, ob->w, 100, "");
32         browser_ = fl_add_browser(FL_SELECT_BROWSER, 0, 0, ob->w, 100, "");
33         form_->u_vdata = this;
34         fl_set_browser_dblclick_callback(browser_, C_DropDownCompletedCB, 0);
35         fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_DropDownPeekEventCB);
36         fl_end_form();
37 }
38
39  
40 DropDown::~DropDown()
41 {
42         if (form_->visible) 
43                 fl_hide_form(form_);
44         fl_free_form(form_);
45 }
46  
47
48 void DropDown::select(std::vector<string> const & choices, int x, int y, int w)
49 {
50         fl_set_form_geometry(form_, x, y, w, 100);
51         fl_clear_browser(browser_);
52         for (std::vector<string>::const_iterator cit = choices.begin();
53                 cit != choices.end(); ++cit) {
54                 fl_add_browser_line(browser_, cit->c_str());
55         }
56         fl_show_form(form_, FL_PLACE_POSITION, FL_NOBORDER, "");
57         XGrabPointer(fl_get_display(), form_->window, false,
58                      ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
59                      GrabModeAsync, GrabModeAsync, 0, 0, 0);
60         XFlush(fl_get_display());
61 }
62
63
64 void DropDown::line_up()
65 {
66         if (fl_get_browser(browser_) > 1)
67                 fl_select_browser_line(browser_, fl_get_browser(browser_) - 1);
68         if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
69                 fl_get_browser_screenlines(browser_))
70                         fl_set_browser_topline(browser_, fl_get_browser(browser_)
71                                 - fl_get_browser_screenlines(browser_) + 1);
72         if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
73                 fl_set_browser_topline(browser_, fl_get_browser(browser_));
74 }
75
76
77 void DropDown::line_down()
78 {
79         if (fl_get_browser(browser_) < fl_get_browser_maxline(browser_))
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 int DropDown::peek(XEvent * xev)
91 {
92         int x,y;
93         unsigned int keymask;
94
95         fl_get_mouse(&x, &y, &keymask);
96  
97         if (xev->type == ButtonPress) {
98                 if (!(x >= form_->x && x <= (form_->x + form_->w) &&
99                         y >= form_->y && y << (form_->y + form_->h))) {
100                         fl_hide_form(form_);
101                         return 1;
102                 }
103         } else if (xev->type == KeyPress) {
104                 char s_r[10]; s_r[9] = '\0';
105                 KeySym keysym_return;
106                 XLookupString(&xev->xkey, s_r, 10, &keysym_return, 0);
107                 switch (keysym_return) {
108                         case XK_Down:
109                                 line_down();
110                                 return 1;
111                         case XK_Up:
112                                 line_up();
113                                 return 1;
114                         case XK_Return:
115                                 completed(); 
116                                 return 1;
117                 }
118         }
119         return 0; 
120 }
121
122  
123 void DropDown::completed()
124 {
125         string selection;
126         int i = fl_get_browser(browser_);
127         if (i == -1)
128                 selection = "";
129         else
130                 selection = fl_get_browser_line(browser_, i); 
131         fl_hide_form(form_);
132
133         result.emit(selection);
134 }