2001-11-05 17:07:23 +00:00
|
|
|
/**
|
|
|
|
* \file DropDown.C
|
|
|
|
* Read the file COPYING
|
|
|
|
*
|
2002-09-05 14:10:50 +00:00
|
|
|
* \author John Levon
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS
|
2001-11-05 17:07:23 +00:00
|
|
|
*/
|
|
|
|
|
2001-12-20 15:11:51 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
2002-03-11 17:00:41 +00:00
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma implementation
|
|
|
|
#endif
|
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
#include "DropDown.h"
|
2002-01-14 12:47:17 +00:00
|
|
|
#include "xforms_helpers.h"
|
2001-11-05 17:07:23 +00:00
|
|
|
|
2002-06-13 13:43:51 +00:00
|
|
|
#include FORMS_H_LOCATION
|
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
#include <iostream>
|
2002-01-14 16:48:28 +00:00
|
|
|
#include <cctype>
|
2002-02-16 15:59:55 +00:00
|
|
|
|
2002-06-10 07:57:39 +00:00
|
|
|
#ifndef CXX_GLOBAL_CSTD
|
|
|
|
using std::isprint;
|
|
|
|
#endif
|
|
|
|
|
2002-02-16 15:59:55 +00:00
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
|
2002-01-14 12:47:17 +00:00
|
|
|
namespace {
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2002-01-14 12:47:17 +00:00
|
|
|
extern "C" void C_CompletedCB(FL_OBJECT * ob, long)
|
2001-11-05 17:07:23 +00:00
|
|
|
{
|
2002-01-14 12:47:17 +00:00
|
|
|
DropDown * d = static_cast<DropDown*>(ob->u_vdata);
|
2001-11-05 17:07:23 +00:00
|
|
|
d->completed();
|
|
|
|
}
|
|
|
|
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2002-01-14 12:47:17 +00:00
|
|
|
extern "C" int C_PeekCB(FL_FORM * form, void *xev)
|
2001-11-05 17:07:23 +00:00
|
|
|
{
|
|
|
|
DropDown * d = static_cast<DropDown*>(form->u_vdata);
|
|
|
|
return d->peek(static_cast<XEvent*>(xev));
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2002-01-14 12:47:17 +00:00
|
|
|
} // namespace anon
|
|
|
|
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2002-07-19 20:56:31 +00:00
|
|
|
DropDown::DropDown(FL_OBJECT * ob)
|
2001-11-05 17:07:23 +00:00
|
|
|
{
|
|
|
|
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;
|
2002-03-21 21:21:28 +00:00
|
|
|
browser_->u_vdata = this;
|
2002-01-14 12:47:17 +00:00
|
|
|
fl_set_object_callback(browser_, C_CompletedCB, 0);
|
|
|
|
fl_register_raw_callback(form_, KeyPressMask|ButtonPressMask, C_PeekCB);
|
2001-11-05 17:07:23 +00:00
|
|
|
fl_end_form();
|
|
|
|
}
|
|
|
|
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
DropDown::~DropDown()
|
|
|
|
{
|
2002-03-21 21:21:28 +00:00
|
|
|
if (form_->visible)
|
2001-11-05 17:07:23 +00:00
|
|
|
fl_hide_form(form_);
|
|
|
|
fl_free_form(form_);
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
|
2002-02-16 15:59:55 +00:00
|
|
|
void DropDown::select(vector<string> const & choices, int x, int y, int w)
|
2001-11-05 17:07:23 +00:00
|
|
|
{
|
2002-01-14 12:47:17 +00:00
|
|
|
if (choices.empty())
|
|
|
|
return;
|
|
|
|
|
2002-08-14 18:31:04 +00:00
|
|
|
fl_set_form_geometry(form_, x, y - 100, w, 100);
|
2001-11-05 17:07:23 +00:00
|
|
|
fl_clear_browser(browser_);
|
2002-02-16 15:59:55 +00:00
|
|
|
|
|
|
|
vector<string>::const_iterator cit = choices.begin();
|
|
|
|
vector<string>::const_iterator end = choices.end();
|
|
|
|
for (; cit != end; ++cit) {
|
2001-11-05 17:07:23 +00:00
|
|
|
fl_add_browser_line(browser_, cit->c_str());
|
|
|
|
}
|
2002-01-14 12:47:17 +00:00
|
|
|
fl_select_browser_line(browser_, 1);
|
2001-11-05 17:07:23 +00:00
|
|
|
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_) +
|
2002-03-21 16:59:12 +00:00
|
|
|
fl_get_browser_screenlines(browser_))
|
|
|
|
fl_set_browser_topline(browser_, fl_get_browser(browser_)
|
|
|
|
- fl_get_browser_screenlines(browser_) + 1);
|
2001-11-05 17:07:23 +00:00
|
|
|
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_) +
|
2002-03-21 16:59:12 +00:00
|
|
|
fl_get_browser_screenlines(browser_))
|
|
|
|
fl_set_browser_topline(browser_, fl_get_browser(browser_)
|
|
|
|
- fl_get_browser_screenlines(browser_) + 1);
|
2001-11-05 17:07:23 +00:00
|
|
|
if (fl_get_browser(browser_) < fl_get_browser_topline(browser_))
|
|
|
|
fl_set_browser_topline(browser_, fl_get_browser(browser_));
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
|
|
|
|
int DropDown::peek(XEvent * xev)
|
|
|
|
{
|
|
|
|
int x,y;
|
|
|
|
unsigned int keymask;
|
|
|
|
|
|
|
|
fl_get_mouse(&x, &y, &keymask);
|
2002-03-21 21:21:28 +00:00
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
if (xev->type == ButtonPress) {
|
|
|
|
if (!(x >= form_->x && x <= (form_->x + form_->w) &&
|
2002-03-21 16:59:12 +00:00
|
|
|
y >= form_->y && y << (form_->y + form_->h))) {
|
2001-11-05 17:07:23 +00:00
|
|
|
fl_hide_form(form_);
|
|
|
|
return 1;
|
|
|
|
}
|
2001-11-08 11:46:06 +00:00
|
|
|
XUngrabPointer(fl_get_display(), CurrentTime);
|
2001-11-05 17:07:23 +00:00
|
|
|
} 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) {
|
2002-03-21 16:59:12 +00:00
|
|
|
case XK_Down:
|
2002-07-10 15:03:25 +00:00
|
|
|
#ifdef XK_KP_Down
|
|
|
|
case XK_KP_Down:
|
|
|
|
#endif
|
2002-03-21 16:59:12 +00:00
|
|
|
line_down();
|
|
|
|
return 1;
|
|
|
|
case XK_Up:
|
2002-07-10 15:03:25 +00:00
|
|
|
#ifdef XK_KP_Up
|
|
|
|
case XK_KP_Up:
|
|
|
|
#endif
|
2002-03-21 16:59:12 +00:00
|
|
|
line_up();
|
|
|
|
return 1;
|
|
|
|
case XK_Return:
|
2002-07-10 15:03:25 +00:00
|
|
|
#ifdef XK_KP_Enter
|
|
|
|
case XK_KP_Enter:
|
|
|
|
#endif
|
2002-03-21 21:21:28 +00:00
|
|
|
completed();
|
2002-03-21 16:59:12 +00:00
|
|
|
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.
|
2002-03-21 21:21:28 +00:00
|
|
|
// fl_XPutBackEvent() doesn't work.
|
2002-03-21 16:59:12 +00:00
|
|
|
|
|
|
|
// 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]);
|
2001-11-08 11:46:06 +00:00
|
|
|
return 1;
|
2002-03-21 16:59:12 +00:00
|
|
|
}
|
2001-11-05 17:07:23 +00:00
|
|
|
}
|
|
|
|
}
|
2002-03-21 21:21:28 +00:00
|
|
|
return 0;
|
2001-11-05 17:07:23 +00:00
|
|
|
}
|
|
|
|
|
2002-03-21 16:59:12 +00:00
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
void DropDown::completed()
|
|
|
|
{
|
2001-11-08 11:46:06 +00:00
|
|
|
XUngrabPointer(fl_get_display(), CurrentTime);
|
2001-11-05 17:07:23 +00:00
|
|
|
fl_hide_form(form_);
|
2002-07-21 15:51:07 +00:00
|
|
|
result(getString(browser_));
|
2002-01-14 12:47:17 +00:00
|
|
|
}
|
|
|
|
|
2001-11-05 17:07:23 +00:00
|
|
|
|
2002-01-14 12:47:17 +00:00
|
|
|
void DropDown::key_pressed(char c)
|
|
|
|
{
|
|
|
|
XUngrabPointer(fl_get_display(), CurrentTime);
|
|
|
|
fl_hide_form(form_);
|
2002-05-29 16:21:03 +00:00
|
|
|
keypress(c);
|
2001-11-05 17:07:23 +00:00
|
|
|
}
|