]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/freebrowser.c
remove defaults stuff, let Qt handle no toolbar
[lyx.git] / src / frontends / xforms / freebrowser.c
1 /**
2  * \file freebrowser.c
3  *
4  * \author Alejandro Aguilar Sierra
5  * \author Angus Leeming
6  *
7  * This is a rewrite of Alejandro's C++ Combox class, originally written
8  * for LyX in 1996. The rewrite turns it into a native xforms widget.
9  */
10 #include <config.h>
11
12 #include FORMS_H_LOCATION
13 #include "freebrowser.h"
14 #include <ctype.h> /* isprint */
15
16 extern void fl_hide_tooltip(void);
17
18 static void browser_cb(FL_OBJECT * ob, long data);
19
20 static int peek_event(FL_FORM * form, void * xev);
21
22
23 FL_FREEBROWSER * fl_create_freebrowser(void * parent)
24 {
25     FL_FORM * current_form = fl_current_form;
26     FL_FREEBROWSER * fb = fl_calloc(1, sizeof(FL_FREEBROWSER));
27     FL_OBJECT * ob;
28
29     /* Default size */
30     FL_Coord const w = 100;
31     FL_Coord const h = 100;
32
33     fb->parent = parent;
34     fb->callback = 0;
35     fb->want_printable = 0;
36     fb->last_printable = 0;
37
38     if (current_form) fl_end_form();
39     fb->form = fl_bgn_form(FL_NO_BOX, w, h);
40
41     fb->form->u_vdata = fb;
42     fl_register_raw_callback(fb->form, ButtonPressMask|KeyPressMask,
43                              peek_event);
44
45     ob = fb->browser = fl_add_browser(FL_HOLD_BROWSER, 0, 0, w, h, "");
46     ob->u_vdata = fb;
47     fl_set_object_boxtype(ob, FL_UP_BOX);
48     fl_set_object_color(ob, FL_MCOL, FL_YELLOW);
49     fl_set_object_gravity(ob, NorthWestGravity, SouthEastGravity);
50     fl_set_object_callback(ob, browser_cb, 0);
51     fl_end_form();
52
53     if (current_form)
54         fl_addto_form(current_form);
55
56     return fb;
57 }
58
59
60 void fl_free_freebrowser(FL_FREEBROWSER * fb)
61 {
62     if (!fb)
63         return;
64
65     if (fb->form)
66         fl_free_form(fb->form);
67
68     fl_free(fb);
69     fb = 0;
70 }
71
72
73 void fl_show_freebrowser(FL_FREEBROWSER * fb,
74                          FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h)
75 {
76     int tmp;
77     int const pos = fl_get_browser(fb->browser);
78
79     fl_set_form_geometry(fb->form, x, y, w, h);
80
81     XGetInputFocus(fl_get_display(), &fb->save_window, &tmp);
82     XFlush(fl_get_display());
83
84     fl_show_form(fb->form, FL_PLACE_POSITION, FL_NOBORDER, "");
85
86     fl_select_browser_line(fb->browser, pos);
87     fl_set_browser_topline(fb->browser, pos);
88
89     XGrabPointer(fl_get_display(), fb->form->window, 0,
90                  ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
91                  GrabModeAsync, GrabModeAsync,
92                  0, 0, 0);
93     XFlush(fl_get_display());
94
95     fl_hide_tooltip();
96 }
97
98
99 void fl_hide_freebrowser(FL_FREEBROWSER * fb)
100 {
101     XUngrabPointer(fl_get_display(), 0);
102     XFlush(fl_get_display());
103
104     if (fb->form->visible)
105         fl_hide_form(fb->form);
106
107     XSetInputFocus(fl_get_display(), fb->save_window,
108                    RevertToParent, CurrentTime);
109     XFlush(fl_get_display());
110
111     if (fb->callback)
112         fb->callback(fb, 0);
113 }
114
115
116 FL_OBJECT * fl_get_freebrowser_browser(FL_FREEBROWSER * fb)
117 {
118     return fb->browser;
119 }
120
121
122 static void browser_cb(FL_OBJECT * ob, long data)
123 {
124     FL_FREEBROWSER * fb = ob->u_vdata;
125     fl_hide_freebrowser(fb);
126     if (fb->callback)
127         fb->callback(fb, 1);
128 }
129
130
131 static int peek_event(FL_FORM * form, void * ev)
132 {
133     XEvent * xev = ev;
134     FL_FREEBROWSER * fb = form->u_vdata;
135     FL_OBJECT * browser = fb->browser;
136
137     fb->last_printable = 0;
138     fl_hide_tooltip();
139
140     if (xev->type == ButtonPress &&
141         ((int)(xev->xbutton.x) - (int)(browser->x) < 0 ||
142          (int)(xev->xbutton.x) - (int)(browser->x) > (int)(browser->w) ||
143          (int)(xev->xbutton.y) - (int)(browser->y) < 0 ||
144          (int)(xev->xbutton.y) - (int)(browser->y) > (int)(browser->h))) {
145         fl_hide_freebrowser(fb);
146         return 1;
147     }
148
149     if (xev->type == KeyPress) {
150         char s_r[10]; s_r[9] = '\0';
151         KeySym keysym_return;
152         XLookupString(&xev->xkey, s_r, 10, &keysym_return, 0);
153
154         XFlush(fl_get_display());
155
156         switch (keysym_return) {
157         case XK_Down:
158 #ifdef XK_KP_Down
159         case XK_KP_Down:
160 #endif
161         {
162             int sel = fl_get_browser(browser);
163             int const top = fl_get_browser_topline(browser);
164             int const screenlines = fl_get_browser_screenlines(browser);
165
166             if (sel < 1 || sel >= fl_get_browser_maxline(browser))
167                 return 0;
168
169             ++sel;
170             fl_select_browser_line(browser, sel);
171
172             if (sel >= top + screenlines)
173                 fl_set_browser_topline(browser, sel - screenlines + 1);
174
175             if (sel < top)
176                 fl_set_browser_topline(browser, sel);
177
178             return 1;
179         }
180
181         case XK_Up:
182 #ifdef XK_KP_Up
183         case XK_KP_Up:
184 #endif
185         {
186             int sel = fl_get_browser(browser);
187             int const top = fl_get_browser_topline(browser);
188             int const screenlines = fl_get_browser_screenlines(browser);
189
190             if (sel <= 1 || sel > fl_get_browser_maxline(browser))
191                 return 0;
192
193             --sel;
194             fl_select_browser_line(browser, sel);
195
196             if (sel >= top + screenlines)
197                 fl_set_browser_topline(browser, sel - screenlines + 1);
198
199             if (sel < top)
200                 fl_set_browser_topline(browser, sel);
201
202             return 1;
203         }
204
205         case XK_Return:
206 #ifdef XK_KP_Enter
207         case XK_KP_Enter:
208 #endif
209             fl_hide_freebrowser(fb);
210             if (fb->callback)
211                 fb->callback(fb, 1);
212             return 1;
213
214         case XK_Escape:
215             fl_hide_freebrowser(fb);
216             return 1;
217         default:
218             if (fb->want_printable && s_r[0] && isprint(s_r[0])) {
219                 fb->last_printable = s_r[0];
220                 fl_hide_freebrowser(fb);
221                 if (fb->callback)
222                     fb->callback(fb, 1);
223                 return 1;
224             }
225         }
226     }
227     return 0;
228 }