3 * Combox: A combination of two objects (a button and a browser) is
4 * encapsulated to get a combobox-like object. All XForms
5 * functions are hidden.
7 * GNU Copyleft (C) 1996 Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
10 * Dependencies: Only XForms, but created to be used with LyX.
16 * 2/06/1996, Alejandro Aguilar Sierra
19 * 4/06/1996, Alejandro Aguilar Sierra
20 * Added droplist mode (a button with a black down arrow at right)
21 * and support for middle and right buttons, as XForms choice object.
23 * 6/06/1996, Lars Gullik Bjønnes
24 * Added a combox with an input object. and a pre and a post handle.
26 * 22/07/96, Alejandro Aguilar Sierra
27 * Assigned to the browser its own popup window. No more need of
28 * external pre and post handlers to simulate the wanted behaviour.
35 #pragma implementation
43 // $Id: combox.C,v 1.1 1999/09/27 18:44:37 larsbj Exp $
45 #if !defined(lint) && !defined(WITH_WARNINGS)
46 static char vcid[] = "$Id: combox.C,v 1.1 1999/09/27 18:44:37 larsbj Exp $";
50 Combox::Combox(combox_type t): type(t)
71 if (browser) fl_clear_browser(browser);
73 if (type == FL_COMBOX_INPUT)
74 fl_set_input(label, "");
76 fl_set_object_label(label, "");
83 //lyxerr.print(LString("Button: ") + int(button));
85 fl_delete_object(button);
86 fl_free_object(button);
89 //lyxerr.print(LString("Label: ") + int(label));
90 if (label && label!=button) {
91 fl_delete_object(label);
92 fl_free_object(label);
95 //lyxerr.print(LString("Form: ") + int(form));
96 //lyxerr.print(LString("Browser: ") + int(browser));
97 if (form && browser) {
98 fl_delete_object(browser);
99 fl_free_object(browser);
111 void Combox::addline(char const* text)
113 if (!browser) return;
114 fl_add_browser_line(browser, text);
116 // By default the first item is selected
119 if (type == FL_COMBOX_INPUT)
120 fl_set_input(label, text);
122 fl_set_object_label(label, text);
128 bool Combox::select_text(char const* t)
130 if (!browser || !t) return false;
131 for (int i=1; i<=fl_get_browser_maxline(browser); i++) {
132 if (!strcmp(t, fl_get_browser_line(browser, i))) {
137 return false; // t does not exist in browser
141 void Combox::select(int i)
143 if (!browser || !button) return;
144 if (i>0 && i<=fl_get_browser_maxline(browser)) sel = i;
145 fl_deactivate_object(button);
147 if (type == FL_COMBOX_INPUT)
148 fl_set_input(label, fl_get_browser_line(browser, sel));
150 fl_set_object_label(label, fl_get_browser_line(browser, sel));
151 fl_activate_object(button);
155 void Combox::add(int x, int y, int w, int hmin, int hmax)
160 case FL_COMBOX_DROPLIST:
162 button = obj = fl_add_button(FL_NORMAL_BUTTON,
163 x+w-22,y,22,hmin,"@2->");
164 fl_set_object_color(obj,FL_MCOL, FL_MCOL);
165 fl_set_object_dblbuffer(obj, 1);
166 fl_set_object_callback(obj,combo_cb,0);
167 label = obj = fl_add_button(FL_NORMAL_TEXT,x,y,w-22,hmin,"");
168 fl_set_object_boxtype(obj,FL_DOWN_BOX);
169 fl_set_object_color(obj,FL_MCOL,FL_BLACK);
170 fl_set_object_lalign(obj,FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
171 fl_set_object_dblbuffer(obj, 1);
172 fl_set_object_callback(obj,combo_cb,0);
175 case FL_COMBOX_NORMAL:
177 button = obj = fl_add_button(FL_NORMAL_BUTTON,x,y,w,hmin,"");
178 fl_set_object_color(obj,FL_MCOL, FL_MCOL);
179 fl_set_object_boxtype(obj,FL_DOWN_BOX);
180 fl_set_object_callback(obj,combo_cb,0);
181 fl_set_object_color(obj,FL_MCOL,FL_BLACK);
185 case FL_COMBOX_INPUT:
187 button = obj = fl_add_button(FL_NORMAL_BUTTON,
188 x+w-22,y,22,hmin,"@2->");
189 fl_set_object_color(obj,FL_MCOL, FL_MCOL);
190 fl_set_object_callback(obj,combo_cb,0);
191 label = obj = fl_add_input(FL_NORMAL_INPUT,x,y,w-22,hmin,"");
192 fl_set_object_boxtype(obj,FL_DOWN_BOX);
193 fl_set_object_return(obj, FL_RETURN_END_CHANGED);
194 fl_set_object_callback(obj,input_cb,0);
195 //fl_set_object_color(obj,FL_MCOL,FL_BLACK);
196 //fl_set_object_lalign(obj,FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
201 label->u_vdata = (void*)this;
202 button->u_vdata = (void*)this;
204 // Hmm, it seems fl_create_browser is broken in xforms 0.86.
205 // We have to work around that by creating the dropped browser form
206 // at this point already. However, this means that we have
207 // to do a little hacking: (Asger)
208 FL_FORM * current_form = fl_current_form;
211 bw = w+20; bh = hmax-hmin-12;
213 form = fl_bgn_form(FL_NO_BOX, bw, bh);
214 browser = obj = fl_add_browser(FL_HOLD_BROWSER, 0, 0, bw,bh,"");
215 fl_set_object_boxtype(obj,FL_UP_BOX);
216 fl_set_object_color(obj,FL_MCOL, FL_YELLOW);
217 fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity);
218 fl_set_object_callback(obj,combo_cb,2);
220 browser->u_vdata = (void*)this;
221 form->u_vdata = browser;
222 fl_register_raw_callback(form, ButtonPressMask|KeyPressMask,peek_event);
224 // And revert to adding to the old form (Asger)
225 fl_addto_form(current_form);
229 static Window save_window;
232 void Combox::Redraw()
234 if (browser) fl_redraw_object(browser);
235 if (button) fl_redraw_object(button);
236 if (label) fl_redraw_object(label);
244 XGetInputFocus(fl_display, &save_window, &tmp); //BUG-Fix Dietmar
246 if (button && type != FL_COMBOX_NORMAL) {
247 fl_set_object_label(button, "@2<-");
248 fl_redraw_object(button);
250 int x = label->form->x + label->x, y = label->form->y + label->y;
251 fl_set_form_position(form, x, y + label->h);
252 fl_show_form(form, FL_PLACE_POSITION, FL_NOBORDER, "");
254 fl_set_browser_topline(browser, sel);
255 fl_select_browser_line(browser, sel);
257 XGrabPointer(fl_display, form->window, false,
258 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
259 GrabModeAsync, GrabModeAsync,
264 void Combox::Hide(int who)
266 if (!who && browser && label) {
267 sel = fl_get_browser(browser);
269 if (type == FL_COMBOX_INPUT)
270 fl_set_input(label, fl_get_browser_line(browser, sel));
272 fl_set_object_label(label,
273 fl_get_browser_line(browser, sel));
274 if (callback) callback(sel,cb_arg);
276 XUngrabPointer(fl_display, 0);
280 XSetInputFocus(fl_display, save_window,
281 RevertToParent, CurrentTime); // BUG-FIX-Dietmar
285 if (type != FL_COMBOX_NORMAL){
286 fl_set_object_label(button, "@2->");
287 fl_redraw_object(button);
294 void Combox::activate()
296 if (browser) fl_activate_object(browser);
297 if (button) fl_activate_object(button);
298 if (label) fl_activate_object(label);
302 void Combox::deactivate()
304 if (browser) fl_deactivate_object(browser);
305 if (button) fl_deactivate_object(button);
306 if (label) fl_deactivate_object(label);
309 void Combox::input_cb(FL_OBJECT *ob, long)
311 Combox *combo = (Combox*)ob->u_vdata;
313 char const *text = fl_get_input(ob);
316 combo->is_empty = false;
320 void Combox::combo_cb(FL_OBJECT *ob, long data)
322 Combox *combo = (Combox*)ob->u_vdata;
326 int i = combo->get();
327 switch (fl_get_button_numb(ob)) {
332 combo->callback(combo->sel,
340 combo->callback(combo->sel,
344 default: combo->Show(); break;
355 int Combox::peek_event(FL_FORM * form, void *xev)
357 FL_OBJECT *ob = (FL_OBJECT *)form->u_vdata;
358 Combox *combo = (Combox*)ob->u_vdata;
361 if(((XEvent *)xev)->type==ButtonPress && !ob->belowmouse)
364 // I don't know why belowmouse does not work, but it doesn't. (Asger)
365 if (((XEvent *) xev)->type == ButtonPress && (
366 ((XEvent *)xev)->xbutton.x - ob->x < 0 ||
367 ((XEvent *)xev)->xbutton.x - ob->x > ob->w ||
368 ((XEvent *)xev)->xbutton.y - ob->y < 0 ||
369 ((XEvent *)xev)->xbutton.y - ob->y > ob->h))
376 if (((XEvent*)xev)->type != KeyPress) return 0;
379 static int num_bytes;
380 KeySym keysym_return;
381 num_bytes = XLookupString(&((XEvent*)xev)->xkey, s_r, 10,
382 &keysym_return, NULL);
384 switch (keysym_return) {
386 if (fl_get_browser(combo->browser) <
387 fl_get_browser_maxline(combo->browser))
388 fl_select_browser_line(combo->browser,
389 fl_get_browser(combo->browser)+1);
390 if (fl_get_browser(combo->browser)>=
391 fl_get_browser_topline(combo->browser) +
392 fl_get_browser_screenlines(combo->browser))
393 fl_set_browser_topline(combo->browser,
394 fl_get_browser(combo->browser)
395 - fl_get_browser_screenlines(combo->browser)+1);
396 if (fl_get_browser(combo->browser)<
397 fl_get_browser_topline(combo->browser))
398 fl_set_browser_topline(combo->browser,
399 fl_get_browser(combo->browser));
402 if (fl_get_browser(combo->browser) > 1)
403 fl_select_browser_line(combo->browser,
404 fl_get_browser(combo->browser)-1);
405 if (fl_get_browser(combo->browser)>=
406 fl_get_browser_topline(combo->browser) +
407 fl_get_browser_screenlines(combo->browser))
408 fl_set_browser_topline(combo->browser,
409 fl_get_browser(combo->browser)
410 - fl_get_browser_screenlines(combo->browser)+1);
411 if (fl_get_browser(combo->browser) <
412 fl_get_browser_topline(combo->browser))
413 fl_set_browser_topline(combo->browser,
414 fl_get_browser(combo->browser));
435 //Combox combo(FL_COMBOX_DROPLIST);
436 Combox combo(FL_COMBOX_INPUT);
440 FD_test *create_form_test(void)
443 FD_test *fdui = (FD_test *) fl_calloc(1, sizeof(*fdui));
445 fdui->test = fl_bgn_form(FL_NO_BOX, 320, 190);
446 obj = fl_add_box(FL_UP_BOX,0,0,320,190,"");
447 obj = fl_add_box(FL_DOWN_BOX,10,50,300,110,"");
448 obj = fl_add_button(FL_NORMAL_BUTTON,250,10,50,30,_("Done"));
449 combo.add(10,15,120,25,135);
457 fprintf(stderr, "selected %d:%s\n", i, combo.getline());
460 int main(int argc, char *argv[])
464 // Same defaults as in lyx
466 cntl.buttonFontSize = FL_NORMAL_SIZE;
467 cntl.browserFontSize = FL_NORMAL_SIZE;
468 cntl.labelFontSize = FL_NORMAL_SIZE;
469 cntl.choiceFontSize = FL_NORMAL_SIZE;
470 cntl.inputFontSize = FL_NORMAL_SIZE;
471 cntl.borderWidth = -2;
472 fl_set_defaults(FL_PDButtonFontSize, &cntl);
473 fl_set_defaults(FL_PDBrowserFontSize, &cntl);
474 fl_set_defaults(FL_PDLabelFontSize, &cntl);
475 fl_set_defaults(FL_PDChoiceFontSize, &cntl);
476 fl_set_defaults(FL_PDInputFontSize, &cntl);
477 fl_set_defaults(FL_PDBorderWidth, &cntl);
478 fl_initialize(&argc, argv, 0, 0, 0);
480 fd_test = create_form_test();
482 /* fill-in form initialization code */
483 combo.addline("Title");
484 combo.addline("Author");
485 combo.addline("Date");
486 combo.addline("Abstract");
487 combo.addline("Chapter");
488 combo.addline("Section");
489 combo.addline("Subsection");
490 combo.addline("List");
491 combo.addline("Description");
492 combo.addline("Verse");
493 combo.addline("Verbatim");
494 combo.setcallback(combo_cb);
497 /* show the first form */
498 fl_show_form(fd_test->test,FL_PLACE_CENTER,FL_FULLBORDER,"test");