From 998ddf60e34ce1d43455fadbf70a815dd4556e8e Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Mon, 14 Jan 2002 12:47:17 +0000 Subject: [PATCH] Nobody complained so I'm committing my minibuffer completion patch. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3369 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/ChangeLog | 8 +++++ src/frontends/xforms/ChangeLog | 15 ++++++++ src/frontends/xforms/DropDown.C | 49 +++++++++++++++++---------- src/frontends/xforms/DropDown.h | 8 ++++- src/frontends/xforms/xforms_helpers.C | 24 +++++++++++-- src/frontends/xforms/xforms_helpers.h | 11 +++--- src/minibuffer.C | 23 +++++++++++-- src/minibuffer.h | 2 ++ 8 files changed, 112 insertions(+), 28 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6355f76506..e065672754 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2002-01-11 Angus Leeming + + * minibuffer.[Ch] (append_char): new method to recieve input from the + drop-down completion browser. If a key was pressed, then recieve this + char and append it to the existing string. + (peek_event): modify the positioning data passed to the completion + browser so that it can be placed above the minibuffer rather than below. + 2002-01-14 Lars Gullik Bjønnes * LyXAction.C (init): alloe error-next for readonly documents. diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index b09c08a6fa..26f563b89e 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,18 @@ +2002-01-11 Angus Leeming + + * DropDown.[Ch] (keypress, key_pressed): new signal and method, + respectively. + + * DropDown.C: place xforms callback functions in namespace anon. + Set browser callback on single not double click. + (select): return immediately of the vector is empty. Highlight the top + line. Position the browser above the minibuffer, not below it. + (peek): call key_pressed when a key press is detected. + (key_pressed): clean-up and emit the keypress signal. + + * xforms_helpers.[Ch} (getSelectedStringFromBrowser): new function. + If nothing is selected, return string(). + 2002-01-14 John Levon * FormSpellchecker.C: disable resizing due to xforms bug diff --git a/src/frontends/xforms/DropDown.C b/src/frontends/xforms/DropDown.C index 0cf93524e9..75f2c45b5d 100644 --- a/src/frontends/xforms/DropDown.C +++ b/src/frontends/xforms/DropDown.C @@ -9,22 +9,27 @@ #include #include "DropDown.h" +#include "xforms_helpers.h" #include -extern "C" void C_DropDownCompletedCB(FL_OBJECT * ob, long) +namespace { + +extern "C" void C_CompletedCB(FL_OBJECT * ob, long) { - DropDown * d = static_cast(ob->form->u_vdata); + DropDown * d = static_cast(ob->u_vdata); d->completed(); } -extern "C" int C_DropDownPeekEventCB(FL_FORM * form, void *xev) +extern "C" int C_PeekCB(FL_FORM * form, void *xev) { DropDown * d = static_cast(form->u_vdata); return d->peek(static_cast(xev)); } +} // namespace anon + DropDown::DropDown(LyXView * lv, FL_OBJECT * ob) : lv_(lv) @@ -33,8 +38,9 @@ DropDown::DropDown(LyXView * lv, FL_OBJECT * ob) 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; - fl_set_browser_dblclick_callback(browser_, C_DropDownCompletedCB, 0); - fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_DropDownPeekEventCB); + browser_->u_vdata = this; + fl_set_object_callback(browser_, C_CompletedCB, 0); + fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_PeekCB); fl_end_form(); } @@ -49,12 +55,16 @@ DropDown::~DropDown() void DropDown::select(std::vector const & choices, int x, int y, int w) { - fl_set_form_geometry(form_, x, y, w, 100); + if (choices.empty()) + return; + + fl_set_form_geometry(form_, x, y-100, w, 100); fl_clear_browser(browser_); for (std::vector::const_iterator cit = choices.begin(); cit != choices.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, @@ -118,7 +128,7 @@ int DropDown::peek(XEvent * xev) completed(); return 1; case XK_Escape: - fl_select_browser_line(browser_, 0); + fl_deselect_browser(browser_); completed(); return 1; default: @@ -126,9 +136,13 @@ int DropDown::peek(XEvent * xev) // convince the event to fall back to the // minibuffer, I'm glad to hear it. // fl_XPutBackEvent() doesn't work. - fl_select_browser_line(browser_, 0); - completed(); - return 1; + + // 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; @@ -138,13 +152,14 @@ int DropDown::peek(XEvent * xev) void DropDown::completed() { XUngrabPointer(fl_get_display(), CurrentTime); - string selection; - int i = fl_get_browser(browser_); - if (i < 1) - selection = ""; - else - selection = fl_get_browser_line(browser_, i); fl_hide_form(form_); + result.emit(getSelectedStringFromBrowser(browser_)); +} + - result.emit(selection); +void DropDown::key_pressed(char c) +{ + XUngrabPointer(fl_get_display(), CurrentTime); + fl_hide_form(form_); + keypress.emit(c); } diff --git a/src/frontends/xforms/DropDown.h b/src/frontends/xforms/DropDown.h index 142a9091fd..8baccbe479 100644 --- a/src/frontends/xforms/DropDown.h +++ b/src/frontends/xforms/DropDown.h @@ -27,10 +27,16 @@ public: /// user completed action void completed(); - + + /// a key was pressed. Act on it. + void key_pressed(char c); + /// signal for completion SigC::Signal1 result; + /// signal that a key was pressed + SigC::Signal1 keypress; + /// X event int peek(XEvent *); diff --git a/src/frontends/xforms/xforms_helpers.C b/src/frontends/xforms/xforms_helpers.C index f65b708255..42d927ce0c 100644 --- a/src/frontends/xforms/xforms_helpers.C +++ b/src/frontends/xforms/xforms_helpers.C @@ -90,9 +90,7 @@ vector const getVectorFromChoice(FL_OBJECT * ob) } -// Given an fl_browser, return the contents of the currently -// highlighted line. -// If nothing is selected, return an empty string +// Given an fl_browser, return the contents of line string const getStringFromBrowser(FL_OBJECT * ob, int line) { if (!ob || ob->objclass != FL_BROWSER || @@ -103,6 +101,26 @@ string const getStringFromBrowser(FL_OBJECT * ob, int line) return (tmp) ? tmp : string(); } +// Given an fl_browser, return the contents of the currently +// highlighted line. +// If nothing is selected, return an empty string +string const getSelectedStringFromBrowser(FL_OBJECT * ob) +{ + if (!ob || ob->objclass != FL_BROWSER) + return string(); + + int const line = fl_get_browser(ob); + if (line < 1 || line > fl_get_browser_maxline(ob)) + return string(); + + if (!fl_isselected_browser_line(ob, line)) + return string(); + + char const * tmp = fl_get_browser_line(ob, line); + return (tmp) ? tmp : string(); +} + + // Given an fl_browser, create a vector of its entries vector const getVectorFromBrowser(FL_OBJECT * ob) { diff --git a/src/frontends/xforms/xforms_helpers.h b/src/frontends/xforms/xforms_helpers.h index 828ada07a0..845fab28d8 100644 --- a/src/frontends/xforms/xforms_helpers.h +++ b/src/frontends/xforms/xforms_helpers.h @@ -39,13 +39,14 @@ std::vector const getVectorFromChoice(FL_OBJECT *); /// Given an fl_browser, create a vector of its entries std::vector const getVectorFromBrowser(FL_OBJECT *); -/** Given an fl_browser, return the contents of the currently - highlighted line (xforms numbering convention; starts at 1). - If nothing is selected, return an empty string. - This function, although apparently overkill, ensures that we don't get - unexpected crashes. +/** Given an fl_browser, return the contents of line + (xforms numbering convention; starts at 1). */ string const getStringFromBrowser(FL_OBJECT * ob, int line); +/** Given an fl_browser, return the contents of the currently + highlighted line. +*/ +string const getSelectedStringFromBrowser(FL_OBJECT * ob); /// Given input and choice widgets, create a string such as "1cm" string getLengthFromWidgets(FL_OBJECT * input, FL_OBJECT * choice); diff --git a/src/minibuffer.C b/src/minibuffer.C index 7df08768eb..4e0666c52d 100644 --- a/src/minibuffer.C +++ b/src/minibuffer.C @@ -71,6 +71,7 @@ void MiniBuffer::dd_init() { dropdown_ = new DropDown(owner_, the_buffer); dropdown_->result.connect(slot(this, &MiniBuffer::set_complete_input)); + dropdown_->keypress.connect(slot(this, &MiniBuffer::append_char)); } @@ -183,8 +184,12 @@ int MiniBuffer::peek_event(FL_OBJECT * ob, int event, int key) fl_get_wingeometry(fl_get_real_object_window(the_buffer), &x, &y, &w, &h); - // asynchronous completion - dropdown_->select(comp, x, y + h, w); + // asynchronous completion + int const air = the_buffer->x; + x += air; + y += h - (the_buffer->h + air); + w = the_buffer->w; + dropdown_->select(comp, x, y, w); } return 1; } @@ -394,6 +399,20 @@ void MiniBuffer::set_complete_input(string const & str) } +void MiniBuffer::append_char(char c) +{ + if (!c || !isprint(c)) + return; + + char const * tmp = fl_get_input(the_buffer); + string str = tmp ? tmp : ""; + + str += c; + + fl_set_input(the_buffer, str.c_str()); +} + + void MiniBuffer::set_input(string const & str) { fl_set_input(the_buffer, str.c_str()); diff --git a/src/minibuffer.h b/src/minibuffer.h index bf4ade1668..63dcffd22d 100644 --- a/src/minibuffer.h +++ b/src/minibuffer.h @@ -76,6 +76,8 @@ private: void stored_set(string const &); /// set the minibuffer content if str non-empty void set_complete_input(string const &); + /// append c to the current contents + void append_char(char c); /// set the minibuffer content void set_input(string const &); /// -- 2.39.2