📄 flve_combo.cxx
字号:
// ======================================================================// File: Flve_Combo.cxx - Flve_Combo implementation// Library: flvw - FLTK Virtual widget library// Version: 0.1.0// Started: 01/12/2000//// Copyright (C) 1999 Laurence Charlton//// Description:// Flve_Combo implements combo box functionality// Included are select from list, text with list, incremental search// ======================================================================#include <FL/Fl.H>#include <Flek/Flve_Combo.H>#include <FL/fl_draw.H>#include <stdio.h>#include <string.h>#include <stdlib.h>#if FL_MAJOR_VERSION == 1#define text_color() FL_BLACK#define text_font() FL_HELVETICA#define text_size() 12#define fl_contrast(x,y) FL_BLACK#define selection_text_color() FL_WHITE#define FL_DAMAGE_HIGHLIGHT FL_DAMAGE_CHILD#define label_font labelfont#define label_size labelsize#define label_color labelcolor#define label_type labeltype#endif#define ADDSIZE 10#define BUTTON_WIDTH 17#ifdef WIN32#define STRCASECMP stricmp#define STRNCASECMP strncmpi#else#define STRCASECMP strcasecmp#define STRNCASECMP strncasecmp#endifchar *get_value(int R){ static char buf[20]; sprintf(buf, "%d", R); return buf;}class Flvl_Drop:public Flv_List{ public: int last_row; Flvl_Drop(int x, int y, int w, int h, const char *l = 0):Flv_List(x, y, w, h, l) { combo = 0; last_row = -1; }; Flve_Combo *combo; protected: void draw_row(int Offset, int &X, int &Y, int &W, int &H, int R);};class Flvw_Drop:public Fl_Window{ public: int key; Flvl_Drop *drop_list; Flve_Combo *combo; Fl_Widget *pushed; Flvw_Drop(int w, int h, const char *l = 0); ~Flvw_Drop(); protected: int handle(int event);};class Flvt_Input:public Fl_Input{ public: Flvt_Input(int x, int y, int w, int h, const char *l = 0):Fl_Input(x, y, w, h, l) { }; protected: int handle(int event); void draw(void);};Flvw_Drop::Flvw_Drop(int w, int h, const char *l):Fl_Window(w, h, l){ drop_list = new Flvl_Drop(0, 0, w, h); ((Flvl_Drop *) drop_list)->has_scrollbar(FLVS_VERTICAL); pushed = 0;}Flvw_Drop::~Flvw_Drop(){ if (drop_list) delete drop_list;}intFlvw_Drop::handle(int event){ int ex, ey, stat, r; ex = Fl::event_x(); ey = Fl::event_y(); r = drop_list->row(); switch (event) { case FL_PUSH: if (ex < 0 || ex > w() || ey < 0 || ey > h()) { key = 0; hide(); return 1; } break; case FL_KEYBOARD: stat = Fl::event_key(); if (Fl::event_ctrl()) stat = flv_ctrl(stat); if (Fl::event_alt()) stat = flv_alt(stat); if (Fl::event_shift()) stat = flv_shift(stat); if (stat == combo->drop_key()) { key = 0; hide(); return 1; } switch (Fl::event_key()) { // modified behavior of escape key to restore original value // of the input widget. // TAB and Enter both accept the new value // D.Freese (dfreese@intrepid.net) case FL_Escape: key = 0; hide(); return 1; case FL_Enter: case FL_Tab: combo->item.index(drop_list->row()); key = Fl::event_key(); //if (key==FL_Escape) // key = 0; hide(); return 1; } break; } if (pushed && (event == FL_DRAG || event == FL_RELEASE) && contains(pushed) && pushed != this) stat = pushed->handle(event); else stat = ((Fl_Widget *) drop_list)->handle(event); if (!stat && event == FL_KEYBOARD) stat = ((Fl_Widget *) combo)->handle(event); pushed = Fl::pushed(); if (event == FL_PUSH && r == drop_list->row() && pushed == this) { combo->item.index(drop_list->row()); key = 0; hide(); return 1; } return stat;}voidFlvl_Drop::draw_row(int Offset, int &X, int &Y, int &W, int &H, int R){ Flv_Style s; get_style(s, R); Flv_List::draw_row(Offset, X, Y, W, H, R); fl_draw(combo->item[R].item(), X - Offset, Y, W, H, s.align()); if (last_row != row()) { combo->value(combo->item[row()].item()); last_row = row(); }}voidFlvt_Input::draw(void){ Fl_Widget *f = Fl::focus(); // Kludge so that events don't get fired all over the place // We just want the input to draw correctly as though it had the // focus. if (f && f != parent()) f = NULL; if (f) Fl::focus_ = this; Fl_Input::draw(); if (f) Fl::focus_ = f;}intFlvt_Input::handle(int event){ int stat, t, i = 0; Flve_Combo *w; w = (Flve_Combo *) parent(); if (w) i = w->item.index(); switch (event) { case FL_FOCUS: case FL_UNFOCUS: Fl_Input::handle(event); return 0; } t = (position() == mark()); stat = Fl_Input::handle(event); if (event != FL_KEYBOARD) return stat; switch (Fl::event_key()) { case FL_BackSpace: // If nothing was selected, Backspace already worked if (t) break; Fl_Input::handle(event); break; case FL_Pause: case FL_Scroll_Lock: case FL_Num_Lock: case FL_Caps_Lock: case FL_Shift_L: case FL_Shift_R: case FL_Control_L: case FL_Control_R: case FL_Meta_L: case FL_Meta_R: case FL_Alt_L: case FL_Alt_R: return stat; } //printf("At this point, my value is [%s]\n", value()); if (!w) {#ifdef PIXIL Fl_Input::redraw();#endif return stat; } if (!w->incremental_search()) {#ifdef PIXIL Fl_Input::redraw();#endif return stat; } if (w->item.findi(value()) > -1) { t = position(); if (w->list) { ((Flvw_Drop *) w->list)->drop_list->row(w->item.index()); ((Flvw_Drop *) w->list)->drop_list->last_row = ((Flvw_Drop *) w->list)->drop_list->row(); } value(w->item[w->item.index()].item()); position(t + 1, size()); } else if (w->list_only()) { t = position(); value(w->item[i].item()); position((t ? t - 1 : t), size()); }#ifdef PIXIL Fl_Input::redraw();#endif return stat;}Flve_Combo::Flve_Combo(int x, int y, int w, int h, const char *l):Fl_Widget(x, y, w, h, l){ vlist_only = true; vincremental_search = true; vlist_title = 0; Fl_Group *gsave = Fl_Group::current(); Fl_Group::current(0); input = new Flvt_Input(x, y, w, h); Fl_Group::current(gsave); box(input->box()); input->box(FL_NO_BOX); resize(x, y, w, h); color((Fl_Color) (input->color())); vdisplay_rows = 8; vdrop_key = flv_ctrl('E'); // Control+E}Flve_Combo::~Flve_Combo(){ if (vlist_title) delete vlist_title;}boolFlve_Combo::list_only(bool v){ if (v != vlist_only) { vlist_only = v; if (v) { input->value(item[item.index()].item()); input->position(0, input->size()); input->set_changed(); } } return vlist_only;}voidFlve_Combo::list_title(const char *v){ if (vlist_title) delete vlist_title; vlist_title = 0; if (v) { vlist_title = new char[strlen(v) + 1]; strcpy(vlist_title, v); }}voidFlve_Combo::resize(int X, int Y, int W, int H){ Fl_Widget::resize(X, Y, W, H); X += (Fl::box_dx(box())); Y += (Fl::box_dy(box())); W -= (Fl::box_dw(box())); H -= (Fl::box_dh(box())); W -= BUTTON_WIDTH; input->resize(X, Y, W, H);}intFlve_Combo::handle(int event){ int stat, ex, ey, X, Y, W, H; Fl_Widget *wid; switch (event) { case FL_UNFOCUS: if (Fl::focus() == input) take_focus(); redraw(); case FL_FOCUS: input->handle(event);// input->position(0, input->size() ); return 1; case FL_KEYBOARD: X = Fl::event_key(); if (Fl::event_ctrl()) X = flv_ctrl(X); if (Fl::event_alt()) X = flv_alt(X); if (Fl::event_shift()) X = flv_shift(X); if (X == vdrop_key) { open_list(); return 1; }#ifdef PIXIL // Kludge to make input think it's focused wid = Fl::focus_; Fl::focus_ = input; stat = input->handle(event); input->redraw(); Fl::focus_ = wid;#endif // Shouldn't be doing searching if the value couldn't have changed! break; case FL_PUSH: // Test for button push ex = Fl::event_x(); ey = Fl::event_y(); X = x() + w() - BUTTON_WIDTH; Y = y(); W = BUTTON_WIDTH; H = h(); if (ex >= X && ex < X + W && ey >= Y && ey <= Y + H) { open_list(); return 1; } return input->handle(event); default: wid = Fl::focus_; Fl::focus_ = input; stat = input->handle(event); Fl::focus_ = wid; } return stat;}voidFlve_Combo::draw(void){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -