home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / combox.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  12KB  |  493 lines

  1. // -*- C++ -*-
  2. /*
  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.         
  6.  * 
  7.  *  GNU Copyleft (C) 1996 Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
  8.  *                        and the LyX Team.
  9.  * 
  10.  *  Dependencies:  Only XForms, but created to be used with LyX.
  11.  * 
  12.  */ 
  13.  
  14. /* Change log:
  15.  *  
  16.  *  2/06/1996,   Alejandro Aguilar Sierra 
  17.  *    Created and tested.
  18.  *  
  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.
  22.  *
  23.  *  6/06/1996,   Lars Gullik Bj°nnes
  24.  *    Added a combox with an input object. and a pre and a post handle.
  25.  * 
  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.
  29.  * 
  30.  */ 
  31.  
  32. #include <config.h>
  33.  
  34. #ifdef __GNUG__
  35. #pragma implementation
  36. #endif
  37.  
  38. #include "combox.h"
  39. #include <string.h>
  40. #if defined(__sgi)
  41. #include <strings.h>
  42. #endif
  43.  
  44. #include "error.h"
  45.  
  46. //     $Id: combox.C,v 1.1.1.1 1998/04/23 16:02:49 larsbj Exp $    
  47.  
  48. #if !defined(lint) && !defined(WITH_WARNINGS)
  49. static char vcid[] = "$Id: combox.C,v 1.1.1.1 1998/04/23 16:02:49 larsbj Exp $";
  50. #endif /* lint */
  51.  
  52.  
  53. Combox::Combox(combox_type t): type(t)
  54. {
  55.    browser = button = 0;
  56.    callback = 0;
  57.    label = 0;
  58.    cb_arg = 0;
  59.    _pre = 0;
  60.    _post = 0;
  61.    sel = 0;
  62.    form = 0;
  63. }
  64.  
  65.  
  66. Combox::~Combox()
  67. {
  68.    remove();
  69. }
  70.  
  71.  
  72. void Combox::clear()
  73. {
  74.     if (browser) fl_clear_browser(browser);   
  75.     sel = 0;
  76.     if (type == FL_COMBOX_INPUT)
  77.         fl_set_input(label, "");
  78.     else
  79.         fl_set_object_label(label, "");
  80.     is_empty = true;
  81. }
  82.  
  83.  
  84. void Combox::remove()
  85. {
  86.     //lyxerr.print(LString("Button: ") + int(button));
  87.     if (button) {
  88.         fl_delete_object(button);
  89.         fl_free_object(button); 
  90.     }
  91.     
  92.     //lyxerr.print(LString("Label: ") + int(label));
  93.     if (label && label!=button) {
  94.         fl_delete_object(label);
  95.         fl_free_object(label); 
  96.     }
  97.     
  98.     //lyxerr.print(LString("Form: ") + int(form));
  99.     //lyxerr.print(LString("Browser: ") + int(browser));
  100.     if (form && browser) {
  101.        fl_delete_object(browser);
  102.        fl_free_object(browser);
  103.        fl_free_form(form);
  104.     }
  105.     button = 0; 
  106.     browser = 0; 
  107.     label = 0;
  108.     form = 0;
  109.     sel = 0;
  110.     is_empty = true;
  111. }
  112.  
  113.  
  114. void Combox::addline(LString const &text)
  115. {
  116.     if (!browser) return;
  117.     fl_add_browser_line(browser, text.c_str());
  118.     
  119.     // By default the first item is selected
  120.     if (!sel) {
  121.         sel = 1;
  122.         if (type == FL_COMBOX_INPUT)
  123.             fl_set_input(label, text.c_str());
  124.         else
  125.             fl_set_object_label(label, text.c_str()); 
  126.     }
  127.     is_empty = false;
  128. }
  129.  
  130.  
  131. bool Combox::select_text(LString const &t)
  132. {
  133.     if (!browser || t.empty) return false;
  134.     for (int i=1; i<=fl_get_browser_maxline(browser); i++) {
  135.         if (!strcmp(t.c_str(), fl_get_browser_line(browser, i))) {
  136.             select(i);
  137.             return true;
  138.         }
  139.     }
  140.     return false;  // t does not exist in browser
  141. }
  142.  
  143.  
  144. void Combox::select(int i)
  145. {
  146.     if (!browser || !button) return;
  147.     if (i>0 && i<=fl_get_browser_maxline(browser)) sel = i; 
  148.     fl_deactivate_object(button);
  149.     
  150.     if (type == FL_COMBOX_INPUT)
  151.         fl_set_input(label, fl_get_browser_line(browser, sel));
  152.     else
  153.         fl_set_object_label(label, fl_get_browser_line(browser, sel)); 
  154.     fl_activate_object(button); 
  155. }
  156.  
  157.  
  158. void Combox::add(int x, int y, int w, int hmin, int hmax)
  159. {  
  160.     FL_OBJECT *obj;
  161.     
  162.     switch(type) {
  163.     case FL_COMBOX_DROPLIST:
  164.     {
  165.         button = obj = fl_add_button(FL_NORMAL_BUTTON,
  166.                          x+w-22,y,22,hmin,"@2->");
  167.         fl_set_object_color(obj,FL_MCOL, FL_MCOL);
  168.         fl_set_object_callback(obj,combo_cb,0);
  169.             label = obj = fl_add_button(FL_NORMAL_TEXT,x,y,w-22,hmin,"");
  170.         fl_set_object_boxtype(obj,FL_DOWN_BOX);
  171.         fl_set_object_color(obj,FL_MCOL,FL_BLACK);
  172.         fl_set_object_lalign(obj,FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
  173.         fl_set_object_callback(obj,combo_cb,0);
  174.         break;
  175.     }
  176.     case FL_COMBOX_NORMAL:
  177.     {
  178.         button = obj = fl_add_button(FL_NORMAL_BUTTON,x,y,w,hmin,"");
  179.         fl_set_object_color(obj,FL_MCOL, FL_MCOL);
  180.         fl_set_object_boxtype(obj,FL_DOWN_BOX);
  181.         fl_set_object_callback(obj,combo_cb,0);
  182.         fl_set_object_color(obj,FL_MCOL,FL_BLACK);
  183.         label = button;
  184.         break;
  185.     }
  186.     case FL_COMBOX_INPUT:
  187.     {
  188.         button = obj = fl_add_button(FL_NORMAL_BUTTON,
  189.                          x+w-22,y,22,hmin,"@2->");
  190.         fl_set_object_color(obj,FL_MCOL, FL_MCOL);
  191.         fl_set_object_callback(obj,combo_cb,0);
  192.         label = obj = fl_add_input(FL_NORMAL_INPUT,x,y,w-22,hmin,"");
  193.         fl_set_object_boxtype(obj,FL_DOWN_BOX);
  194.         fl_set_object_return(obj, FL_RETURN_END_CHANGED);
  195.         fl_set_object_callback(obj,input_cb,0);
  196.         //fl_set_object_color(obj,FL_MCOL,FL_BLACK);
  197.         //fl_set_object_lalign(obj,FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
  198.         break;
  199.     }
  200.     } // end of switch
  201.  
  202.     label->u_vdata = (void*)this;
  203.     button->u_vdata = (void*)this;
  204.  
  205.     // Hmm, it seems fl_create_browser is broken in xforms 0.86.
  206.     // We have to work around that by creating the dropped browser form
  207.     // at this point already. However, this means that we have
  208.     // to do a little hacking: (Asger)
  209.     FL_FORM * current_form = fl_current_form;
  210.     fl_end_form();
  211.  
  212.     bw = w+20; bh = hmax-hmin-12;
  213.  
  214.     form = fl_bgn_form(FL_NO_BOX, bw, bh);
  215.     browser = obj = fl_add_browser(FL_HOLD_BROWSER, 0, 0, bw,bh,"");
  216.     fl_set_object_boxtype(obj,FL_UP_BOX);
  217.     fl_set_object_color(obj,FL_MCOL, FL_YELLOW);
  218.     fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity);
  219.     fl_set_object_callback(obj,combo_cb,2);
  220.     fl_end_form();
  221.     browser->u_vdata = (void*)this;
  222.     form->u_vdata = browser;
  223.     fl_register_raw_callback(form, ButtonPressMask|KeyPressMask,peek_event);
  224.  
  225.     // And revert to adding to the old form (Asger)
  226.     fl_addto_form(current_form);
  227. }
  228.  
  229.  
  230. static Window save_window;
  231.  
  232. void Combox::Show()
  233. {
  234.     if (_pre) _pre();
  235.     
  236.     int tmp;
  237.     XGetInputFocus(fl_display, &save_window, &tmp); //BUG-Fix Dietmar
  238.     XFlush(fl_display);
  239.     if (button && type != FL_COMBOX_NORMAL) {
  240.         fl_set_object_label(button, "@2<-");          
  241.         fl_redraw_object(button);
  242.     }
  243.     int x = label->form->x + label->x, y = label->form->y + label->y;
  244.     fl_set_form_position(form, x, y + label->h);
  245.     fl_show_form(form, FL_PLACE_POSITION, FL_NOBORDER, "");
  246.         if (sel>0) {
  247.         fl_set_browser_topline(browser, sel);
  248.         fl_select_browser_line(browser, sel);
  249.     }
  250.     XGrabPointer(fl_display, form->window, false,
  251.              ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  252.              GrabModeAsync, GrabModeAsync,
  253.              0, 0,0);
  254.     XFlush(fl_display);
  255. }
  256.  
  257. void Combox::Hide(int who)
  258. {  
  259.     if (!who && browser && label) {
  260.         sel = fl_get_browser(browser);
  261.         
  262.         if (type == FL_COMBOX_INPUT)
  263.             fl_set_input(label, fl_get_browser_line(browser, sel));
  264.         else
  265.             fl_set_object_label(label,
  266.                         fl_get_browser_line(browser, sel));        
  267.             if (callback) callback(sel,cb_arg);
  268.     }
  269.         XUngrabPointer(fl_display, 0);
  270.     XFlush(fl_display);
  271.         if (form) {
  272.         fl_hide_form(form);
  273.         XSetInputFocus(fl_display, save_window,
  274.                    RevertToParent, CurrentTime); // BUG-FIX-Dietmar
  275.         XFlush(fl_display);
  276.         }
  277.     if (button) {
  278.             if (type != FL_COMBOX_NORMAL){
  279.             fl_set_object_label(button, "@2->");
  280.             fl_redraw_object(button);
  281.         }
  282.     } 
  283.         if (_post) _post();
  284. }
  285.  
  286.  
  287. void Combox::activate()
  288. {
  289.     if (browser) fl_activate_object(browser);
  290.     if (button) fl_activate_object(button);
  291.     if (label) fl_activate_object(label);
  292. }
  293.  
  294.  
  295. void Combox::deactivate()
  296. {
  297.     if (browser) fl_deactivate_object(browser);
  298.     if (button) fl_deactivate_object(button);
  299.     if (label) fl_deactivate_object(label);
  300. }
  301.  
  302. void Combox::input_cb(FL_OBJECT *ob, long)
  303. {
  304.     Combox *combo = (Combox*)ob->u_vdata;
  305.  
  306.     char const *text = fl_get_input(ob);
  307.  
  308.     combo->addto(text);
  309.     combo->is_empty = false;
  310. }
  311.  
  312.  
  313. void Combox::combo_cb(FL_OBJECT *ob, long data)
  314. {
  315.     Combox *combo = (Combox*)ob->u_vdata;
  316.     switch (data) {
  317.     case 0:
  318.     {  
  319.         int i = combo->get();
  320.         switch (fl_get_button_numb(ob)) {
  321.         case 2: 
  322.         {
  323.             combo->select(--i); 
  324.             if (combo->callback)
  325.                 combo->callback(combo->sel,
  326.                         combo->cb_arg);
  327.             break;
  328.         }
  329.         case 3: 
  330.         {
  331.             combo->select(++i);  
  332.             if (combo->callback)
  333.                 combo->callback(combo->sel,
  334.                         combo->cb_arg);
  335.             break;
  336.         }
  337.         default: combo->Show(); break;
  338.         }
  339.         break;
  340.     }
  341.     case 2:
  342.         combo->Hide();
  343.         break;
  344.     }
  345. }
  346.  
  347.  
  348. int Combox::peek_event(FL_FORM * form, void *xev)
  349. {
  350.     FL_OBJECT *ob = (FL_OBJECT *)form->u_vdata;
  351.     Combox *combo = (Combox*)ob->u_vdata;
  352.     
  353. // I don't know why belowmouse does not work, but it doesn't. (Asger)
  354. #warning Check again!
  355.         if (((XEvent *) xev)->type == ButtonPress && (
  356.             ((XEvent *)xev)->xbutton.x - ob->x < 0 ||
  357.             ((XEvent *)xev)->xbutton.x - ob->x > ob->w ||
  358.             ((XEvent *)xev)->xbutton.y - ob->y < 0 ||
  359.             ((XEvent *)xev)->xbutton.y - ob->y > ob->h))
  360.     {
  361.         combo->Hide(1); 
  362.         return 1;
  363.     }
  364.         
  365.     if (((XEvent*)xev)->type != KeyPress) return 0;
  366.     
  367.     char s_r[10];
  368.     static int num_bytes;
  369.     KeySym keysym_return;
  370.     num_bytes = XLookupString(&((XEvent*)xev)->xkey, s_r, 10, 
  371.                   &keysym_return, NULL);
  372.     XFlush(fl_display);
  373.     switch (keysym_return) {
  374.     case XK_Down:
  375.         if (fl_get_browser(combo->browser) <
  376.             fl_get_browser_maxline(combo->browser))
  377.             fl_select_browser_line(combo->browser,
  378.                            fl_get_browser(combo->browser)+1);
  379.         if (fl_get_browser(combo->browser)>=
  380.             fl_get_browser_topline(combo->browser) +
  381.             fl_get_browser_screenlines(combo->browser))
  382.             fl_set_browser_topline(combo->browser,
  383.                            fl_get_browser(combo->browser)
  384.                            - fl_get_browser_screenlines(combo->browser)+1);
  385.         if (fl_get_browser(combo->browser)<
  386.             fl_get_browser_topline(combo->browser))
  387.             fl_set_browser_topline(combo->browser,
  388.                            fl_get_browser(combo->browser));
  389.         return 1; 
  390.     case XK_Up:
  391.         if (fl_get_browser(combo->browser) > 1)
  392.             fl_select_browser_line(combo->browser,
  393.                            fl_get_browser(combo->browser)-1);
  394.         if (fl_get_browser(combo->browser)>=
  395.             fl_get_browser_topline(combo->browser) +
  396.             fl_get_browser_screenlines(combo->browser))
  397.             fl_set_browser_topline(combo->browser,
  398.                            fl_get_browser(combo->browser)
  399.                            - fl_get_browser_screenlines(combo->browser)+1);
  400.         if (fl_get_browser(combo->browser) <
  401.             fl_get_browser_topline(combo->browser))
  402.             fl_set_browser_topline(combo->browser,
  403.                            fl_get_browser(combo->browser));
  404.         return 1;
  405.     case XK_Return:
  406.         combo->Hide();
  407.         return 1;
  408.     case XK_Escape:
  409.         combo->Hide(1);
  410.         return 1;
  411.     }
  412.     return 0;  
  413. }
  414.     
  415.  
  416. #ifdef TESTCOMBO
  417. typedef struct {
  418.     FL_FORM *test;
  419.     FL_OBJECT *bar;
  420.     void *vdata;
  421.     long ldata;
  422. } FD_test;
  423.  
  424. //Combox combo(FL_COMBOX_DROPLIST);
  425. Combox combo(FL_COMBOX_INPUT);
  426.  
  427. FD_test *fd_test;
  428.    
  429. FD_test *create_form_test(void)
  430. {
  431.    FL_OBJECT *obj;
  432.    FD_test *fdui = (FD_test *) fl_calloc(1, sizeof(*fdui));
  433.    
  434.    fdui->test = fl_bgn_form(FL_NO_BOX, 320, 190);
  435.    obj = fl_add_box(FL_UP_BOX,0,0,320,190,"");
  436.    obj = fl_add_box(FL_DOWN_BOX,10,50,300,110,"");
  437.    obj = fl_add_button(FL_NORMAL_BUTTON,250,10,50,30,_("Done"));
  438.    combo.add(10,15,120,25,135); 
  439.    fl_end_form();
  440.  
  441.   return fdui;
  442. }
  443.  
  444. void combo_cb(int i)
  445. {
  446.    fprintf(stderr, "selected %d:%s\n", i, combo.getline());
  447. }
  448.  
  449. int main(int argc, char *argv[])
  450. {
  451.     //int n1;
  452.    
  453.    // Same defaults as in lyx 
  454.    FL_IOPT cntl;
  455.    cntl.buttonFontSize = FL_NORMAL_SIZE;
  456.    cntl.browserFontSize = FL_NORMAL_SIZE;
  457.    cntl.labelFontSize = FL_NORMAL_SIZE;
  458.    cntl.choiceFontSize = FL_NORMAL_SIZE;
  459.    cntl.inputFontSize = FL_NORMAL_SIZE;
  460.    cntl.borderWidth = -2;
  461.    fl_set_defaults(FL_PDButtonFontSize, &cntl);  
  462.    fl_set_defaults(FL_PDBrowserFontSize, &cntl);  
  463.    fl_set_defaults(FL_PDLabelFontSize, &cntl);  
  464.    fl_set_defaults(FL_PDChoiceFontSize, &cntl);  
  465.    fl_set_defaults(FL_PDInputFontSize, &cntl);  
  466.    fl_set_defaults(FL_PDBorderWidth, &cntl);
  467.    fl_initialize(&argc, argv, 0, 0, 0);
  468.    
  469.    fd_test = create_form_test();
  470.  
  471.    /* fill-in form initialization code */
  472.    combo.addline("Title");
  473.    combo.addline("Author");
  474.    combo.addline("Date");
  475.    combo.addline("Abstract");
  476.    combo.addline("Chapter");
  477.    combo.addline("Section");
  478.    combo.addline("Subsection");
  479.    combo.addline("List");
  480.    combo.addline("Description");
  481.    combo.addline("Verse");
  482.    combo.addline("Verbatim");
  483.    combo.setcallback(combo_cb);
  484. //   combo.select(4);
  485.    
  486.    /* show the first form */
  487.    fl_show_form(fd_test->test,FL_PLACE_CENTER,FL_FULLBORDER,"test");
  488.    fl_do_forms();
  489.    return 0;
  490. }
  491.  
  492. #endif
  493.