-/*
- * Combox: A combination of two objects (a button and a browser) is
- * encapsulated to get a combobox-like object. All XForms
- * functions are hidden.
- *
- * GNU Copyleft 1996 Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
- * and the LyX Team.
- *
- * Dependencies: Only XForms, but created to be used with LyX.
- *
- */
+/**
+ * \file combox.C
+ * Copyright 1996Alejandro Aguilar Sierra
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Alejandro Aguilar Sierra
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+/* A combination of two objects (a button and a browser) is encapsulated to
+ * get a combobox-like object. All XForms functions are hidden.
+ *
+ */
/* Change log:
- *
- * 2/06/1996, Alejandro Aguilar Sierra
+ *
+ * 2/06/1996, Alejandro Aguilar Sierra
* Created and tested.
- *
- * 4/06/1996, Alejandro Aguilar Sierra
+ *
+ * 4/06/1996, Alejandro Aguilar Sierra
* Added droplist mode (a button with a black down arrow at right)
* and support for middle and right buttons, as XForms choice object.
*
* 6/06/1996, Lars Gullik Bjønnes
* Added a combox with an input object. and a pre and a post handle.
- *
- * 22/07/96, Alejandro Aguilar Sierra
+ *
+ * 22/07/96, Alejandro Aguilar Sierra
* Assigned to the browser its own popup window. No more need of
* external pre and post handlers to simulate the wanted behaviour.
- *
- */
+ *
+ */
#include <config.h>
// These are C wrappers around static members of Combox, used as
// callbacks for xforms.
-extern "C" void C_Combox_input_cb(FL_OBJECT *ob, long);
-extern "C" void C_Combox_combo_cb(FL_OBJECT *ob, long data) ;
-extern "C" int C_Combox_peek_event(FL_FORM * form, void *xev);
+extern "C" {
+
+ static
+ void C_Combox_input_cb(FL_OBJECT * ob, long data)
+ {
+ Combox::input_cb(ob, data);
+ }
+
+ static
+ void C_Combox_combo_cb(FL_OBJECT * ob, long data)
+ {
+ Combox::combo_cb(ob, data);
+ }
+
+ static
+ int C_Combox_peek_event(FL_FORM * form, void *xev)
+ {
+ return Combox::peek_event(form, xev);
+ }
+
+}
+
Combox::Combox(combox_type t)
- : type(t), tabfolder1(0), tabfolder2(0)
+ : type(t)
{
browser = button = 0;
callback = 0;
Combox::~Combox()
{
- remove();
+ // This is now handled by the XFormsView destructor (Lgb)
+ // remove();
}
void Combox::clear()
{
- if (browser) fl_clear_browser(browser);
+ if (browser) fl_clear_browser(browser);
sel = 0;
if (type == FL_COMBOX_INPUT)
fl_set_input(label, "");
lyxerr[Debug::GUI] << "Button: " << button << endl;
if (button) {
fl_delete_object(button);
- fl_free_object(button);
+ fl_free_object(button);
}
-
+
lyxerr[Debug::GUI] << "Label: " << label << endl;
if (label && label != button) {
fl_delete_object(label);
- fl_free_object(label);
+ fl_free_object(label);
}
-
+
lyxerr[Debug::GUI] << "Form: " << form << endl;
lyxerr[Debug::GUI] << "Browser: " << browser << endl;
if (form && browser) {
fl_free_object(browser);
fl_free_form(form);
}
- button = 0;
- browser = 0;
+ button = 0;
+ browser = 0;
label = 0;
form = 0;
sel = 0;
{
if (!browser) return;
fl_add_browser_line(browser, text.c_str());
-
+
// By default the first item is selected
if (!sel) {
sel = 1;
if (type == FL_COMBOX_INPUT)
fl_set_input(label, text.c_str());
else
- fl_set_object_label(label, text.c_str());
+ fl_set_object_label(label, text.c_str());
}
is_empty = false;
}
-bool Combox::select_text(string const & t)
+bool Combox::select(string const & t)
{
if (!browser || t.empty()) return false;
int const maxline = fl_get_browser_maxline(browser);
-
+
for (int i = 1; i <= maxline; ++i) {
if (t == fl_get_browser_line(browser, i)) {
select(i);
void Combox::select(int i)
{
if (!browser || !button) return;
- if (i > 0 && i <= fl_get_browser_maxline(browser)) sel = i;
+ if (i > 0 && i <= fl_get_browser_maxline(browser)) sel = i;
fl_deactivate_object(button);
-
+
if (type == FL_COMBOX_INPUT)
fl_set_input(label, fl_get_browser_line(browser, sel));
else
- fl_set_object_label(label, fl_get_browser_line(browser, sel));
- fl_activate_object(button);
+ fl_set_object_label(label, fl_get_browser_line(browser, sel));
+ fl_activate_object(button);
}
-void Combox::add(int x, int y, int w, int hmin, int hmax,
- FL_OBJECT * tabfolder1_, FL_OBJECT * tabfolder2_)
+void Combox::add(int x, int y, int w, int hmin, int hmax)
{
- // Store these for later use in working round an xforms bug in Show()
- tabfolder1 = tabfolder1_;
- tabfolder2 = tabfolder2_;
-
FL_OBJECT * obj;
-
+
switch (type) {
case FL_COMBOX_DROPLIST:
{
fl_set_object_color(obj, FL_MCOL, FL_MCOL);
fl_set_object_dblbuffer(obj, 1);
fl_set_object_callback(obj, C_Combox_combo_cb, 0);
- label = obj = fl_add_button(FL_NORMAL_TEXT, x, y, w-22, hmin, "");
+ label = obj = fl_add_button(FL_NORMAL_TEXT, x, y, w-22, hmin, "");
fl_set_object_boxtype(obj, FL_DOWN_BOX);
fl_set_object_color(obj, FL_MCOL, FL_BLACK);
fl_set_object_lalign(obj, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
FL_FORM * current_form = fl_current_form;
fl_end_form();
- bw = w + 20; bh = hmax - hmin - 12;
+ bw = w + 20;
+ bh = hmax - hmin - 12;
form = fl_bgn_form(FL_NO_BOX, bw, bh);
browser = obj = fl_add_browser(FL_HOLD_BROWSER, 0, 0, bw, bh, "");
fl_end_form();
browser->u_vdata = this;
form->u_vdata = browser;
- fl_register_raw_callback(form,
+ fl_register_raw_callback(form,
ButtonPressMask|KeyPressMask,
C_Combox_peek_event);
} // namespace anon
-void Combox::Redraw()
+void Combox::redraw()
{
if (browser) fl_redraw_object(browser);
if (button) fl_redraw_object(button);
if (label) fl_redraw_object(label);
}
-
-void Combox::Show()
+
+void Combox::show()
{
if (_pre) _pre();
-
+
int tmp;
XGetInputFocus(fl_get_display(), &save_window, &tmp); //BUG-Fix Dietmar
XFlush(fl_get_display());
if (button && type != FL_COMBOX_NORMAL) {
- fl_set_object_label(button, "@2<-");
+ fl_set_object_label(button, "@2<-");
fl_redraw_object(button);
}
- int x = label->x;
- int y = label->y + label->h;
- if (tabfolder1) {
- // This is a bug work around suggested by Steve Lamont on the
- // xforms mailing list. It correctly positions the browser form
- // after the main window has been moved.
- // The bug only occurs in tabbed folders.
- int folder_x, folder_y, folder_w, folder_h;
- fl_get_folder_area( tabfolder1,
- &folder_x, &folder_y,
- &folder_w, &folder_h );
- x += folder_x;
- y += folder_y;
-
- if (tabfolder2) {
- fl_get_folder_area( tabfolder2,
- &folder_x, &folder_y,
- &folder_w, &folder_h );
- x += tabfolder2->form->x + folder_x;
- y += tabfolder2->form->y + folder_y;
- } else {
- x += tabfolder1->form->x;
- y += tabfolder1->form->y;
- }
-
- } else {
- x += label->form->x;
- y += label->form->y;
+ // This fix ensures that, even if label lies on a tabfolder,
+ // the x,y coords of the underlying form are up to date.
+ // It should be rendered redundant by a similar fix in the
+ // tabfolder prehandler, but apparently "enter" events are not always
+ // caught...
+ // Angus 4 Oct, 2002.
+ if (label->form->window) {
+ FL_FORM * lf = label->form;
+ fl_get_winorigin(lf->window, &(lf->x), &(lf->y));
}
+ int const x = label->form->x + label->x;
+ int const y = label->form->y + label->y + label->h;
+
fl_set_form_position(form, x, y);
fl_show_form(form, FL_PLACE_POSITION, FL_NOBORDER, "");
- if (sel>0) {
+ if (sel > 0) {
fl_set_browser_topline(browser, sel);
fl_select_browser_line(browser, sel);
}
XFlush(fl_get_display());
}
-void Combox::Hide(int who)
-{
+void Combox::hide(int who)
+{
if (!who && browser && label) {
sel = fl_get_browser(browser);
-
+
if (type == FL_COMBOX_INPUT)
fl_set_input(label, fl_get_browser_line(browser, sel));
else
fl_set_object_label(label,
- fl_get_browser_line(browser, sel));
+ fl_get_browser_line(browser, sel));
// if (callback) callback(sel, cb_arg);
}
- XUngrabPointer(fl_get_display(), 0);
+ XUngrabPointer(fl_get_display(), 0);
XFlush(fl_get_display());
- if (!who && browser && label && callback)
- callback(sel, cb_arg, this);
- if (form) {
+ if (form) {
fl_hide_form(form);
XSetInputFocus(fl_get_display(), save_window,
RevertToParent, CurrentTime); // BUG-FIX-Dietmar
XFlush(fl_get_display());
- }
+ }
if (button) {
- if (type != FL_COMBOX_NORMAL){
+ if (type != FL_COMBOX_NORMAL) {
fl_set_object_label(button, "@2->");
fl_redraw_object(button);
}
- }
- if (_post) _post();
+ }
+ if (!who && browser && label && callback)
+ callback(sel, cb_arg, this);
+ if (_post) _post();
}
void Combox::activate()
{
- if (browser) fl_activate_object(browser);
- if (button) fl_activate_object(button);
- if (label) fl_activate_object(label);
+ if (browser)
+ fl_activate_object(browser);
+ if (button) {
+ fl_activate_object(button);
+ fl_set_object_lcol(button, FL_BLACK);
+ }
+ if (label) {
+ fl_activate_object(label);
+ fl_set_object_lcol(label, FL_BLACK);
+ }
}
void Combox::deactivate()
{
- if (browser) fl_deactivate_object(browser);
- if (button) fl_deactivate_object(button);
- if (label) fl_deactivate_object(label);
+ if (browser)
+ fl_deactivate_object(browser);
+ if (button) {
+ fl_deactivate_object(button);
+ fl_set_object_lcol(button, FL_INACTIVE);
+ }
+ if (label) {
+ fl_deactivate_object(label);
+ fl_set_object_lcol(label, FL_INACTIVE);
+ }
}
}
-extern "C" void C_Combox_input_cb(FL_OBJECT * ob, long data)
-{
- Combox::input_cb(ob, data);
-}
-
-
void Combox::combo_cb(FL_OBJECT * ob, long data)
{
Combox * combo = static_cast<Combox*>(ob->u_vdata);
switch (data) {
case 0:
- {
+ {
int const i = combo->get();
switch (fl_get_button_numb(ob)) {
- case 2:
+ case 2:
{
- combo->select(i - 1);
+ combo->select(i - 1);
if (combo->callback)
combo->callback(combo->sel,
combo->cb_arg, combo);
break;
}
- case 3:
+ case 3:
{
- combo->select(i + 1);
+ combo->select(i + 1);
if (combo->callback)
combo->callback(combo->sel,
combo->cb_arg, combo);
break;
}
- default: combo->Show(); break;
+ default: combo->show(); break;
}
break;
}
case 2:
- combo->Hide();
+ combo->hide();
break;
}
}
-extern "C" void C_Combox_combo_cb(FL_OBJECT * ob, long data)
-{
- Combox::combo_cb(ob, data);
-}
-
int Combox::peek_event(FL_FORM * form, void * xev)
{
FL_OBJECT * ob = static_cast<FL_OBJECT *>(form->u_vdata);
Combox * combo = static_cast<Combox*>(ob->u_vdata);
-
- // I don't know why belowmouse does not work, but it doesn't. (Asger)
- // Are we sure? Please verify. (Lgb)
+
+ // below mouse does not work like we need it
if (static_cast<XEvent *>(xev)->type == ButtonPress && (
static_cast<XEvent *>(xev)->xbutton.x - ob->x < 0 ||
static_cast<XEvent *>(xev)->xbutton.x - ob->x > ob->w ||
static_cast<XEvent *>(xev)->xbutton.y - ob->y < 0 ||
static_cast<XEvent *>(xev)->xbutton.y - ob->y > ob->h)) {
- combo->Hide(1);
+ combo->hide(1);
return 1;
}
-
+
if (static_cast<XEvent*>(xev)->type != KeyPress) return 0;
-
+
char s_r[10]; s_r[9] = '\0';
KeySym keysym_return;
- XLookupString(&static_cast<XEvent*>(xev)->xkey, s_r, 10,
+ XLookupString(&static_cast<XEvent*>(xev)->xkey, s_r, 10,
&keysym_return, 0);
XFlush(fl_get_display());
switch (keysym_return) {
case XK_Down:
+#ifdef XK_KP_Down
+ case XK_KP_Down:
+#endif
if (fl_get_browser(combo->browser) <
fl_get_browser_maxline(combo->browser))
fl_select_browser_line(combo->browser,
fl_get_browser(combo->browser)+1);
- if (fl_get_browser(combo->browser)>=
+ if (fl_get_browser(combo->browser)>=
fl_get_browser_topline(combo->browser) +
fl_get_browser_screenlines(combo->browser))
fl_set_browser_topline(combo->browser,
fl_get_browser_topline(combo->browser))
fl_set_browser_topline(combo->browser,
fl_get_browser(combo->browser));
- return 1;
+ return 1;
case XK_Up:
+#ifdef XK_KP_Up
+ case XK_KP_Up:
+#endif
if (fl_get_browser(combo->browser) > 1)
fl_select_browser_line(combo->browser,
fl_get_browser(combo->browser)-1);
- if (fl_get_browser(combo->browser)>=
+ if (fl_get_browser(combo->browser)>=
fl_get_browser_topline(combo->browser) +
fl_get_browser_screenlines(combo->browser))
fl_set_browser_topline(combo->browser,
fl_get_browser(combo->browser));
return 1;
case XK_Return:
- combo->Hide();
+#ifdef XK_KP_Enter
+ case XK_KP_Enter:
+#endif
+ combo->hide();
return 1;
case XK_Escape:
- combo->Hide(1);
+ combo->hide(1);
return 1;
}
- return 0;
-}
-
-extern "C" int C_Combox_peek_event(FL_FORM * form, void *xev)
-{
- return Combox::peek_event(form, xev);
+ return 0;
}
Combox combo(FL_COMBOX_INPUT);
FD_test *fd_test;
-
+
FD_test *create_form_test(void)
{
FL_OBJECT *obj;
FD_test *fdui = (FD_test *) fl_calloc(1, sizeof(*fdui));
-
+
fdui->test = fl_bgn_form(FL_NO_BOX, 320, 190);
obj = fl_add_box(FL_UP_BOX, 0, 0, 320, 190, "");
obj = fl_add_box(FL_DOWN_BOX, 10, 50, 300, 110, "");
obj = fl_add_button(FL_NORMAL_BUTTON, 250, 10, 50, 30, _("Done"));
- combo.add(10, 15, 120, 25, 135);
+ combo.add(10, 15, 120, 25, 135);
fl_end_form();
return fdui;
int main(int argc, char *argv[])
{
//int n1;
-
- // Same defaults as in lyx
+
+ // Same defaults as in lyx
FL_IOPT cntl;
cntl.buttonFontSize = FL_NORMAL_SIZE;
cntl.browserFontSize = FL_NORMAL_SIZE;
cntl.choiceFontSize = FL_NORMAL_SIZE;
cntl.inputFontSize = FL_NORMAL_SIZE;
cntl.borderWidth = -2;
- fl_set_defaults(FL_PDButtonFontSize, &cntl);
- fl_set_defaults(FL_PDBrowserFontSize, &cntl);
- fl_set_defaults(FL_PDLabelFontSize, &cntl);
- fl_set_defaults(FL_PDChoiceFontSize, &cntl);
- fl_set_defaults(FL_PDInputFontSize, &cntl);
+ fl_set_defaults(FL_PDButtonFontSize, &cntl);
+ fl_set_defaults(FL_PDBrowserFontSize, &cntl);
+ fl_set_defaults(FL_PDLabelFontSize, &cntl);
+ fl_set_defaults(FL_PDChoiceFontSize, &cntl);
+ fl_set_defaults(FL_PDInputFontSize, &cntl);
fl_set_defaults(FL_PDBorderWidth, &cntl);
fl_initialize(&argc, argv, 0, 0, 0);
-
+
fd_test = create_form_test();
/* fill-in form initialization code */
combo.addline("Verbatim");
combo.setcallback(combo_cb);
// combo.select(4);
-
+
/* show the first form */
fl_show_form(fd_test->test, FL_PLACE_CENTER, FL_FULLBORDER, "test");
fl_do_forms();