📄 wx_combo.cpp
字号:
#include "Hw_Kb_Core.h"#include "Wx_Combo.h"#define ADDSIZE 10#define BUTTON_WIDTH 17#define MAINWND_W 640 #define MAINWND_H 432 char *get_value (int R);class Wx_Flvl_Drop : public Flv_List{public: int last_row; Wx_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; }; Wx_Flve_Combo *combo;protected: void draw_row( int Offset, int &X, int &Y, int &W, int &H, int R );};class Wx_Flvw_Drop : public Fl_Window{public: int key; Wx_Flvl_Drop *drop_list; Wx_Flve_Combo *combo; Fl_Widget *pushed; Wx_Flvw_Drop( int w, int h, const char *l=0 ); ~Wx_Flvw_Drop();protected: int handle(int event);};Wx_Flvw_Drop::Wx_Flvw_Drop( int w, int h, const char *l ) : Fl_Window(w,h,l){ drop_list = new Wx_Flvl_Drop(0,0,w,h); ((Wx_Flvl_Drop *)drop_list)->has_scrollbar(FLVS_VERTICAL); pushed = 0;}Wx_Flvw_Drop::~Wx_Flvw_Drop(){ if (drop_list) delete drop_list;}bool selectflag = false;int Wx_Flvw_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() ) { selectflag = false; //added by wangxin 2002-07-05 key = 0; hide(); return 1; } selectflag = true; //added by wangxin 2002-07-05 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()) { case FL_Escape: 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) if (event==FL_PUSH && pushed==this) { combo->item.index(drop_list->row()); combo->do_callback( combo, (void *)(drop_list->row()+1) ); key = 0; hide(); return 1; } return stat;}void Wx_Flvl_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()) { last_row = row(); }}void Wx_Flvt_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;}int Wx_Flvt_Input::handle(int event){ //int stat; int t, i; Wx_Flve_Combo *w; w = (Wx_Flve_Combo *)parent(); if (w) i = w->item.index(); switch(event) { case FL_FOCUS: case FL_UNFOCUS: Fl_Input::handle(event); return 0; case FL_PUSH: { if (0==type_) { config_keyboard(1,Fl::event_x_root(),Fl::event_y_root()); } else { config_handwriting(); } return Fl_Input::handle(event); } } t = (position()==mark()); if (event!=FL_KEYBOARD) return Fl_Input::handle(event);//stat; switch( Fl::event_key() ) { case FL_BackSpace: 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 Fl_Input::handle(event);//stat; default: { if (w->type()==1) { char ascii = Fl::event_text ()[0]; if ( (ascii == '(') || (ascii == ')') || (ascii == '-') || (ascii >= '0' && ascii <= '9') || (iscntrl (ascii)) ) return Fl_Input::handle(event);//stat; else return 1; } else Fl_Input::handle(event); } } return 1;}Wx_Flve_Combo::Wx_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; input = new Wx_Flvt_Input(x,y,w,h); input->parent(this); 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}Wx_Flve_Combo::~Wx_Flve_Combo(){ if (vlist_title) delete vlist_title;}bool Wx_Flve_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()); } } return vlist_only;}void Wx_Flve_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); }}void Wx_Flve_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);}int Wx_Flve_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; } // Kludge to make input think it's focused wid = Fl::focus_; Fl::focus_ = input; stat = input->handle(event); Fl::focus_ = wid; // 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: stat = input->handle(event); } return stat;}void Wx_Flve_Combo::draw(void){ int X,Y,W,H,bx; if ( (damage()&FL_DAMAGE_ALL)!=0 ) draw_box(); X = x() + (Fl::box_dx(box())); Y = y() + (Fl::box_dy(box())); W = w() - (Fl::box_dw(box())); H = h() - (Fl::box_dh(box())); bx = X + W - BUTTON_WIDTH; draw_box( FL_UP_BOX, bx+1, Y, BUTTON_WIDTH, H, (Fl_Color)(FL_GRAY_RAMP+17) ); fl_draw_symbol("@#2>", bx+3, Y, BUTTON_WIDTH-5, H, FL_BLACK ); fl_color( (Fl_Color)(FL_GRAY_RAMP+17) ); fl_yxline(bx,Y,Y+H); input->draw();}void Wx_Flve_Combo::open_list(){ int W, H, r; Fl_Window *win; Wx_Flvw_Drop *lst; fl_font( text_font(), text_size() ); fl_measure("X", W, H ); r = item.count(); if (vlist_title) r++; if (r>display_rows()) r=display_rows(); list = lst = new Wx_Flvw_Drop(w(),H*r+4+(vlist_title?4:0)); list->box(FL_DOWN_BOX); list->end(); list->parent(NULL); lst->drop_list->rows(item.count()); if (vlist_title) lst->drop_list->label(vlist_title); list->clear_border(); list->set_modal(); lst->drop_list->combo = this; lst->combo = this; lst->drop_list->row(item.index()); //*** win = window(); if (win) { int bottom = y()+h()+lst->drop_list->h(); if (bottom>MAINWND_H) list->position(win->x()+x(), win->y()+y()-lst->drop_list->h()); else list->position(win->x()+x(), win->y()+y()+h()-3); } Fl::grab(list); list->show(); while( list->shown() ) Fl::wait(); Fl::grab(0); take_focus(); if (selectflag) value( item[item.index()].item() ); selectflag = false; if (win && ((Wx_Flvw_Drop *)list)->key) Fl::handle(FL_KEYBOARD,win); delete list; list = 0;}const char *Wx_Flve_Combo::value(){ return input->value();}void Wx_Flve_Combo::value(const char *v){ input->value(v); input->position(0, input->size() );}void Wx_Flve_Combo::display_rows(int v){ vdisplay_rows = v;}// =================================================================// Wx_Flv_Combo_Item// =================================================================Wx_Flv_Combo_Item::Wx_Flv_Combo_Item(){ vitem = 0; vvalue = 0;}Wx_Flv_Combo_Item::~Wx_Flv_Combo_Item(){ if (vitem) delete vitem;}const char *Wx_Flv_Combo_Item::item(void){ return (vitem?vitem:"");}void Wx_Flv_Combo_Item::item(const char *v){ if (vitem) delete vitem; vitem = 0; if (v) { vitem = new char[strlen(v)+1]; strcpy( vitem, v ); }}long Wx_Flv_Combo_Item::value(void){ return vvalue;}void Wx_Flv_Combo_Item::value(long v){ vvalue = v;}// =================================================================// Wx_Flv_Combo_Items// =================================================================Wx_Flv_Combo_Items::Wx_Flv_Combo_Items(){ list = 0; vcount = 0; vallocated = 0; vcurrent = 0;}Wx_Flv_Combo_Items::~Wx_Flv_Combo_Items(){ clear();}void Wx_Flv_Combo_Items::add( const char *item, long v ){ Wx_Flv_Combo_Item *i; if (vcount==vallocated) make_room_for(vallocated+10); if (vcount==vallocated) return; i = new Wx_Flv_Combo_Item(); i->item(item); i->value(v); list[vcount++] = i;}void Wx_Flv_Combo_Items::insert( int index, const char *item, long v ){ int t; Wx_Flv_Combo_Item *i; if (vcount==vallocated) make_room_for(vallocated+10); if (vcount==vallocated) return; i = new Wx_Flv_Combo_Item(); i->item(item); i->value(v); if (index<0) index = 0; if (index>vcount) index = vcount; for (t=vcount; t>index; t-- ) list[t] = list[t-1]; list[index] = i;}void Wx_Flv_Combo_Items::remove( int index ){ int t; if (index<0 || index>=vcount) return; if (list[index]) delete list[index]; for (t=index; t<vcount-1; t++ ) list[t] = list[t+1]; list[t] = 0; vcount--; if (vcurrent>=vcount && vcurrent) vcurrent--;}void Wx_Flv_Combo_Items::change( int i, const char *item, long v ){ if (i<0 || i>vcount) return; list[i]->item(item); list[i]->value(v);}void Wx_Flv_Combo_Items::change( int i, const char *item ){ if (i<0 || i>vcount) return; list[i]->item(item);}void Wx_Flv_Combo_Items::change( int i, long v ){ if (i<0 || i>vcount) return; list[i]->value(v);}#define C(x) ((Wx_Flv_Combo_Item *)(x))static int cmp( const void *a, const void *b ){ int stat; stat = strcmp(C(a)->item(), C(b)->item()); if (stat) return stat; return C(a)->value() - C(b)->value();}void Wx_Flv_Combo_Items::sort(void) // Sort list{ if (list && vcount>1) qsort(list, vcount, sizeof(Wx_Flv_Combo_Item *), cmp );}void Wx_Flv_Combo_Items::clear(void) // Clear list{ int t; for (t=0; t<vcount; t++ ) if (list[t]) delete list[t]; if (list) delete []list; list = 0; vallocated = 0; vcount = 0; vcurrent = 0;}void Wx_Flv_Combo_Items::index(int i) // Set current index{ if (i<0 || i>=vcount) return; vcurrent = i;}int Wx_Flv_Combo_Items::findi( const char *v ) // Find text return index (-1 not found){ int t; for (t=0; t<vcount; t++ ) { if (strncmp(list[t]->item(),v, strlen(v))==0) { vcurrent = t; return t; } } return -1;}int Wx_Flv_Combo_Items::find( const char *v ) // Find text return index (-1 not found){ int t; for (t=0; t<vcount; t++ ) { if (strcmp(list[t]->item(),v)==0) { vcurrent = t; return t; } } return -1;}int Wx_Flv_Combo_Items::find( long v ) // Find value return index (-1 not found){ int t; for (t=0; t<vcount; t++ ) { if ( list[t]->value()==v ) { vcurrent = t; return t; } } return -1;}Wx_Flv_Combo_Item *Wx_Flv_Combo_Items::current(void){ if (list) return list[vcurrent]; return NULL;}Wx_Flv_Combo_Item &Wx_Flv_Combo_Items::operator[](int index){ static Wx_Flv_Combo_Item x; if (index<0 || index>=vcount) return x; return *(list[index]);}void Wx_Flv_Combo_Items::make_room_for(int n){ if (n >= vallocated) { Wx_Flv_Combo_Item **a = new Wx_Flv_Combo_Item *[n]; if (!a) return; // Wasted CPU cycles, but list is pretty memset( a, 0, sizeof(Flv_Style *)*(vallocated+ADDSIZE) ); if (vcount) memcpy( a, list, sizeof(Wx_Flv_Combo_Item *)*vcount ); vallocated += ADDSIZE; if (list) delete []list; list = a; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -