]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/combox.c
Introduce LFUN_PRINT.
[lyx.git] / src / frontends / xforms / combox.c
index 3dc9bea9c3b1968922b7f3252a0d13f4044b9d91..b4b3094dce874deca8f74b0b9d0836379a2ff077 100644 (file)
@@ -1,19 +1,24 @@
 /**
  * \file combox.c
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
  * \author Alejandro Aguilar Sierra
+ * \author Lars Gullik Bjønnes
+ * \author Jean-Marc Lasgouttes
  * \author Angus Leeming
  *
+ * Full author contact details are available in file CREDITS
+ *
  * This is a rewrite of Alejandro's C++ Combox class, originally written
  * for LyX in 1996. The rewrite turns it into a native xforms widget.
  */
 #include <config.h>
 
-#include FORMS_H_LOCATION
+#include "lyx_forms.h"
 #include "combox.h"
 #include "freebrowser.h"
 
-
 extern void fl_add_child(FL_OBJECT *, FL_OBJECT *);
 extern void fl_addto_freelist(void *);
 
@@ -22,7 +27,7 @@ typedef struct {
      /** A pointer to the parent widget */
     FL_OBJECT * combox;
 
-    FL_FREEBROWSER * browser;
+    FL_FREEBROWSER * freebrowser;
     int browser_height;
 
     /** The browser will be displayed either below or above the main body. */
@@ -61,9 +66,10 @@ static void set_state_label(COMBOX_SPEC * sp, int state);
 static void attrib_change(COMBOX_SPEC * sp);
 
 
-FL_OBJECT * fl_create_combox(int type,
-                            FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h,
-                            char const * label)
+FL_OBJECT *
+fl_create_combox(FL_COMBOX_TYPE type,
+                FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h,
+                char const * label)
 {
     FL_OBJECT * ob;
     FL_OBJECT * button;
@@ -73,6 +79,9 @@ FL_OBJECT * fl_create_combox(int type,
     FL_Coord const ws = 0.7 * h;
     FL_Coord const xs = x + w - ws;
 
+    /* The width of button_chosen */
+    FL_Coord const wc = (type == FL_DROPLIST_COMBOX) ? (w - ws) : w;
+
     ob = fl_make_object(FL_COMBOX, type, x, y, w, h, label, combox_handle);
     ob->align = FL_ALIGN_LEFT;
 
@@ -81,23 +90,26 @@ FL_OBJECT * fl_create_combox(int type,
     sp->browser_height = 100;
     sp->browser_position = FL_FREEBROWSER_BELOW;
 
-    sp->browser = fl_create_freebrowser(sp);
-    sp->browser->callback = update_button_chosen;
+    sp->freebrowser = fl_create_freebrowser(sp);
+    sp->freebrowser->callback = update_button_chosen;
 
-    sp->button_state = fl_add_button(FL_NORMAL_BUTTON, xs, y, ws, h, "");
+    sp->button_state = 0;
+    if (type == FL_DROPLIST_COMBOX) {
+       sp->button_state = fl_add_button(FL_NORMAL_BUTTON, xs, y, ws, h, "");
 
-    button = sp->button_state;
-    fl_set_object_lalign(button, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
-    fl_set_object_callback(button, state_cb, 0);
-    fl_set_object_posthandler(button, combox_post);
-    fl_set_object_prehandler(button,  combox_pre);
-    set_state_label(sp, COMBOX_CLOSED);
+       button = sp->button_state;
+       fl_set_object_lalign(button, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
+       fl_set_object_callback(button, state_cb, 0);
+       fl_set_object_posthandler(button, combox_post);
+       fl_set_object_prehandler(button,  combox_pre);
+       set_state_label(sp, COMBOX_CLOSED);
 
-    set_activation(button, DEACTIVATE);
-    button->parent = ob;
-    button->u_vdata = sp;
+       set_activation(button, DEACTIVATE);
+       button->parent = ob;
+       button->u_vdata = sp;
+    }
 
-    sp->button_chosen = fl_add_button(FL_NORMAL_TEXT, x, y, (w - ws), h, "");
+    sp->button_chosen = fl_add_button(FL_NORMAL_TEXT, x, y, wc, h, "");
 
     button = sp->button_chosen;
     fl_set_object_boxtype(button, FL_FRAME_BOX);
@@ -113,14 +125,16 @@ FL_OBJECT * fl_create_combox(int type,
 }
 
 
-FL_OBJECT * fl_add_combox(int type,
-                         FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h,
-                         char const * label)
+FL_OBJECT *
+fl_add_combox(FL_COMBOX_TYPE type,
+             FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h,
+             char const * label)
 {
     FL_OBJECT * ob = fl_create_combox(type, x, y, w, h, label);
     COMBOX_SPEC * sp = ob->spec;
 
-    fl_add_child(ob, sp->button_state);
+    if (sp->button_state)
+       fl_add_child(ob, sp->button_state);
     fl_add_child(ob, sp->button_chosen);
 
     fl_add_object(fl_current_form, ob);
@@ -128,7 +142,8 @@ FL_OBJECT * fl_add_combox(int type,
 }
 
 
-void fl_set_combox_browser_height(FL_OBJECT * ob, int bh)
+void
+fl_set_combox_browser_height(FL_OBJECT * ob, int bh)
 {
     COMBOX_SPEC * sp;
 
@@ -140,7 +155,8 @@ void fl_set_combox_browser_height(FL_OBJECT * ob, int bh)
 }
 
 
-void fl_set_combox_position(FL_OBJECT * ob, int position)
+void
+fl_set_combox_position(FL_OBJECT * ob, FL_COMBOX_POSITION position)
 {
     COMBOX_SPEC * sp;
 
@@ -148,14 +164,15 @@ void fl_set_combox_position(FL_OBJECT * ob, int position)
        return;
 
     sp = ob->spec;
-    sp->browser_position = (position == FL_FREEBROWSER_ABOVE) ?
+    sp->browser_position = (position == FL_COMBOX_ABOVE) ?
        FL_FREEBROWSER_ABOVE : FL_FREEBROWSER_BELOW;
 
     set_state_label(sp, COMBOX_CLOSED);
 }
 
 
-void fl_clear_combox(FL_OBJECT * ob)
+void
+fl_clear_combox(FL_OBJECT * ob)
 {
     COMBOX_SPEC * sp;
     FL_OBJECT * browser;
@@ -164,14 +181,15 @@ void fl_clear_combox(FL_OBJECT * ob)
        return;
 
     sp = ob->spec;
-    browser = fl_get_freebrowser_browser(sp->browser);
+    browser = sp->freebrowser->browser;
 
     fl_clear_browser(browser);
     fl_set_object_label(sp->button_chosen, "");
 }
 
 
-void fl_addto_combox(FL_OBJECT * ob, char const * text)
+void
+fl_addto_combox(FL_OBJECT * ob, char const * text)
 {
     COMBOX_SPEC * sp;
     FL_OBJECT * browser;
@@ -183,7 +201,7 @@ void fl_addto_combox(FL_OBJECT * ob, char const * text)
        return;
 
     sp = ob->spec;
-    browser = fl_get_freebrowser_browser(sp->browser);
+    browser = sp->freebrowser->browser;
 
     /* Split the string on '|' boundaries. */
     i = j = 0;
@@ -197,22 +215,25 @@ void fl_addto_combox(FL_OBJECT * ob, char const * text)
        }
     }
 
-    if (j != 0)
-       {
+    if (j != 0) {
            line[j] = '\0';
            fl_add_browser_line(browser, line);
-       }
+    }
 
     /* By default the first item is selected */
-    if (!fl_get_browser(browser)) {
-       fl_set_object_label(sp->button_chosen, text);
+    if (fl_get_browser_maxline(browser)) {
+       char const * const label = fl_get_browser_line(browser, 1);
+       fl_set_object_label(sp->button_chosen, label);
+       fl_select_browser_line(browser, 1);
        set_activation(sp->button_chosen, ACTIVATE);
-       set_activation(sp->button_state,  ACTIVATE);
+       if (sp->button_state)
+           set_activation(sp->button_state,  ACTIVATE);
     }
 }
 
 
-void fl_set_combox(FL_OBJECT * ob, int sel)
+void
+fl_set_combox(FL_OBJECT * ob, int sel)
 {
     COMBOX_SPEC * sp;
     FL_OBJECT * browser;
@@ -221,7 +242,7 @@ void fl_set_combox(FL_OBJECT * ob, int sel)
        return;
 
     sp = ob->spec;
-    browser = fl_get_freebrowser_browser(sp->browser);
+    browser = sp->freebrowser->browser;
 
     if (sel < 1 || sel > fl_get_browser_maxline(browser))
        return;
@@ -231,7 +252,8 @@ void fl_set_combox(FL_OBJECT * ob, int sel)
 }
 
 
-int fl_get_combox(FL_OBJECT * ob)
+int
+fl_get_combox(FL_OBJECT * ob)
 {
     COMBOX_SPEC * sp;
     FL_OBJECT * browser;
@@ -240,12 +262,13 @@ int fl_get_combox(FL_OBJECT * ob)
        return 0;
 
     sp = ob->spec;
-    browser = fl_get_freebrowser_browser(sp->browser);
+    browser = sp->freebrowser->browser;
     return fl_get_browser(browser);
 }
 
 
-char const * fl_get_combox_text(FL_OBJECT * ob)
+char const *
+fl_get_combox_text(FL_OBJECT * ob)
 {
     COMBOX_SPEC * sp;
 
@@ -257,7 +280,8 @@ char const * fl_get_combox_text(FL_OBJECT * ob)
 }
 
 
-char const * fl_get_combox_line(FL_OBJECT * ob, int line)
+char const *
+fl_get_combox_line(FL_OBJECT * ob, int line)
 {
     COMBOX_SPEC * sp;
     FL_OBJECT * browser;
@@ -267,7 +291,7 @@ char const * fl_get_combox_line(FL_OBJECT * ob, int line)
        return 0;
 
     sp = ob->spec;
-    browser = fl_get_freebrowser_browser(sp->browser);
+    browser = sp->freebrowser->browser;
 
     maxlines = fl_get_browser_maxline(browser);
     if (line > maxlines)
@@ -277,7 +301,8 @@ char const * fl_get_combox_line(FL_OBJECT * ob, int line)
 }
 
 
-int fl_get_combox_maxitems(FL_OBJECT * ob)
+int
+fl_get_combox_maxitems(FL_OBJECT * ob)
 {
     COMBOX_SPEC * sp;
     FL_OBJECT * browser;
@@ -286,12 +311,13 @@ int fl_get_combox_maxitems(FL_OBJECT * ob)
        return 0;
 
     sp = ob->spec;
-    browser = fl_get_freebrowser_browser(sp->browser);
+    browser = sp->freebrowser->browser;
     return fl_get_browser_maxline(browser);
 }
 
 
-void fl_show_combox_browser(FL_OBJECT * ob)
+void
+fl_show_combox_browser(FL_OBJECT * ob)
 {
     if (!ob || ob->objclass != FL_COMBOX)
        return;
@@ -300,7 +326,8 @@ void fl_show_combox_browser(FL_OBJECT * ob)
 }
 
 
-void fl_hide_combox_browser(FL_OBJECT * ob)
+void
+fl_hide_combox_browser(FL_OBJECT * ob)
 {
     COMBOX_SPEC * sp;
 
@@ -308,12 +335,13 @@ void fl_hide_combox_browser(FL_OBJECT * ob)
        return;
 
     sp = ob->spec;
-    fl_free_freebrowser(sp->browser);
+    fl_free_freebrowser(sp->freebrowser);
 }
 
 
-static int combox_pre(FL_OBJECT * ob, int ev, FL_Coord mx, FL_Coord my,
-                     int key, void *xev)
+static int
+combox_pre(FL_OBJECT * ob, int ev, FL_Coord mx, FL_Coord my, int key,
+          void * xev)
 {
     COMBOX_SPEC * sp = ob->u_vdata;
     FL_OBJECT * combox = sp->combox;
@@ -323,8 +351,9 @@ static int combox_pre(FL_OBJECT * ob, int ev, FL_Coord mx, FL_Coord my,
 }
 
 
-static int combox_post(FL_OBJECT * ob, int ev, FL_Coord mx, FL_Coord my,
-                      int key, void *xev)
+static int
+combox_post(FL_OBJECT * ob, int ev, FL_Coord mx, FL_Coord my, int key,
+           void * xev)
 {
     COMBOX_SPEC * sp = ob->u_vdata;
     FL_OBJECT * combox = sp->combox;
@@ -334,8 +363,9 @@ static int combox_post(FL_OBJECT * ob, int ev, FL_Coord mx, FL_Coord my,
 }
 
 
-static int combox_handle(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my,
-                        int key, void * ev)
+static int
+combox_handle(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my, int key,
+             void * ev)
 {
     if (!ob || ob->objclass != FL_COMBOX)
        return 0;
@@ -346,13 +376,13 @@ static int combox_handle(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my,
        /* Fall through */
     case FL_DRAWLABEL:
        fl_draw_object_label(ob);
-       break;
+       break;
     case FL_SHORTCUT:
        show_browser(ob->spec);
        break;
     case FL_FREEMEM: {
        COMBOX_SPEC * sp = ob->spec;
-       fl_free_freebrowser(sp->browser);
+       fl_free_freebrowser(sp->freebrowser);
        /* children take care of themselves, but we must make sure that
           sp itself is free-d eventually. */
        fl_addto_freelist(sp);
@@ -363,7 +393,8 @@ static int combox_handle(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my,
 }
 
 
-static void set_activation(FL_OBJECT * ob, int activation)
+static void
+set_activation(FL_OBJECT * ob, int activation)
 {
     switch (activation) {
     case ACTIVATE:
@@ -377,7 +408,8 @@ static void set_activation(FL_OBJECT * ob, int activation)
 }
 
 
-static void show_browser(COMBOX_SPEC * sp)
+static void
+show_browser(COMBOX_SPEC * sp)
 {
     FL_OBJECT * ob = sp->combox;
 
@@ -391,27 +423,30 @@ static void show_browser(COMBOX_SPEC * sp)
     abs_y += (sp->browser_position == FL_FREEBROWSER_BELOW) ? ob->h : -bh;
 
     set_state_label(sp, COMBOX_OPEN);
-    fl_show_freebrowser(sp->browser, abs_x, abs_y, bw, bh);
+    fl_show_freebrowser(sp->freebrowser, abs_x, abs_y, bw, bh);
 }
 
 
-static void state_cb(FL_OBJECT * ob, long data)
+static void
+state_cb(FL_OBJECT * ob, long data)
 {
     show_browser(ob->u_vdata);
 }
 
 
-static void chosen_cb(FL_OBJECT * ob, long data)
+static void
+chosen_cb(FL_OBJECT * ob, long data)
 {
     show_browser(ob->u_vdata);
 }
 
 
-static void update_button_chosen(FL_FREEBROWSER * fb, int action)
+static void
+update_button_chosen(FL_FREEBROWSER * fb, int action)
 {
     COMBOX_SPEC * sp = fb->parent;
 
-    FL_OBJECT * browser = fl_get_freebrowser_browser(sp->browser);
+    FL_OBJECT * browser = sp->freebrowser->browser;
     FL_OBJECT * combox = sp->combox;
     if (!browser || !combox) return;
 
@@ -426,11 +461,16 @@ static void update_button_chosen(FL_FREEBROWSER * fb, int action)
 }
 
 
-static void set_state_label(COMBOX_SPEC * sp, int state)
+static void
+set_state_label(COMBOX_SPEC * sp, int state)
 {
     char const * const up   = "@2<-";
     char const * const down = "@2->";
     char const * label = 0;
+
+    if (!sp->button_state)
+       return;
+
     if (sp->browser_position == FL_FREEBROWSER_BELOW) {
        label = (state == COMBOX_OPEN) ? up : down;
     } else {
@@ -441,7 +481,8 @@ static void set_state_label(COMBOX_SPEC * sp, int state)
 }
 
 
-static void attrib_change(COMBOX_SPEC * sp)
+static void
+attrib_change(COMBOX_SPEC * sp)
 {
     FL_OBJECT * parent = sp->combox;
     FL_OBJECT * button = sp->button_chosen;
@@ -451,10 +492,12 @@ static void attrib_change(COMBOX_SPEC * sp)
     button->col2    = parent->col2;
     button->bw      = parent->bw;
 
-    button = sp->button_state;
+    if (sp->button_state) {
+       button = sp->button_state;
 
-    /* The boxtype is not changed */
-    button->col1    = parent->col1;
-    button->col2    = parent->col2;
-    button->bw      = parent->bw;
+       /* The boxtype is not changed */
+       button->col1    = parent->col1;
+       button->col2    = parent->col2;
+       button->bw      = parent->bw;
+    }
 }