* forms/form_character.fd: rearrange widget order.
+2003-04-02 Angus Leeming <leeming@lyx.org>
+
+ * combox.C:
+ * DropDown.[Ch]: removed.
+
+ * combox.[ch]:
+ * freebrowser.[ch]: replace Alejandro's Combox and John's DropDown
+ C++ code with something that can be integrated into xforms itself.
+
+ * Dialogs2.C: remove #include "combox.h".
+
+ * FormCharacter.[Ch]:
+ * forms/form_character.fd:
+ * FormDocument.[Ch]:
+ * forms/form_document.fd:
+ * FormPreferences.[Ch]:
+ * forms/form_preferences.fd:
+ * Toolbar_pimpl.[Ch]: replace code using Alejandro's Combox with
+ code using an FL_OBJECT of type FL_COMBOX.
+
+ * XMiniBuffer.[Ch]: replace John's DropDown with code using
+ FL_FREEBROWSER.
+
+ * Makefile.am: remove combox.C, DropDown.[Ch].
+ Add combox.c, freebrowser.[ch].
+
+ * forms/README:
+ * forms/fdfix.sh:
+ * forms/fdfixc.sed: update to suit the new combox code.
+
2003-04-02 Angus Leeming <leeming@lyx.org>
* FormDocument.[Ch]:
#include "Tooltips.h"
#include "xformsBC.h"
-#include "combox.h"
#include "ControlDocument.h"
#include "FormDocument.h"
+++ /dev/null
-/**
- * \file DropDown.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author John Levon
- *
- * Full author contact details are available in file CREDITS
- */
-
-#include <config.h>
-
-
-#include "DropDown.h"
-#include "xforms_helpers.h"
-
-#include FORMS_H_LOCATION
-
-#include <iostream>
-#include <cctype>
-
-#ifndef CXX_GLOBAL_CSTD
-using std::isprint;
-#endif
-
-using std::vector;
-
-
-namespace {
-
-extern "C" void C_CompletedCB(FL_OBJECT * ob, long)
-{
- DropDown * d = static_cast<DropDown*>(ob->u_vdata);
- d->completed();
-}
-
-
-extern "C" int C_PeekCB(FL_FORM * form, void *xev)
-{
- DropDown * d = static_cast<DropDown*>(form->u_vdata);
- return d->peek(static_cast<XEvent*>(xev));
-}
-
-} // namespace anon
-
-
-DropDown::DropDown(FL_OBJECT * ob)
-{
- form_ = fl_bgn_form(FL_NO_BOX, ob->w, 100);
- fl_add_box(FL_UP_BOX, 0, 0, ob->w, 100, "");
- browser_ = fl_add_browser(FL_SELECT_BROWSER, 0, 0, ob->w, 100, "");
- form_->u_vdata = this;
- browser_->u_vdata = this;
- fl_set_object_callback(browser_, C_CompletedCB, 0);
- fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_PeekCB);
- fl_end_form();
-}
-
-
-DropDown::~DropDown()
-{
- if (form_->visible)
- fl_hide_form(form_);
- fl_free_form(form_);
-}
-
-
-void DropDown::select(vector<string> const & choices, int x, int y, int w)
-{
- if (choices.empty())
- return;
-
- fl_set_form_geometry(form_, x, y - 100, w, 100);
- fl_clear_browser(browser_);
-
- vector<string>::const_iterator cit = choices.begin();
- vector<string>::const_iterator end = choices.end();
- for (; cit != end; ++cit) {
- fl_add_browser_line(browser_, cit->c_str());
- }
- fl_select_browser_line(browser_, 1);
- fl_show_form(form_, FL_PLACE_POSITION, FL_NOBORDER, "");
- XGrabPointer(fl_get_display(), form_->window, false,
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, 0, 0, 0);
- XFlush(fl_get_display());
-}
-
-
-void DropDown::line_up()
-{
- if (fl_get_browser(browser_) > 1)
- fl_select_browser_line(browser_, fl_get_browser(browser_) - 1);
- if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
- fl_get_browser_screenlines(browser_))
- fl_set_browser_topline(browser_, fl_get_browser(browser_)
- - fl_get_browser_screenlines(browser_) + 1);
- if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
- fl_set_browser_topline(browser_, fl_get_browser(browser_));
-}
-
-
-void DropDown::line_down()
-{
- if (fl_get_browser(browser_) < fl_get_browser_maxline(browser_))
- fl_select_browser_line(browser_, fl_get_browser(browser_) + 1);
- if (fl_get_browser(browser_) >= fl_get_browser_topline(browser_) +
- fl_get_browser_screenlines(browser_))
- fl_set_browser_topline(browser_, fl_get_browser(browser_)
- - fl_get_browser_screenlines(browser_) + 1);
- if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
- fl_set_browser_topline(browser_, fl_get_browser(browser_));
-}
-
-
-int DropDown::peek(XEvent * xev)
-{
- int x,y;
- unsigned int keymask;
-
- fl_get_mouse(&x, &y, &keymask);
-
- if (xev->type == ButtonPress) {
- if (!(x >= form_->x && x <= (form_->x + form_->w) &&
- y >= form_->y && y << (form_->y + form_->h))) {
- fl_hide_form(form_);
- return 1;
- }
- XUngrabPointer(fl_get_display(), CurrentTime);
- } else if (xev->type == KeyPress) {
- char s_r[10]; s_r[9] = '\0';
- KeySym keysym_return;
- XLookupString(&xev->xkey, s_r, 10, &keysym_return, 0);
- switch (keysym_return) {
- case XK_Down:
-#ifdef XK_KP_Down
- case XK_KP_Down:
-#endif
- line_down();
- return 1;
- case XK_Up:
-#ifdef XK_KP_Up
- case XK_KP_Up:
-#endif
- line_up();
- return 1;
- case XK_Return:
-#ifdef XK_KP_Enter
- case XK_KP_Enter:
-#endif
- completed();
- return 1;
- case XK_Escape:
- fl_deselect_browser(browser_);
- completed();
- return 1;
- default:
- // FIXME: if someone has a got a way to
- // convince the event to fall back to the
- // minibuffer, I'm glad to hear it.
- // fl_XPutBackEvent() doesn't work.
-
- // This is a bit less elegant perhaps, but works
- // well enough. Angus 11 Jan 2002
- if (s_r[0] && isprint(s_r[0])) {
- key_pressed(s_r[0]);
- return 1;
- }
- }
- }
- return 0;
-}
-
-
-void DropDown::completed()
-{
- XUngrabPointer(fl_get_display(), CurrentTime);
- fl_hide_form(form_);
- result(getString(browser_));
-}
-
-
-void DropDown::key_pressed(char c)
-{
- XUngrabPointer(fl_get_display(), CurrentTime);
- fl_hide_form(form_);
- keypress(c);
-}
+++ /dev/null
-// -*- C++ -*-
-/**
- * \file DropDown.h
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author John Levon
- *
- * Full author contact details are available in file CREDITS
- */
-
-#ifndef DROPDOWN_H
-#define DROPDOWN_H
-
-
-#include "forms_fwd.h"
-#include <X11/Xlib.h>
-
-#include <boost/signals/signal1.hpp>
-
-#include "LString.h"
-#include <vector>
-
-class DropDown {
-public:
- /// constructor
- DropDown(FL_OBJECT * ob);
- /// destructor
- ~DropDown();
-
- /// choose from the list of choices.
- void select(std::vector<string> const & choices, int x, int y, int w);
-
- /// user completed action
- void completed();
-
- /// a key was pressed. Act on it.
- void key_pressed(char c);
-
- /// signal for completion
- boost::signal1<void, string const &> result;
-
- /// signal that a key was pressed
- boost::signal1<void, char> keypress;
-
- /// X event
- int peek(XEvent *);
-
-private:
- /// move up a browser line
- void line_up();
-
- /// move down a browser line
- void line_down();
-
- /// our form
- FL_FORM * form_;
-
- /// the browser
- FL_OBJECT * browser_;
-};
-
-#endif // DROPDOWN_H
#include "FormCharacter.h"
#include "forms/form_character.h"
#include "gettext.h"
-#include "combox.h"
#include "helper_funcs.h"
#include "xforms_helpers.h"
#include FORMS_H_LOCATION
+#include "combox.h"
#include "frnt_lang.h"
{}
-void FormCharacter::ComboInputCB(int, void * v, Combox *)
-{
- FormCharacter * pre = static_cast<FormCharacter*>(v);
- // must use input() directly, to avoid treating the Combox
- // as an FL_OBJECT, leading to a crash (bug 406)
- pre->bc().input(pre->input(0, 0));
-}
-
void FormCharacter::build()
{
dialog_.reset(build_character(this));
choice = ' ' + getStringFromVector(getFirst(color), " | ") + ' ';
fl_addto_choice(dialog_->choice_color, choice.c_str());
- // xforms appears to need this to prevent a crash...
- fl_addto_choice(dialog_->choice_language, "prevent crash");
-
- // insert default language box manually
- fl_addto_form(dialog_->form);
- FL_OBJECT * ob = dialog_->choice_language;
- fl_hide_object(dialog_->choice_language);
-
- combo_language2_.reset(new Combox(FL_COMBOX_DROPLIST));
- combo_language2_->add(ob->x, ob->y, ob->w, ob->h, 250);
- combo_language2_->shortcut("#L", 1);
- combo_language2_->setcallback(ComboInputCB, this);
- fl_end_form();
-
- // build up the combox entries
- vector<LanguagePair>::const_iterator it = langs.begin();
- vector<LanguagePair>::const_iterator end = langs.end();
- for (; it != end; ++it) {
- combo_language2_->addto(it->first);
- }
- combo_language2_->select(1);
+ choice = ' ' + getStringFromVector(getFirst(langs), " | ") + ' ';
+ fl_addto_combox(dialog_->combox_language, choice.c_str());
+ fl_set_combox_browser_height(dialog_->combox_language, 250);
// Manage the ok, apply and cancel/close buttons
bcview().setApply(dialog_->button_apply);
pos = fl_get_choice(dialog_->choice_color);
controller().setColor(color_[pos - 1]);
- pos = combo_language2_->get();
+ pos = fl_get_combox(dialog_->combox_language);
controller().setLanguage(lang_[pos - 1]);
bool const toggleall = fl_get_button(dialog_->check_toggle_all);
fl_set_choice(dialog_->choice_color, pos+1);
pos = int(findPos(lang_, controller().getLanguage()));
- combo_language2_->select(pos+1);
+ fl_set_combox(dialog_->combox_language, pos+1);
fl_set_button(dialog_->check_toggle_all, controller().getToggleAll());
}
if (color_[pos - 1] != LColor::ignore)
activate = ButtonPolicy::SMI_VALID;
- pos = combo_language2_->get();
+ pos = fl_get_combox(dialog_->combox_language);
if (lang_[pos - 1] != "No change")
activate = ButtonPolicy::SMI_VALID;
#include "LColor.h" // for LColor enum
#include "character.h" // for FONT_STATE enum
-#include <boost/scoped_ptr.hpp>
-
-class Combox;
struct FD_character;
/**
/// Filter the inputs on callback from xforms
virtual ButtonPolicy::SMInput input(FL_OBJECT *, long);
- /** Callback method (used only to activate Apply button when
- combox is changed */
- static void ComboInputCB(int, void *, Combox *);
-
- ///
- boost::scoped_ptr<Combox> combo_language2_;
///
std::vector<LyXFont::FONT_FAMILY> family_;
///
#include "bmtable.h"
#include "checkedwidgets.h"
-#include "combox.h"
#include "input_validators.h" // fl_unsigned_float_filter
#include "xforms_helpers.h"
#include XPM_H_LOCATION
#include FORMS_H_LOCATION
+#include "combox.h"
#include <boost/bind.hpp>
class_.reset(build_document_class(this));
// disable for read-only documents
+ bcview().addReadOnly(class_->combox_doc_class);
bcview().addReadOnly(class_->radio_doc_indent);
bcview().addReadOnly(class_->radio_doc_skip);
bcview().addReadOnly(class_->choice_doc_pagestyle);
FL_OBJECT * obj;
- // the class list is a combo-box and has to be inserted manually
- obj = class_->choice_doc_class;
- fl_deactivate_object(obj);
- fl_addto_form(class_->form);
- combo_doc_class.reset(new Combox(FL_COMBOX_DROPLIST));
- combo_doc_class->add(obj->x, obj->y, obj->w, obj->h, 400);
- combo_doc_class->shortcut("#C",1);
- combo_doc_class->setcallback(ComboInputCB, this);
- fl_end_form();
- for (LyXTextClassList::const_iterator cit = textclasslist.begin();
- cit != textclasslist.end(); ++cit) {
- combo_doc_class->addto(cit->description());
+ // Fill the combox and choices.
+ obj = class_->combox_doc_class;
+ LyXTextClassList::const_iterator tit = textclasslist.begin();
+ LyXTextClassList::const_iterator tend = textclasslist.end();
+ for (; tit != tend; ++tit) {
+ fl_addto_combox(obj, tit->description().c_str());
}
+ fl_set_combox_browser_height(obj, 400);
fl_addto_choice(class_->choice_doc_spacing,
_(" Single | OneHalf | Double | Custom "));
language_.reset(build_document_language(this));
// disable for read-only documents
+ bcview().addReadOnly(language_->combox_language);
bcview().addReadOnly(language_->choice_inputenc);
bcview().addReadOnly(language_->choice_quotes_language);
bcview().addReadOnly(language_->radio_single);
// Store the identifiers for later
lang_ = getSecond(langs);
- // The language is a combo-box and has to be inserted manually
- obj = language_->choice_language;
- fl_deactivate_object(obj);
- fl_addto_form(language_->form);
- combo_language.reset(new Combox(FL_COMBOX_DROPLIST));
- combo_language->add(obj->x, obj->y, obj->w, obj->h, 400);
- combo_language->shortcut("#L",1);
- combo_language->setcallback(ComboInputCB, this);
- fl_end_form();
-
vector<frnt::LanguagePair>::const_iterator lit = langs.begin();
vector<frnt::LanguagePair>::const_iterator lend = langs.end();
for (; lit != lend; ++lit) {
- combo_language->addto(lit->first);
+ fl_addto_combox(language_->combox_language,
+ lit->first.c_str());
}
- combo_language->select(1);
+ fl_set_combox_browser_height(language_->combox_language, 400);
fl_addto_choice(language_->choice_quotes_language,
_(" ``text'' | ''text'' | ,,text`` | ,,text'' |"
setEnabled(class_->input_doc_spacing,
fl_get_choice(class_->choice_doc_spacing) == 4);
+ } else if (ob == class_->combox_doc_class) {
+ CheckChoiceClass();
} else if (ob == class_->radio_doc_skip ||
ob == class_->radio_doc_indent ||
ob == class_->choice_doc_skip) {
} else if (ob == dialog_->button_reset_defaults) {
BufferParams & params = controller().params();
- params.textclass = combo_doc_class->get() - 1;
+ params.textclass = fl_get_combox(class_->combox_doc_class) - 1;
params.useClassDefaults();
UpdateLayoutDocument(params);
}
-void FormDocument::ComboInputCB(int, void * v, Combox * combox)
-{
- FormDocument * pre = static_cast<FormDocument*>(v);
- if (combox == pre->combo_doc_class.get())
- pre->CheckChoiceClass();
- pre->bc().valid();
-}
-
-
bool FormDocument::class_apply(BufferParams ¶ms)
{
bool redo = false;
params.fontsize = getString(class_->choice_doc_fontsize);
params.pagestyle = getString(class_->choice_doc_pagestyle);
- params.textclass = combo_doc_class->get() - 1;
+ params.textclass = fl_get_combox(class_->combox_doc_class) - 1;
BufferParams::PARSEP tmpsep = params.paragraph_separation;
if (fl_get_button(class_->radio_doc_indent))
else
params.quotes_times = InsetQuotes::DoubleQ;
- int const pos = combo_language->get();
+ int const pos = fl_get_combox(language_->combox_language);
Language const * new_language = languages.getLanguage(lang_[pos-1]);
if (!new_language)
new_language = default_language;
/* update the bullet settings */
BufferParams & buf_params = controller().params();
- // a little bit of loop unrolling
- params.user_defined_bullets[0] = buf_params.temp_bullets[0];
- params.user_defined_bullets[1] = buf_params.temp_bullets[1];
- params.user_defined_bullets[2] = buf_params.temp_bullets[2];
- params.user_defined_bullets[3] = buf_params.temp_bullets[3];
+ for (int i = 0; i < 4; ++i) {
+ params.user_defined_bullets[i] = buf_params.temp_bullets[i];
+ }
}
LyXTextClass const & tclass = textclasslist[params.textclass];
- combo_doc_class->select(tclass.description());
+ fl_set_combox(class_->combox_doc_class, params.textclass + 1);
fl_clear_choice(class_->choice_doc_fontsize);
fl_addto_choice(class_->choice_doc_fontsize, "default");
fl_addto_choice(class_->choice_doc_fontsize,
return;
int const pos = int(findPos(lang_, params.language->lang()));
- combo_language->select(pos+1);
+ fl_set_combox(language_->combox_language, pos+1);
fl_set_choice_text(language_->choice_inputenc, params.inputenc.c_str());
fl_set_choice(language_->choice_quotes_language, params.quotes_language + 1);
void FormDocument::checkReadOnly()
{
if (bc().readOnly(controller().bufferIsReadonly())) {
- combo_doc_class->deactivate();
- combo_language->deactivate();
postWarning(_("Document is read-only."
" No changes to layout permitted."));
} else {
- combo_doc_class->activate();
- combo_language->activate();
clearMessage();
}
}
{
BufferParams & params = controller().params();
- lyx::textclass_type const tc = combo_doc_class->get() - 1;
+ lyx::textclass_type const tc =
+ fl_get_combox(class_->combox_doc_class) - 1;
if (controller().loadTextclass(tc)) {
params.textclass = tc;
} else {
int const revert = int(params.textclass);
- combo_doc_class->select(revert + 1);
+ fl_set_combox(class_->combox_doc_class, revert + 1);
}
}
class ControlDocument;
-class Combox;
class BufferParams;
struct FD_document;
class FormDocument : public FormCB<ControlDocument, FormDB<FD_document> > {
public:
FormDocument();
- ///
- static void ComboInputCB(int, void *, Combox *);
private:
/** Redraw the form (on receipt of a Signal indicating, for example,
that the xforms colours have been re-mapped). */
///
FL_OBJECT * fbullet;
///
- boost::scoped_ptr<Combox> combo_language;
- ///
- boost::scoped_ptr<Combox> combo_doc_class;
- ///
std::vector<string> lang_;
};
#include "xformsBC.h"
#include "ButtonController.h"
-#include "combox.h"
#include "Color.h"
#include "input_validators.h"
#include "forms_gettext.h"
#include <boost/bind.hpp>
#include FORMS_H_LOCATION
+#include "combox.h"
+
#include <utility>
#include <iomanip>
#include <X11/Xlib.h>
void FormPreferences::Language::apply(LyXRC & rc)
{
- int const pos = combo_default_lang->get();
+ int const pos = fl_get_combox(dialog_->combox_default_lang);
rc.default_language = lang_[pos-1];
int button = fl_get_button(dialog_->check_use_kbmap);
vector<frnt::LanguagePair> const langs = frnt::getLanguageData(false);
lang_ = getSecond(langs);
- // The default_language is a combo-box and has to be inserted manually
- fl_freeze_form(dialog_->form);
- fl_addto_form(dialog_->form);
-
- FL_OBJECT * obj = dialog_->choice_default_lang;
- fl_deactivate_object(dialog_->choice_default_lang);
- combo_default_lang.reset(new Combox(FL_COMBOX_DROPLIST));
- combo_default_lang->add(obj->x, obj->y, obj->w, obj->h, 400);
- combo_default_lang->shortcut("#L",1);
- combo_default_lang->setcallback(ComboCB, &parent_);
-
+ FL_OBJECT * obj = dialog_->combox_default_lang;
vector<frnt::LanguagePair>::const_iterator lit = langs.begin();
vector<frnt::LanguagePair>::const_iterator lend = langs.end();
for (; lit != lend; ++lit) {
- combo_default_lang->addto(lit->first);
+ fl_addto_combox(obj, lit->first.c_str());
}
- combo_default_lang->select(1);
-
- fl_end_form();
- fl_unfreeze_form(dialog_->form);
+ fl_set_combox_browser_height(obj, 400);
// set up the feedback mechanism
setPrehandler(dialog_->input_package);
setPrehandler(dialog_->check_use_kbmap);
-
- // This is safe, as nothing is done to the pointer, other than
- // to use its address in a block-if statement.
- // No it's not! Leads to crash.
- // setPrehandler(
- // reinterpret_cast<FL_OBJECT *>(combo_default_lang),
- // C_FormPreferencesFeedbackCB);
-
+ setPrehandler(dialog_->combox_default_lang);
setPrehandler(dialog_->input_kbmap1);
setPrehandler(dialog_->input_kbmap2);
setPrehandler(dialog_->check_rtl_support);
string const
FormPreferences::Language::feedback(FL_OBJECT const * const ob) const
{
- if (reinterpret_cast<Combox const *>(ob) == combo_default_lang.get())
+ if (ob == dialog_->combox_default_lang)
return LyXRC::getDescription(LyXRC::RC_DEFAULT_LANGUAGE);
if (ob == dialog_->check_use_kbmap)
return LyXRC::getDescription(LyXRC::RC_KBMAP);
rc.use_kbmap);
int const pos = int(findPos(lang_, rc.default_language));
- combo_default_lang->select(pos + 1);
+ fl_set_combox(dialog_->combox_default_lang, pos + 1);
if (rc.use_kbmap) {
fl_set_input(dialog_->input_kbmap1,
}
-void FormPreferences::Language::ComboCB(int, void * v, Combox * combox)
-{
- FormPreferences * pre = static_cast<FormPreferences*>(v);
- // This is safe, as nothing is done to the pointer, other than
- // to use its address in a block-if statement.
- pre->bc().valid(pre->input(reinterpret_cast<FL_OBJECT *>(combox), 0));
-}
-
-
FormPreferences::LnFmisc::LnFmisc(FormPreferences & p)
: parent_(p)
{}
class ControlPrefs;
-class Combox;
class Dialogs;
class LyXView;
class RGBColor;
bool input(FL_OBJECT const * const);
///
void update(LyXRC const & rc);
- ///
- static void ComboCB(int, void *, Combox *);
private:
///
///
boost::scoped_ptr<FD_preferences_language> dialog_;
///
- boost::scoped_ptr<Combox> combo_default_lang;
- ///
std::vector<string> lang_;
};
///
bmtable.h \
checkedwidgets.C \
checkedwidgets.h \
- combox.C \
+ combox.c \
combox.h \
+ freebrowser.c \
+ freebrowser.h \
fdesign_base.C \
fdesign_base.h \
input_validators.C \
ColorHandler.h \
Dialogs.C \
Dialogs2.C \
- DropDown.h \
- DropDown.C \
FileDialog.C \
FontInfo.C \
FontInfo.h \
#include "Tooltips.h"
#include FORMS_H_LOCATION
#include "combox.h"
+#include "xforms_helpers.h"
+
#include "ToolbarDefaults.h"
#include "LyXAction.h"
Toolbar::Pimpl::Pimpl(LyXView * o, int x, int y)
- : owner_(static_cast<XFormsView *>(o)), xpos(x), ypos(y)
+ : owner_(static_cast<XFormsView *>(o)), combox_(0), xpos(x), ypos(y)
{
- combox_ = 0;
tooltip_ = new Tooltips();
}
//toollist.clear();
toollist_.erase(toollist_.begin(), toollist_.end());
- delete combox_;
-
fl_unfreeze_form(owner_->getForm());
delete tooltip_;
}
ToolbarList::const_iterator end = toollist_.end();
for (; p != end; ++p) {
if (p->action == ToolbarDefaults::LAYOUTS && combox_) {
- if (owner_->getLyXFunc().getStatus(LFUN_LAYOUT).disabled())
- combox_->deactivate();
- else
- combox_->activate();
+ LyXFunc const & lf = owner_->getLyXFunc();
+ bool const disable =
+ lf.getStatus(LFUN_LAYOUT).disabled();
+ setEnabled(combox_, !disable);
continue;
}
}
-// this one is not "C" because combox callbacks are really C++ %-|
-void Toolbar::Pimpl::layoutSelectedCB(int, void * arg, Combox *)
+namespace {
+
+void C_layoutSelectedCB(FL_OBJECT * ob, long)
{
- reinterpret_cast<Toolbar::Pimpl *>(arg)->layoutSelected();
+ if (!ob || !ob->u_vdata)
+ return;
+ Toolbar::Pimpl * ptr = static_cast<Toolbar::Pimpl *>(ob->u_vdata);
+ ptr->layoutSelected();
}
+} // namespace anon
+
void Toolbar::Pimpl::layoutSelected()
{
- string const & layoutguiname = combox_->getline();
+ if (!combox_)
+ return;
+
+ string const & layoutguiname = getString(combox_);
LyXTextClass const & tc =
owner_->buffer()->params.getLyXTextClass();
void Toolbar::Pimpl::setLayout(string const & layout)
{
- if (combox_) {
- LyXTextClass const & tc =
- owner_->buffer()->params.getLyXTextClass();
- combox_->select(_(tc[layout]->name()));
+ if (!combox_)
+ return;
+
+ LyXTextClass const & tc = owner_->buffer()->params.getLyXTextClass();
+ string const layoutname = _(tc[layout]->name());
+
+ int const nnames = fl_get_combox_maxitems(combox_);
+ for (int i = 1; i <= nnames; ++i) {
+ string const name = fl_get_combox_line(combox_, i);
+ if (name == layoutname) {
+ fl_set_combox(combox_, i);
+ break;
+ }
}
}
void Toolbar::Pimpl::updateLayoutList(bool force)
{
- // Update the layout display
- if (!combox_) return;
+ if (!combox_)
+ return;
// If textclass is different, we need to update the list
- if (combox_->empty() || force) {
- combox_->clear();
+ if (fl_get_combox_maxitems(combox_) == 0 || force) {
+ fl_clear_combox(combox_);
LyXTextClass const & tc =
owner_->buffer()->params.getLyXTextClass();
LyXTextClass::const_iterator end = tc.end();
for (LyXTextClass::const_iterator cit = tc.begin();
cit != end; ++cit) {
// ignore obsolete entries
- if ((*cit)->obsoleted_by().empty())
- combox_->addline(_((*cit)->name()));
+ if ((*cit)->obsoleted_by().empty()) {
+ string const & name = _((*cit)->name());
+ fl_addto_combox(combox_, name.c_str());
+ }
}
}
// we need to do this.
- combox_->redraw();
+ fl_redraw_object(combox_);
}
void Toolbar::Pimpl::clearLayoutList()
{
- if (combox_) {
- combox_->clear();
- combox_->redraw();
- }
+ if (!combox_)
+ return;
+
+ fl_clear_combox(combox_);
+ fl_redraw_object(combox_);
}
void Toolbar::Pimpl::openLayoutList()
{
- if (combox_)
- combox_->show();
+ if (!combox_)
+ return;
+
+ fl_show_combox_browser(combox_);
}
void Toolbar::Pimpl::add(int action)
{
- FL_OBJECT * obj;
-
toolbarItem item;
item.action = action;
break;
case ToolbarDefaults::LAYOUTS:
xpos += standardspacing;
- if (!combox_)
- combox_ = new Combox(FL_COMBOX_DROPLIST);
- combox_->add(xpos, ypos, 135, height, 400);
- combox_->setcallback(layoutSelectedCB, this);
- combox_->resize(FL_RESIZE_ALL);
- combox_->gravity(NorthWestGravity, NorthWestGravity);
+ if (combox_)
+ break;
+
+ combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
+ xpos, ypos, 135, height, "");
+ fl_set_combox_browser_height(combox_, 400);
+ fl_set_object_boxtype(combox_, FL_DOWN_BOX);
+ fl_set_object_color(combox_, FL_MCOL, FL_MCOL);
+ fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
+ fl_set_object_resize(combox_, FL_RESIZE_ALL);
+
+ combox_->u_vdata = this;
+ fl_set_object_callback(combox_, C_layoutSelectedCB, 0);
xpos += 135;
break;
- default:
+ default: {
+ FL_OBJECT * obj;
+
xpos += standardspacing;
item.icon = obj =
fl_add_pixmapbutton(FL_NORMAL_BUTTON,
*/
break;
}
+ }
toollist_.push_back(item);
}
class XFormsView;
class Tooltips;
-class Combox;
/** The LyX xforms toolbar class
*/
struct Toolbar::Pimpl {
public:
- /// called when user selects a layout from combox
- static void layoutSelectedCB(int, void *, Combox *);
-
/// create an empty toolbar
Pimpl(LyXView * o, int x, int y);
void openLayoutList();
/// Erase the layout list
void clearLayoutList();
- /// the non-static version of layoutSelectedCB
+ ///
void layoutSelected();
/// an item on the toolbar
/// tooltips manager
Tooltips * tooltip_;
/// layout combo
- Combox * combox_;
+ FL_OBJECT * combox_;
/// x position of end of toolbar
int xpos;
/// y position of end of toolbar
fl_set_form_minsize(getForm(), 50, 50);
fl_end_form();
-
- minibuffer_->dd_init();
}
#include <config.h>
#include "XMiniBuffer.h"
-#include "DropDown.h"
#include "ControlCommandBuffer.h"
+#include "freebrowser.h"
+#include "xforms_helpers.h"
#include "gettext.h"
#include "frontends/Timeout.h"
+#include "support/lstrings.h"
+
#include <boost/bind.hpp>
#include <vector>
FL_OBJECT * create_input_box(void * parent, int type,
FL_Coord, FL_Coord, FL_Coord, FL_Coord);
+FL_FREEBROWSER * create_freebrowser(void * parent);
+
+FL_OBJECT * get_freebrowser_browser(boost::shared_ptr<FL_FREEBROWSER> &);
+
} // namespace anon
info_shown_(false)
{
input_ = create_input_box(this, FL_NORMAL_INPUT, x, y, h, w);
+ freebrowser_.reset(create_freebrowser(this), fl_free_freebrowser);
+
info_timer_.reset(new Timeout(1500));
idle_timer_.reset(new Timeout(6000));
info_con = info_timer_->timeout.connect(boost::bind(&XMiniBuffer::info_timeout, this));
{}
-// thanks for nothing, xforms (recursive creation not allowed)
-void XMiniBuffer::dd_init()
+void XMiniBuffer::freebrowserCB(int action)
{
- dropdown_.reset(new DropDown(input_));
- result_con = dropdown_->result.connect(boost::bind(&XMiniBuffer::set_complete_input, this, _1));
- keypress_con = dropdown_->keypress.connect(boost::bind(&XMiniBuffer::append_char, this, _1));
+ if (action < 0 || action > 1)
+ // unrecognized action
+ return;
+
+ if (action == 0)
+ // The freebrowser has been hidden
+ return;
+
+ if (freebrowser_->last_printable) {
+ // Append this char to the current input contents
+ string input = getString(input_);
+ input += freebrowser_->last_printable;
+ fl_set_input(input_, input.c_str());
+
+ } else {
+ // Fill the input widget with the selected
+ // browser entry.
+ FL_OBJECT * browser = get_freebrowser_browser(freebrowser_);
+ string const str = getString(browser);
+
+ if (!str.empty()) {
+ // add a space so the user can type
+ // an argument immediately
+ set_input(str + ' ');
+ }
+ }
}
set_input(new_input);
+ // Fill freebrowser_'s browser with the list of
+ // available completions
+ FL_OBJECT * browser =
+ get_freebrowser_browser(freebrowser_);
+ fl_clear_browser(browser);
+ vector<string>::const_iterator cit = comp.begin();
+ vector<string>::const_iterator end = comp.end();
+ for (; cit != end; ++cit) {
+ fl_add_browser_line(browser, cit->c_str());
+ }
+ fl_select_browser_line(browser, 1);
+
+ // Set the position of the freebrowser and display it.
int x,y,w,h;
fl_get_wingeometry(fl_get_real_object_window(input_),
&x, &y, &w, &h);
x += air;
y += h - (input_->h + air);
w = input_->w;
- dropdown_->select(comp, x, y, w);
+ h = 100;
+
+ fl_show_freebrowser(freebrowser_.get(), x, y-h, w, h);
return 1;
}
case 27:
}
-void XMiniBuffer::append_char(char c)
-{
- if (!c || !isprint(c))
- return;
-
- char const * tmp = fl_get_input(input_);
- string str = tmp ? tmp : "";
-
- str += c;
-
- fl_set_input(input_, str.c_str());
-}
-
-
-void XMiniBuffer::set_complete_input(string const & str)
-{
- if (!str.empty()) {
- // add a space so the user can type
- // an argument immediately
- set_input(str + ' ');
- }
-}
-
-
void XMiniBuffer::message(string const & str)
{
if (!isEditingMode())
}
+extern "C"
+void C_freebrowserCB(FL_FREEBROWSER * fb, int action)
+{
+ if (!fb || !fb->parent)
+ return;
+
+ XMiniBuffer * ptr = static_cast<XMiniBuffer *>(fb->parent);
+ ptr->freebrowserCB(action);
+}
+
+
FL_OBJECT * create_input_box(void * parent, int type,
FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h)
{
return obj;
}
+
+FL_FREEBROWSER * create_freebrowser(void * parent)
+{
+ FL_FREEBROWSER * fb = fl_create_freebrowser(parent);
+ fb->want_printable = 1;
+ fb->callback = C_freebrowserCB;
+ return fb;
+}
+
+FL_OBJECT * get_freebrowser_browser(boost::shared_ptr<FL_FREEBROWSER> & fb)
+{
+ FL_FREEBROWSER * ptr = fb.get();
+ return ptr ? fl_get_freebrowser_browser(ptr) : 0;
+}
+
} // namespace anon
#include "LString.h"
#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/signals/connection.hpp>
-class DropDown;
+struct fl_freebrowser_;
+typedef fl_freebrowser_ FL_FREEBROWSER;
+
class ControlCommandBuffer;
class Timeout;
///
~XMiniBuffer();
- /// create drop down
- void dd_init();
-
/// repaint the minibuffer
void redraw();
/// disable event management
void freeze();
+ /// xforms callback routine
+ void freebrowserCB(int action);
+
private:
/// Are we in editing mode?
bool isEditingMode() const;
/// go back to "at rest" message
void idle_timeout();
- /**
- * Append "c" to the current input contents when the completion
- * list is displayed and has focus.
- */
- void append_char(char c);
-
- /// completion selection callback
- void set_complete_input(string const & str);
-
/// set the minibuffer content in editing mode
void set_input(string const &);
void show_info(string const & info, string const & input, bool append = true);
/// the dropdown menu
- boost::scoped_ptr<DropDown> dropdown_;
+ boost::shared_ptr<FL_FREEBROWSER> freebrowser_;
/// info timer
boost::scoped_ptr<Timeout> info_timer_;
+++ /dev/null
-/**
- * \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
- * Created and tested.
- *
- * 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
- * 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>
-
-
-#include "combox.h"
-//#include <cstring>
-
-#include "debug.h"
-
-using std::endl;
-
-// These are C wrappers around static members of Combox, used as
-// callbacks for xforms.
-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)
-{
- browser = button = 0;
- callback = 0;
- label = 0;
- cb_arg = 0;
- _pre = 0;
- _post = 0;
- sel = 0;
- form = 0;
-}
-
-
-Combox::~Combox()
-{
- // This is now handled by the XFormsView destructor (Lgb)
- // remove();
-}
-
-
-void Combox::clear()
-{
- if (browser) fl_clear_browser(browser);
- sel = 0;
- if (type == FL_COMBOX_INPUT)
- fl_set_input(label, "");
- else
- fl_set_object_label(label, "");
- is_empty = true;
-}
-
-
-void Combox::remove()
-{
- lyxerr[Debug::GUI] << "Button: " << button << endl;
- if (button) {
- fl_delete_object(button);
- fl_free_object(button);
- }
-
- lyxerr[Debug::GUI] << "Label: " << label << endl;
- if (label && label != button) {
- fl_delete_object(label);
- fl_free_object(label);
- }
-
- lyxerr[Debug::GUI] << "Form: " << form << endl;
- lyxerr[Debug::GUI] << "Browser: " << browser << endl;
- if (form && browser) {
- fl_delete_object(browser);
- fl_free_object(browser);
- fl_free_form(form);
- }
- button = 0;
- browser = 0;
- label = 0;
- form = 0;
- sel = 0;
- is_empty = true;
-}
-
-
-void Combox::addline(string const & text)
-{
- 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());
- }
- is_empty = false;
-}
-
-
-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);
- return true;
- }
- }
- return false; // t does not exist in browser
-}
-
-
-void Combox::select(int i)
-{
- if (!browser || !button) return;
- 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);
-}
-
-
-void Combox::add(int x, int y, int w, int hmin, int hmax)
-{
- FL_OBJECT * obj;
-
- switch (type) {
- case FL_COMBOX_DROPLIST:
- {
- button = obj = fl_add_button(FL_NORMAL_BUTTON,
- x+w-22, y, 22, hmin, "@2->");
- 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, "");
- 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_set_object_dblbuffer(obj, 1);
- fl_set_object_callback(obj, C_Combox_combo_cb, 0);
- break;
- }
- case FL_COMBOX_NORMAL:
- {
- button = obj = fl_add_button(FL_NORMAL_BUTTON, x, y, w, hmin, "");
- fl_set_object_color(obj, FL_MCOL, FL_MCOL);
- fl_set_object_boxtype(obj, FL_DOWN_BOX);
- fl_set_object_callback(obj, C_Combox_combo_cb, 0);
- fl_set_object_color(obj, FL_MCOL, FL_BLACK);
- label = button;
- break;
- }
- case FL_COMBOX_INPUT:
- {
- button = obj = fl_add_button(FL_NORMAL_BUTTON,
- x+w-22, y, 22, hmin, "@2->");
- fl_set_object_color(obj, FL_MCOL, FL_MCOL);
- fl_set_object_callback(obj, C_Combox_combo_cb, 0);
- label = obj = fl_add_input(FL_NORMAL_INPUT, x, y, w-22, hmin, "");
- fl_set_object_boxtype(obj, FL_DOWN_BOX);
- fl_set_object_return(obj, FL_RETURN_END_CHANGED);
- fl_set_object_callback(obj, C_Combox_input_cb, 0);
- //fl_set_object_color(obj, FL_MCOL, FL_BLACK);
- //fl_set_object_lalign(obj,FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
- break;
- }
- } // end of switch
-
- label->u_vdata = this;
- button->u_vdata = this;
-
- // Hmm, it seems fl_create_browser is broken in xforms 0.86.
- // We have to work around that by creating the dropped browser form
- // at this point already. However, this means that we have
- // to do a little hacking: (Asger)
- FL_FORM * current_form = fl_current_form;
- fl_end_form();
-
- 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_set_object_boxtype(obj, FL_UP_BOX);
- fl_set_object_color(obj, FL_MCOL, FL_YELLOW);
- fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity);
- fl_set_object_callback(obj, C_Combox_combo_cb, 2);
- fl_end_form();
- browser->u_vdata = this;
- form->u_vdata = browser;
- fl_register_raw_callback(form,
- ButtonPressMask|KeyPressMask,
- C_Combox_peek_event);
-
- // And revert to adding to the old form (Asger)
- fl_addto_form(current_form);
-}
-
-
-namespace {
-
-Window save_window;
-
-} // namespace anon
-
-
-void Combox::redraw()
-{
- if (browser) fl_redraw_object(browser);
- if (button) fl_redraw_object(button);
- if (label) fl_redraw_object(label);
-}
-
-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_redraw_object(button);
- }
-
- 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) {
- fl_set_browser_topline(browser, sel);
- fl_select_browser_line(browser, sel);
- }
- XGrabPointer(fl_get_display(), form->window, false,
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync,
- 0, 0, 0);
- XFlush(fl_get_display());
-}
-
-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));
-// if (callback) callback(sel, cb_arg);
- }
- XUngrabPointer(fl_get_display(), 0);
- XFlush(fl_get_display());
- 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) {
- fl_set_object_label(button, "@2->");
- fl_redraw_object(button);
- }
- }
- 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);
- 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);
- fl_set_object_lcol(button, FL_INACTIVE);
- }
- if (label) {
- fl_deactivate_object(label);
- fl_set_object_lcol(label, FL_INACTIVE);
- }
-}
-
-
-void Combox::input_cb(FL_OBJECT * ob, long)
-{
- Combox * combo = static_cast<Combox*>(ob->u_vdata);
-
- char const * text = fl_get_input(ob);
-
- combo->addto(text ? string(text) : string());
- combo->is_empty = false;
-}
-
-
-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:
- {
- combo->select(i - 1);
- if (combo->callback)
- combo->callback(combo->sel,
- combo->cb_arg, combo);
- break;
- }
- case 3:
- {
- combo->select(i + 1);
- if (combo->callback)
- combo->callback(combo->sel,
- combo->cb_arg, combo);
- break;
- }
- default: combo->show(); break;
- }
- break;
- }
- case 2:
- combo->hide();
- break;
- }
-}
-
-
-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);
-
- // 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);
- 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,
- &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)>=
- fl_get_browser_topline(combo->browser) +
- fl_get_browser_screenlines(combo->browser))
- fl_set_browser_topline(combo->browser,
- fl_get_browser(combo->browser)
- - fl_get_browser_screenlines(combo->browser)+1);
- if (fl_get_browser(combo->browser)<
- fl_get_browser_topline(combo->browser))
- fl_set_browser_topline(combo->browser,
- fl_get_browser(combo->browser));
- 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)>=
- fl_get_browser_topline(combo->browser) +
- fl_get_browser_screenlines(combo->browser))
- fl_set_browser_topline(combo->browser,
- fl_get_browser(combo->browser)
- - fl_get_browser_screenlines(combo->browser)+1);
- if (fl_get_browser(combo->browser) <
- fl_get_browser_topline(combo->browser))
- fl_set_browser_topline(combo->browser,
- fl_get_browser(combo->browser));
- return 1;
- case XK_Return:
-#ifdef XK_KP_Enter
- case XK_KP_Enter:
-#endif
- combo->hide();
- return 1;
- case XK_Escape:
- combo->hide(1);
- return 1;
- }
- return 0;
-}
-
-
-#ifdef TESTCOMBO
-typedef struct {
- FL_FORM *test;
- FL_OBJECT *bar;
- void *vdata;
- long ldata;
-} FD_test;
-
-//Combox combo(FL_COMBOX_DROPLIST);
-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);
- fl_end_form();
-
- return fdui;
-}
-
-void combo_cb(int i)
-{
- fprintf(stderr, "selected %d:%s\n", i, combo.getline());
-}
-
-int main(int argc, char *argv[])
-{
- //int n1;
-
- // Same defaults as in lyx
- FL_IOPT cntl;
- cntl.buttonFontSize = FL_NORMAL_SIZE;
- cntl.browserFontSize = FL_NORMAL_SIZE;
- cntl.labelFontSize = 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_PDBorderWidth, &cntl);
- fl_initialize(&argc, argv, 0, 0, 0);
-
- fd_test = create_form_test();
-
- /* fill-in form initialization code */
- combo.addline("Title");
- combo.addline("Author");
- combo.addline("Date");
- combo.addline("Abstract");
- combo.addline("Chapter");
- combo.addline("Section");
- combo.addline("Subsection");
- combo.addline("List");
- combo.addline("Description");
- combo.addline("Verse");
- 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();
- return 0;
-}
-
-#endif
--- /dev/null
+/**
+ * \file combox.c
+ *
+ * \author Alejandro Aguilar Sierra
+ * \author Angus Leeming
+ *
+ * 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 "combox.h"
+#include "freebrowser.h"
+
+
+extern void fl_add_child(FL_OBJECT *, FL_OBJECT *);
+extern void fl_addto_freelist(void *);
+
+
+typedef struct {
+ /** A pointer to the parent widget */
+ FL_OBJECT * combox;
+
+ FL_FREEBROWSER * browser;
+ int browser_height;
+
+ /** The browser will be displayed either below or above the main body. */
+ int browser_position;
+
+ /** button_state displays a down or up arrow depending on whether the
+ * browser is visible or not.
+ * Click on it to toggle the browser.
+ */
+ FL_OBJECT * button_state;
+
+ /** button_chosen displays the current selection from the browser.
+ * Click on it to toggle the browser.
+ */
+ FL_OBJECT * button_chosen;
+} COMBOX_SPEC;
+
+
+enum { ACTIVATE, DEACTIVATE };
+
+enum { COMBOX_OPEN, COMBOX_CLOSED };
+
+
+/* function declarations */
+static int combox_pre(FL_OBJECT *, int, FL_Coord, FL_Coord, int, void *);
+static int combox_post(FL_OBJECT *, int, FL_Coord, FL_Coord, int, void *);
+static int combox_handle(FL_OBJECT *, int, FL_Coord, FL_Coord, int, void *);
+
+static void update_button_chosen(FL_FREEBROWSER * fb, int action);
+static void chosen_cb(FL_OBJECT * ob, long data);
+static void state_cb(FL_OBJECT * ob, long data);
+
+static void show_browser(COMBOX_SPEC * sp);
+static void set_activation(FL_OBJECT * ob, int activation);
+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 * ob;
+ FL_OBJECT * button;
+ COMBOX_SPEC * sp;
+
+ /* The width and x-position of button_state, respectively. */
+ FL_Coord const ws = 0.7 * h;
+ FL_Coord const xs = x + w - ws;
+
+ ob = fl_make_object(FL_COMBOX, type, x, y, w, h, label, combox_handle);
+ ob->align = FL_ALIGN_LEFT;
+
+ sp = ob->spec = fl_calloc(1, sizeof(COMBOX_SPEC));
+ sp->combox = ob;
+ sp->browser_height = 100;
+ sp->browser_position = FL_FREEBROWSER_BELOW;
+
+ sp->browser = fl_create_freebrowser(sp);
+ sp->browser->callback = update_button_chosen;
+
+ 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);
+
+ 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, "");
+
+ button = sp->button_chosen;
+ fl_set_object_boxtype(button, FL_FRAME_BOX);
+ fl_set_object_lalign(button, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
+ fl_set_object_callback(button, chosen_cb, 0);
+ fl_set_object_posthandler(button, combox_post);
+ fl_set_object_prehandler(button, combox_pre);
+ set_activation(button, DEACTIVATE);
+ button->parent = ob;
+ button->u_vdata = sp;
+
+ return ob;
+}
+
+
+FL_OBJECT * fl_add_combox(int 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);
+ fl_add_child(ob, sp->button_chosen);
+
+ fl_add_object(fl_current_form, ob);
+ return ob;
+}
+
+
+void fl_set_combox_browser_height(FL_OBJECT * ob, int bh)
+{
+ COMBOX_SPEC * sp;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ sp = ob->spec;
+ sp->browser_height = bh;
+}
+
+
+void fl_set_combox_position(FL_OBJECT * ob, int position)
+{
+ COMBOX_SPEC * sp;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ sp = ob->spec;
+ sp->browser_position = (position == FL_FREEBROWSER_ABOVE) ?
+ FL_FREEBROWSER_ABOVE : FL_FREEBROWSER_BELOW;
+
+ set_state_label(sp, COMBOX_CLOSED);
+}
+
+
+void fl_clear_combox(FL_OBJECT * ob)
+{
+ COMBOX_SPEC * sp;
+ FL_OBJECT * browser;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ sp = ob->spec;
+ browser = fl_get_freebrowser_browser(sp->browser);
+
+ fl_clear_browser(browser);
+ fl_set_object_label(sp->button_chosen, "");
+}
+
+
+void fl_addto_combox(FL_OBJECT * ob, char const * text)
+{
+ COMBOX_SPEC * sp;
+ FL_OBJECT * browser;
+ int i;
+ int j;
+ char line[128];
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ sp = ob->spec;
+ browser = fl_get_freebrowser_browser(sp->browser);
+
+ /* Split the string on '|' boundaries. */
+ i = j = 0;
+ for (; text[i] != '\0'; ++i) {
+ if (text[i] == '|') {
+ line[j] = '\0';
+ fl_add_browser_line(browser, line);
+ j = 0;
+ } else {
+ line[j++] = text[i];
+ }
+ }
+
+ 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);
+ set_activation(sp->button_chosen, ACTIVATE);
+ set_activation(sp->button_state, ACTIVATE);
+ }
+}
+
+
+void fl_set_combox(FL_OBJECT * ob, int sel)
+{
+ COMBOX_SPEC * sp;
+ FL_OBJECT * browser;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ sp = ob->spec;
+ browser = fl_get_freebrowser_browser(sp->browser);
+
+ if (sel < 1 || sel > fl_get_browser_maxline(browser))
+ return;
+
+ fl_select_browser_line(browser, sel);
+ fl_set_object_label(sp->button_chosen, fl_get_browser_line(browser, sel));
+}
+
+
+int fl_get_combox(FL_OBJECT * ob)
+{
+ COMBOX_SPEC * sp;
+ FL_OBJECT * browser;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return 0;
+
+ sp = ob->spec;
+ browser = fl_get_freebrowser_browser(sp->browser);
+ return fl_get_browser(browser);
+}
+
+
+char const * fl_get_combox_text(FL_OBJECT * ob)
+{
+ COMBOX_SPEC * sp;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return 0;
+
+ sp = ob->spec;
+ return sp->button_chosen->label;
+}
+
+
+char const * fl_get_combox_line(FL_OBJECT * ob, int line)
+{
+ COMBOX_SPEC * sp;
+ FL_OBJECT * browser;
+ int maxlines;
+
+ if (line < 1 || !ob || ob->objclass != FL_COMBOX)
+ return 0;
+
+ sp = ob->spec;
+ browser = fl_get_freebrowser_browser(sp->browser);
+
+ maxlines = fl_get_browser_maxline(browser);
+ if (line > maxlines)
+ return 0;
+
+ return fl_get_browser_line(browser, line);
+}
+
+
+int fl_get_combox_maxitems(FL_OBJECT * ob)
+{
+ COMBOX_SPEC * sp;
+ FL_OBJECT * browser;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return 0;
+
+ sp = ob->spec;
+ browser = fl_get_freebrowser_browser(sp->browser);
+ return fl_get_browser_maxline(browser);
+}
+
+
+void fl_show_combox_browser(FL_OBJECT * ob)
+{
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ show_browser(ob->spec);
+}
+
+
+void fl_hide_combox_browser(FL_OBJECT * ob)
+{
+ COMBOX_SPEC * sp;
+
+ if (!ob || ob->objclass != FL_COMBOX)
+ return;
+
+ sp = ob->spec;
+ fl_free_freebrowser(sp->browser);
+}
+
+
+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;
+
+ return combox->prehandle ?
+ combox->prehandle(combox, ev, mx, my, key, xev) : 0;
+}
+
+
+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;
+
+ return combox->posthandle ?
+ combox->posthandle(combox, ev, mx, my, key, xev) : 0;
+}
+
+
+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;
+
+ switch (event) {
+ case FL_DRAW:
+ attrib_change(ob->spec);
+ /* Fall through */
+ case FL_DRAWLABEL:
+ fl_draw_object_label(ob);
+ break;
+ case FL_SHORTCUT:
+ show_browser(ob->spec);
+ break;
+ case FL_FREEMEM: {
+ COMBOX_SPEC * sp = ob->spec;
+ fl_free_freebrowser(sp->browser);
+ /* children take care of themselves, but we must make sure that
+ sp itself is free-d eventually. */
+ fl_addto_freelist(sp);
+ break;
+ }
+ }
+ return 0;
+}
+
+
+static void set_activation(FL_OBJECT * ob, int activation)
+{
+ switch (activation) {
+ case ACTIVATE:
+ fl_activate_object(ob);
+ fl_set_object_lcol(ob, FL_LCOL);
+ break;
+ case DEACTIVATE:
+ fl_deactivate_object(ob);
+ fl_set_object_lcol(ob, FL_INACTIVE);
+ }
+}
+
+
+static void show_browser(COMBOX_SPEC * sp)
+{
+ FL_OBJECT * ob = sp->combox;
+
+ /* The browser dimensions. */
+ FL_Coord const bw = ob->w + 20;
+ FL_Coord const bh = sp->browser_height;
+
+ FL_Coord const abs_x = ob->form->x + ob->x;
+
+ FL_Coord abs_y = ob->form->y + ob->y;
+ 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);
+}
+
+
+static void state_cb(FL_OBJECT * ob, long data)
+{
+ show_browser(ob->u_vdata);
+}
+
+
+static void chosen_cb(FL_OBJECT * ob, long data)
+{
+ show_browser(ob->u_vdata);
+}
+
+
+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 * combox = sp->combox;
+ if (!browser || !combox) return;
+
+ set_state_label(sp, COMBOX_CLOSED);
+
+ if (action == 1) {
+ int const sel = fl_get_browser(browser);
+ char const * const text = fl_get_browser_line(browser, sel);
+ fl_set_object_label(sp->button_chosen, text);
+ fl_call_object_callback(combox);
+ }
+}
+
+
+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->browser_position == FL_FREEBROWSER_BELOW) {
+ label = (state == COMBOX_OPEN) ? up : down;
+ } else {
+ label = (state == COMBOX_OPEN) ? down : up;
+ }
+ fl_set_object_label(sp->button_state, label);
+ fl_redraw_object(sp->button_state);
+}
+
+
+static void attrib_change(COMBOX_SPEC * sp)
+{
+ FL_OBJECT * parent = sp->combox;
+ FL_OBJECT * button = sp->button_chosen;
+
+ button->boxtype = parent->boxtype;
+ button->col1 = parent->col1;
+ button->col2 = parent->col2;
+ button->bw = parent->bw;
+
+ button = sp->button_state;
+
+ /* The boxtype is not changed */
+ button->col1 = parent->col1;
+ button->col2 = parent->col2;
+ button->bw = parent->bw;
+}
-// -*- C++ -*-
/**
* \file combox.h
- * Copyright 1996 Alejandro Aguilar Sierra
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
+ * \author Angus Leeming
*
- * \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
- * Created and tested.
- *
- * 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.
+ * A combination of two objects (a button and a browser) is encapsulated to
+ * get a combobox-like object.
*/
-#ifndef COMBOX_H
-#define COMBOX_H
-
+#ifndef FL_COMBOX_H
+#define FL_COMBOX_H
-#include FORMS_H_LOCATION
-#include <cstdlib>
-#include "LString.h"
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
-///
-enum combox_type {
- ///
- FL_COMBOX_NORMAL,
- ///
- FL_COMBOX_DROPLIST,
- ///
- FL_COMBOX_INPUT
+/** This will eventually be moved into the enum of in-built widgets
+ in forms.h. */
+enum {
+ FL_COMBOX = 200
};
-class Combox;
-
-/// callback prototype
-typedef void (*FL_COMBO_CB) (int, void *, Combox *);
-/// pre post prototype
-typedef void (*FL_COMBO_PRE_POST) ();
-
-
-///
-class Combox {
-public:
- ///
- explicit Combox(combox_type t = FL_COMBOX_NORMAL);
- ///
- ~Combox();
-
- /** To add this object to a form. Note that there are two heights
- * for normal (button) and expanded (browser) mode each.
- */
- void add(int x, int y, int w, int hmin, int hmax);
-
- /// Add lines. Same as for fl_browser object
- void addline(string const &);
- /// Add lines. Same as for fl_browser object
- void addto(string const &);
-
- /// Returns the selected item
- int get() const;
-
- /// Returns a pointer to the selected line of text
- string const getline() const;
-
- /// Select an arbitrary item
- void select(int);
- ///
- bool select(string const &);
-
- /// Clear all the list
- void clear();
-
- /// Is the combox cleared (empty)
- bool empty() const { return is_empty; }
-
- /// Remove the objects from the form they are in.
- void remove();
-
- /**
- * Assign a callback to this object. The callback should be a void
- * function with a int, a void pointer, and a Combox pointer as
- * parameters.
- */
- void setcallback(FL_COMBO_CB, void *);
-
- /// Pre handler
- void setpre(FL_COMBO_PRE_POST);
- /// Post handler
- void setpost(FL_COMBO_PRE_POST);
-
- /// XForms attributes
- void resize(unsigned);
- ///
- void gravity(unsigned, unsigned);
- ///
- void activate();
- ///
- void deactivate();
- ///
- void shortcut(string const &, int);
- ///
- void redraw();
- ///
- void show();
- ///
- static void combo_cb(FL_OBJECT *, long);
- ///
- static void input_cb(FL_OBJECT *, long);
- ///
- static int peek_event(FL_FORM *, void *);
- protected:
- /// At least Hide should not be public
- void hide(int who = 0);
- ///
- FL_OBJECT * browser;
- private:
- ///
- combox_type type;
- ///
- int bw;
- ///
- int bh;
- ///
- int sel;
- ///
- bool is_empty;
- ///
- FL_COMBO_CB callback;
- ///
- void * cb_arg;
- ///
- FL_COMBO_PRE_POST _pre;
- ///
- FL_COMBO_PRE_POST _post;
- ///
- FL_OBJECT * button;
- ///
- FL_OBJECT * label;
- ///
- FL_FORM* form;
+/** The types of combox. At the moment, there's only one. */
+enum {
+ FL_DROPLIST_COMBOX
};
+/** A function to create a combox widget.
+ * \param type is, as yet, unused. there is only one type of combox.
+ * \param x, \param y: the x,y coordinates of the upper left hand corner
+ * of the widget, relative to the parent form'd origin.
+ * \param w, \param h: the widget's dimensions.
+ * \param label: the widget's label as it appears on the GUI.
+ */
+FL_EXPORT FL_OBJECT *
+fl_create_combox(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h,
+ char const * label);
+/** A function to create a combox widget and add it to the parent form.
+ * \see fl_create_combox() for an explanation of the argument list.
+ */
+FL_EXPORT FL_OBJECT *
+fl_add_combox(int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h,
+ char const * label);
-//----------------- Inline methods ---------------------------
-
-inline
-void Combox::addto(string const & text)
-{
- if (browser) {
- fl_addto_browser(browser, text.c_str());
- is_empty = false;
- }
-}
-
-
-inline
-void Combox::resize(unsigned r)
-{
- fl_set_object_resize(button, r);
- if (label!= button) fl_set_object_resize(label, r);
-}
-
-
-inline
-void Combox::gravity(unsigned g1, unsigned g2)
-{
- fl_set_object_gravity(button, g1, g2);
- if (label!= button) fl_set_object_gravity(label, g1, g2);
-}
-
+/** The combox browser has a default height of 100 pixels. Adjust to suit. */
+FL_EXPORT void fl_set_combox_browser_height(FL_OBJECT * ob, int bh);
-inline
-void Combox::shortcut(string const & s, int i)
-{
- if (button)
- fl_set_object_shortcut(button, s.c_str(), i);
-}
+/** The browser will be displayed either below or above the button,
+ * dependent upon \param position.
+ */
+FL_EXPORT void fl_set_combox_position(FL_OBJECT * ob, int position);
+/** Empty the browser and the combox, \param ob. */
+FL_EXPORT void fl_clear_combox(FL_OBJECT * ob);
-inline
-void Combox::setcallback(FL_COMBO_CB cb, void * a = 0)
-{
- callback = cb;
- cb_arg = a;
-}
+/** Add a line to the combox browser.*/
+FL_EXPORT void fl_addto_combox(FL_OBJECT * ob, char const * text);
+/** Set the combox to return line \param choice of the combox browser. */
+FL_EXPORT void fl_set_combox(FL_OBJECT * ob, int choice);
-inline
-void Combox::setpre(FL_COMBO_PRE_POST cb)
-{
- _pre = cb;
-}
+/** \return the currently selected line of the combox browser. */
+FL_EXPORT int fl_get_combox(FL_OBJECT * ob);
+/** \return the contents of the combox.
+ * (Also the contents of currently selected line of the combox browser.)
+ */
+FL_EXPORT char const * fl_get_combox_text(FL_OBJECT * ob);
-inline
-void Combox::setpost(FL_COMBO_PRE_POST cb)
-{
- _post = cb;
-}
+/** \return the contents of \param line of the combox browser. */
+FL_EXPORT char const * fl_get_combox_line(FL_OBJECT * ob, int line);
+/** \return the number of items in the combox browser. */
+FL_EXPORT int fl_get_combox_maxitems(FL_OBJECT * ob);
-inline
-int Combox::get() const
-{
- return sel;
-}
+/** Show the browser */
+void fl_show_combox_browser(FL_OBJECT * ob);
+/** Hide the browser */
+void fl_hide_combox_browser(FL_OBJECT * ob);
-inline
-string const Combox::getline() const
-{
- if (type == FL_COMBOX_INPUT)
- return fl_get_input(label);
- else
- return (browser && sel > 0) ?
- string(fl_get_browser_line(browser, sel)) : string();
+#if defined(__cplusplus)
}
+#endif
#endif
FL_TEXT | text
The only exceptions to this are objects that are to be converted in the sed
-scripts. At the moment this applies only to bmtable:
+scripts. At the moment this applies only to bmtable and to combox:
Convert an FL_BUTTON to a FL_BMTABLE by using prefix "bmtable".
+ Convert an FL_CHOICE to a FL_COMBOX by using prefix "combox".
Enter the full name of the callback eg.:
C_FormBaseOkCB
echo "#include <config.h>" >> ${TMP}
echo "#include \"forms_gettext.h\"" >> ${TMP}
echo "#include \"gettext.h\"" >> ${TMP}
+echo "#include FORMS_H_LOCATION" >> ${TMP}
grep bmtable ${CIN} > /dev/null &&
echo "#include \"bmtable.h\"" >> ${TMP}
+grep combox ${CIN} > /dev/null &&
+ echo "#include \"combox.h\"" >> ${TMP}
sed -f ${FDFIXC} < ${CIN} >> ${TMP}
/^\/\*-----/d
-# Replace "forms.h" by FORMS_H_LOCATION in the #include directives
-s/#include \"forms\.h\"/#include FORMS_H_LOCATION/
+# Remove '#include "forms.h"'. It is replace by a macro in fdfix.sh.
+/^#include \"forms\.h\"/d
# Pretty formatting; replace all leading whitespace with a tab
/bmtable/ s/fl_add_button/fl_add_bmtable/
+# For all lines containing "combox",
+# replace "fl_add_choice" with "fl_add_combox"
+/combox/ s/fl_add_choice([^,]*/fl_add_combox(FL_DROPLIST_COMBOX/
+
+
# For all lines containing fl_add_choice,
# add a line that turns off the title. (These titles can contain meta-chars
# that just look nasty ;-)
Name: form_character
Width: 300
Height: 415
-Number of Objects: 15
+Number of Objects: 14
--------------------
class: FL_BOX
type: DROPLIST_CHOICE
box: 95 175 190 30
boxtype: FL_FRAME_BOX
-colors: FL_COL1 FL_BLACK
+colors: FL_COL1 FL_COL1
alignment: FL_ALIGN_LEFT
style: FL_NORMAL_STYLE
size: FL_NORMAL_SIZE
lcol: FL_BLACK
-label: Language:
+label: Language:|#L
shortcut:
resize: FL_RESIZE_X
gravity: FL_NorthWest FL_NorthEast
-name: choice_language
+name: combox_language
callback: C_FormDialogView_InputCB
argument: 0
---------------------
-class: FL_TEXT
-type: NORMAL_TEXT
-box: 11 170 84 40
-boxtype: FL_FLAT_BOX
-colors: FL_COL1 FL_MCOL
-alignment: FL_ALIGN_RIGHT|FL_ALIGN_INSIDE
-style: FL_NORMAL_STYLE
-size: FL_NORMAL_SIZE
-lcol: FL_BLACK
-label: Language:
-shortcut:
-resize: FL_RESIZE_ALL
-gravity: FL_NoGravity FL_NoGravity
-name:
-callback:
-argument:
-
--------------------
class: FL_CHECKBUTTON
type: PUSH_BUTTON
--------------------
class: FL_CHOICE
-type: NORMAL_CHOICE
+type: DROPLIST_CHOICE
box: 110 10 160 25
boxtype: FL_FRAME_BOX
-colors: FL_COL1 FL_BLACK
+colors: FL_COL1 FL_COL1
alignment: FL_ALIGN_LEFT
style: FL_NORMAL_STYLE
size: FL_NORMAL_SIZE
lcol: FL_BLACK
-label: Class:|#l
+label: Class:|#C
shortcut:
resize: FL_RESIZE_ALL
gravity: FL_NoGravity FL_NoGravity
-name: choice_doc_class
+name: combox_doc_class
callback: C_FormBaseInputCB
argument: 0
--------------------
class: FL_CHOICE
-type: NORMAL_CHOICE
+type: DROPLIST_CHOICE
box: 120 35 190 25
boxtype: FL_FRAME_BOX
-colors: FL_COL1 FL_BLACK
+colors: FL_COL1 FL_COL1
alignment: FL_ALIGN_LEFT
style: FL_NORMAL_STYLE
size: FL_NORMAL_SIZE
shortcut:
resize: FL_RESIZE_ALL
gravity: FL_NoGravity FL_NoGravity
-name: choice_language
+name: combox_language
callback: C_FormBaseInputCB
argument: 0
type: NORMAL_CHOICE
box: 231 56 200 30
boxtype: FL_FRAME_BOX
-colors: FL_COL1 FL_BLACK
+colors: FL_COL1 FL_COL1
alignment: FL_ALIGN_LEFT
style: FL_NORMAL_STYLE
size: FL_DEFAULT_SIZE
shortcut:
resize: FL_RESIZE_ALL
gravity: FL_NoGravity FL_NoGravity
-name: choice_default_lang
+name: combox_default_lang
callback: C_FormBaseInputCB
argument: 0
--- /dev/null
+/**
+ * \file freebrowser.c
+ *
+ * \author Alejandro Aguilar Sierra
+ * \author Angus Leeming
+ *
+ * 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 "freebrowser.h"
+#include <ctype.h> /* isprint */
+
+extern void fl_hide_tooltip(void);
+
+static void browser_cb(FL_OBJECT * ob, long data);
+
+static int peek_event(FL_FORM * form, void * xev);
+
+
+FL_FREEBROWSER * fl_create_freebrowser(void * parent)
+{
+ FL_FORM * current_form = fl_current_form;
+ FL_FREEBROWSER * fb = fl_calloc(1, sizeof(FL_FREEBROWSER));
+ FL_OBJECT * ob;
+
+ /* Default size */
+ FL_Coord const w = 100;
+ FL_Coord const h = 100;
+
+ fb->parent = parent;
+ fb->callback = 0;
+ fb->want_printable = 0;
+ fb->last_printable = 0;
+
+ if (current_form) fl_end_form();
+ fb->form = fl_bgn_form(FL_NO_BOX, w, h);
+
+ fb->form->u_vdata = fb;
+ fl_register_raw_callback(fb->form, ButtonPressMask|KeyPressMask,
+ peek_event);
+
+ ob = fb->browser = fl_add_browser(FL_HOLD_BROWSER, 0, 0, w, h, "");
+ ob->u_vdata = fb;
+ fl_set_object_boxtype(ob, FL_UP_BOX);
+ fl_set_object_color(ob, FL_MCOL, FL_YELLOW);
+ fl_set_object_gravity(ob, NorthWestGravity, SouthEastGravity);
+ fl_set_object_callback(ob, browser_cb, 0);
+ fl_end_form();
+
+ if (current_form)
+ fl_addto_form(current_form);
+
+ return fb;
+}
+
+
+void fl_free_freebrowser(FL_FREEBROWSER * fb)
+{
+ if (!fb)
+ return;
+
+ if (fb->form)
+ fl_free_form(fb->form);
+
+ fl_free(fb);
+ fb = 0;
+}
+
+
+void fl_show_freebrowser(FL_FREEBROWSER * fb,
+ FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h)
+{
+ int tmp;
+ int const pos = fl_get_browser(fb->browser);
+
+ fl_set_form_geometry(fb->form, x, y, w, h);
+
+ XGetInputFocus(fl_get_display(), &fb->save_window, &tmp);
+ XFlush(fl_get_display());
+
+ fl_show_form(fb->form, FL_PLACE_POSITION, FL_NOBORDER, "");
+
+ fl_select_browser_line(fb->browser, pos);
+ fl_set_browser_topline(fb->browser, pos);
+
+ XGrabPointer(fl_get_display(), fb->form->window, 0,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ 0, 0, 0);
+ XFlush(fl_get_display());
+
+ fl_hide_tooltip();
+}
+
+
+void fl_hide_freebrowser(FL_FREEBROWSER * fb)
+{
+ XUngrabPointer(fl_get_display(), 0);
+ XFlush(fl_get_display());
+
+ if (fb->form->visible)
+ fl_hide_form(fb->form);
+
+ XSetInputFocus(fl_get_display(), fb->save_window,
+ RevertToParent, CurrentTime);
+ XFlush(fl_get_display());
+
+ if (fb->callback)
+ fb->callback(fb, 0);
+}
+
+
+FL_OBJECT * fl_get_freebrowser_browser(FL_FREEBROWSER * fb)
+{
+ return fb->browser;
+}
+
+
+static void browser_cb(FL_OBJECT * ob, long data)
+{
+ FL_FREEBROWSER * fb = ob->u_vdata;
+ fl_hide_freebrowser(fb);
+ if (fb->callback)
+ fb->callback(fb, 1);
+}
+
+
+static int peek_event(FL_FORM * form, void * ev)
+{
+ XEvent * xev = ev;
+ FL_FREEBROWSER * fb = form->u_vdata;
+ FL_OBJECT * browser = fb->browser;
+
+ fb->last_printable = 0;
+ fl_hide_tooltip();
+
+ if (xev->type == ButtonPress &&
+ ((int)(xev->xbutton.x) - (int)(browser->x) < 0 ||
+ (int)(xev->xbutton.x) - (int)(browser->x) > (int)(browser->w) ||
+ (int)(xev->xbutton.y) - (int)(browser->y) < 0 ||
+ (int)(xev->xbutton.y) - (int)(browser->y) > (int)(browser->h))) {
+ fl_hide_freebrowser(fb);
+ return 1;
+ }
+
+ if (xev->type == KeyPress) {
+ char s_r[10]; s_r[9] = '\0';
+ KeySym keysym_return;
+ XLookupString(&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
+ {
+ int sel = fl_get_browser(browser);
+ int const top = fl_get_browser_topline(browser);
+ int const screenlines = fl_get_browser_screenlines(browser);
+
+ if (sel < 1 || sel >= fl_get_browser_maxline(browser))
+ return 0;
+
+ ++sel;
+ fl_select_browser_line(browser, sel);
+
+ if (sel >= top + screenlines)
+ fl_set_browser_topline(browser, sel - screenlines + 1);
+
+ if (sel < top)
+ fl_set_browser_topline(browser, sel);
+
+ return 1;
+ }
+
+ case XK_Up:
+#ifdef XK_KP_Up
+ case XK_KP_Up:
+#endif
+ {
+ int sel = fl_get_browser(browser);
+ int const top = fl_get_browser_topline(browser);
+ int const screenlines = fl_get_browser_screenlines(browser);
+
+ if (sel <= 1 || sel > fl_get_browser_maxline(browser))
+ return 0;
+
+ --sel;
+ fl_select_browser_line(browser, sel);
+
+ if (sel >= top + screenlines)
+ fl_set_browser_topline(browser, sel - screenlines + 1);
+
+ if (sel < top)
+ fl_set_browser_topline(browser, sel);
+
+ return 1;
+ }
+
+ case XK_Return:
+#ifdef XK_KP_Enter
+ case XK_KP_Enter:
+#endif
+ fl_hide_freebrowser(fb);
+ if (fb->callback)
+ fb->callback(fb, 1);
+ return 1;
+
+ case XK_Escape:
+ fl_hide_freebrowser(fb);
+ return 1;
+ default:
+ if (fb->want_printable && s_r[0] && isprint(s_r[0])) {
+ fb->last_printable = s_r[0];
+ fl_hide_freebrowser(fb);
+ if (fb->callback)
+ fb->callback(fb, 1);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
--- /dev/null
+/**
+ * \file freebrowser.h
+ * \author Angus Leeming
+ *
+ * A freebrowser is a browser widget in its own form.
+ * It is used for example to instantiate the drop-down list beneath a
+ * combox.
+ */
+
+#ifndef FL_FREEBROWSER_H
+#define FL_FREEBROWSER_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+enum freebrowser_position {
+ FL_FREEBROWSER_BELOW,
+ FL_FREEBROWSER_ABOVE
+};
+
+typedef struct fl_freebrowser_ {
+ /** Use this and you'll be told when something happens.
+ * \param == 0: the browser has merely been hidden.
+ * == 1: a change has been made.
+ */
+ void (* callback) (struct fl_freebrowser_ *, int action);
+
+ /** Set this to 1 if you want to capture all KeyPress events
+ * generating printable chars.
+ */
+ int want_printable;
+ /** Is set only if want_printable is true. */
+ char last_printable;
+
+ /** Details of the implementation. */
+ void * parent;
+ FL_FORM * form;
+ FL_OBJECT * browser;
+ Window save_window;
+} FL_FREEBROWSER;
+
+
+/** A function to create a freebrowser widget, "owned" by widget \param parent.
+ */
+FL_EXPORT FL_FREEBROWSER * fl_create_freebrowser(void * parent);
+
+FL_EXPORT void fl_free_freebrowser(FL_FREEBROWSER *);
+
+/** \param abs_x, \param abs_y are the coordinates of the top left corner
+ * of the browser relative to the top left hand corner of the _screen_.
+ * \param w, \param h are the browser dimensions.
+ */
+FL_EXPORT void fl_show_freebrowser(FL_FREEBROWSER *,
+ FL_Coord abs_x, FL_Coord abs_y,
+ FL_Coord w, FL_Coord h);
+
+FL_EXPORT void fl_hide_freebrowser(FL_FREEBROWSER *);
+
+/** Return the browser itself. */
+FL_EXPORT FL_OBJECT * fl_get_freebrowser_browser(FL_FREEBROWSER *);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
#include <fstream>
#include FORMS_H_LOCATION
+#include "combox.h"
using std::ofstream;
using std::pair;
tmp = fl_get_choice_item_text(ob, line);
break;
+ case FL_COMBOX:
+ tmp = fl_get_combox_text(ob);
+ break;
+
default:
lyx::Assert(0);
}