📄 flv_list.cxx
字号:
// ======================================================================// File: Flv_List.cxx - Flv_List implementation// Program: Flv_List - FLTK List Widget// Version: 0.1.0// Started: 11/21/99//// Copyright (C) 1999 Laurence Charlton//// Description:// Flv_List implements a scrollable list. No data is stored// in the widget. Supports headers/footers, natively supports a single// row height per list. Row grids can be turned on and off. Supports// no scroll bars as well as horizontal/vertical automatic or always// on scroll bars.// Uses absolute row references.//// row -1 is defined as the row header// row -2 is defined as the row footer//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "lcharlto@mail.coin.missouri.edu"// ======================================================================#include <Flek/Flv_List.H>#include <FL/fl_draw.H>#include <FL/Fl_Output.H>#include <stdio.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#ifdef PIXIL#define selection_text_color() NxApp::GlobalColor(HILIGHT_TEXT)#else#define selection_text_color() FL_WHITE#endif#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 DOcb(x) ((vcallback_when & (x))==(x))// Resizing constants#define FUDGE 2#define MOVE_X 1#define MOVE_Y 2#define MOVE_XY (MOVE_X|MOVE_Y)static voidvscrollbar_cb(Fl_Widget * o, void *){ Flv_List *s = (Flv_List *) (o->parent());#ifdef PIXIL s->top_row(((NxScrollbar *) o)->value());#else s->top_row(((Fl_Scrollbar *) o)->value());#endif s->damage(FL_DAMAGE_CHILD);// s->select_start_row( ((Fl_Scrollbar *)o)->value() );}static voidhscrollbar_cb(Fl_Widget * o, void *){ Flv_List *s = (Flv_List *) (o->parent());#ifdef PIXIL s->row_offset(((NxScrollbar *) o)->value());#else s->row_offset(((Fl_Scrollbar *) o)->value());#endif}#if FL_MAJOR_VERSION == 2//================================================================// Style stuff?//================================================================static voidrevert(Fl_Style * s){ s->selection_color = FL_BLUE_SELECTION_COLOR; s->selection_text_color = FL_WHITE; //s->off_color = FL_BLACK; s->box = FL_THIN_DOWN_BOX; s->color = FL_GRAY_RAMP + 1;}static Fl_Named_Style *_style = new Fl_Named_Style("flvlist", revert, &_style);#endifFlv_List::Flv_List(int X, int Y, int W, int H, const char *l):Fl_Group(X, Y, W, H, l),scrollbar(0, 0, 0, 0, 0),hscrollbar(0, 0, 0, 0, 0){ int r, rh; edit_row = -1;#if FL_MAJOR_VERSION == 2// CET - FIXME style(_style);#else box(FL_THIN_DOWN_BOX);#endif fl_font(text_font(), text_size()); fl_measure("X", r, rh);// Leave global_style & row_style undefined// get_default_style(global_style); if (parent()) vdead_space_color = parent()->color(); else vdead_space_color = FL_GRAY; scrollbar.callback(vscrollbar_cb); hscrollbar.callback(hscrollbar_cb); hscrollbar.type(FL_HORIZONTAL); vclicks = 0; vmax_clicks = 2; // Double click the most vcallback_when = 0xffff; // All Events veditor = NULL; vediting = false; vedit_when = FLV_EDIT_MANUAL; vwhy_event = 0; vfeature = FLVF_PERSIST_SELECT; vhas_scrollbars = FLVS_BOTH; vlast_row = 0; vrow = 0; vrow_offset = 0; vrow_width = 0; vrows = 0; vrows_per_page = 0; vscrollbar_width = 17; vselect_locked = true; vselect_row = 0; vtop_row = 0; end(); // Don't put other widgets in this one.}Flv_List::~Flv_List(){ row_style.release(); // Free any memory allocated}//================================================================// Virtual functions//================================================================voidFlv_List::save_editor(Fl_Widget *, int, int){}voidFlv_List::load_editor(Fl_Widget *, int, int){}voidFlv_List::position_editor(Fl_Widget * e, int x, int y, int w, int h, Flv_Style &){ e->resize(x, y, w, h);}#include <FL/Fl_Box.H>// Draw a single rowvoidFlv_List::draw_row(int Offset, int &X, int &Y, int &W, int &H, int R){ Fl_Boxtype bt; Flv_Style s; get_style(s, R); // Guaranteed to fill in style if (Fl::focus() == this || persist_select()) add_selection_style(s, R); // Add selection coloring if applicable if (row_divider()) s.border(s.border() | FLVB_BOTTOM); // Be sure bottom is on X -= Offset; draw_border(s, X, Y, W, H); bt = s.frame(); fl_color(s.background()); fl_rectf(X, Y, W, H);#if FL_MAJOR_VERSION == 2// CET - FIXME - this is completely lame. Need to fix FLTK2 Fl_Box *box = new Fl_Box(X, Y, W, H); box->color(s.background()); box->box(bt); ((Fl_Widget *) box)->draw(); // cast to make sure draw is public delete box; bt->inset(X, Y, W, H);#else draw_box(bt, X, Y, W, H, s.background()); X += (Fl::box_dx(bt)); Y += (Fl::box_dy(bt)); W -= (Fl::box_dw(bt)); H -= (Fl::box_dh(bt));#endif if (R == row() && (Fl::focus() == this || persist_select())) { fl_color(fl_contrast(FL_BLACK, selection_color())); fl_rect(X, Y, W, H); } X += s.x_margin(); Y += s.y_margin(); W -= s.x_margin() * 2; H -= s.y_margin() * 2; fl_font(s.font(), s.font_size()); if (!active())#if FL_MAJOR_VERSION == 1# if FL_MINOR_VERSION == 0 s.foreground(inactive(s.foreground()));# else s.foreground(fl_inactive(s.foreground()));# endif#endif fl_color(s.foreground()); X += Offset; if (R == -3) // Draw title fl_draw(label(), X, Y, W, H, s.align());}// Handle eventsintFlv_List::handle(int event){ int t, x, y; bool bs; bs = (vselect_row != vrow); switch (event) { case FL_DEACTIVATE: case FL_HIDE: case FL_LEAVE: case FL_ENTER: case FL_ACTIVATE: case FL_SHOW: return 1; case FL_MOVE: check_cursor(); Fl_Group::handle(event); return 1; case FL_FOCUS: Fl::focus(this); damage(FL_DAMAGE_CHILD); Fl_Group::handle(event); return 1; case FL_UNFOCUS: damage(FL_DAMAGE_CHILD); Fl_Group::handle(event); return 1; case FL_KEYBOARD: break; case FL_RELEASE: Fl_Group::handle(event); return 1; case FL_DRAG: if (check_resize()) return 1; case FL_PUSH: Fl::focus(this); damage(FL_DAMAGE_CHILD); x = Fl::event_x(); y = Fl::event_y(); t = get_row(x, y); // Row header clicked if (t < 0) { vwhy_event = 0; switch (t) { case -3: if (DOcb(FLVEcb_TITLE_CLICKED)) vwhy_event = FLVE_TITLE_CLICKED; break; case -2: if (DOcb(FLVEcb_ROW_FOOTER_CLICKED)) vwhy_event = FLVE_ROW_FOOTER_CLICKED; break; case -1: if (DOcb(FLVEcb_ROW_HEADER_CLICKED)) vwhy_event = FLVE_ROW_HEADER_CLICKED; break; } if (vwhy_event) { do_callback(this, user_data()); vwhy_event = 0; } Fl_Group::handle(event); return 1; } row(t); if (!multi_select() || (event == FL_PUSH && !Fl::event_state(FL_SHIFT))) { if (bs) vlast_row = vrow; if (vselect_row != vrow) select_start_row(vrow); } if (event == FL_PUSH) { if (DOcb(FLVEcb_CLICKED)) { vwhy_event = FLVE_CLICKED; do_callback(this, user_data()); vwhy_event = 0; } } Fl_Group::handle(event); return 1; default: return Fl_Group::handle(event); } switch (Fl::event_key()) { case FL_Up: if (Fl::event_state(FL_CTRL)) { if (vrow > 0) row(0); } else row(vrow - 1); break; case FL_Down: if (Fl::event_state(FL_CTRL)) { if (vrow < vrows - 1) row(vrows - 1); } else { if (vrow < vrows - 1) row(vrow + 1); } break; case FL_Page_Down: if (Fl::event_state(FL_CTRL)) { if (vrow < vrows - 1) row(vrows - 1); } else { if (vrow < vrows - 1) row(vrow + page_size()); } break; case FL_Page_Up: if (Fl::event_state(FL_CTRL)) { if (vrow > 0) row(0); } else row(vrow - page_size()); break; case FL_Right: row_offset(vrow_offset + 10); break; case FL_Left: row_offset(vrow_offset - 10); break; default: return Fl_Group::handle(event); } if (!multi_select()) { if (bs) vlast_row = vrow; if (vselect_row != vrow) select_start_row(vrow); } if (!Fl::event_state(FL_SHIFT) && vselect_row != vrow) select_start_row(vrow); Fl_Group::handle(event); return 1;}intFlv_List::row_height(int r){ int rh, x; Flv_Style *rows; if (!global_style.height_defined()) { fl_font(text_font(), text_size()); fl_measure("X", x, rh); } else rh = global_style.height(); if (r < 0) rh += 4; rows = row_style.find(r); if (rows) if (rows->height_defined()) rh = rows->height(); return rh;}// H is set to height of drawn row not including any gridsintFlv_List::row_height(int n, int r){ if (r > -4 && r < rows()) row_style[r].height(n); return row_height(r); // Note: this is only the constant value, if row_height(r) is a calculated // value, it's the only way we can really determine row height. // Don't rely on the value of this function, ALWAYS call row_height(r)}intFlv_List::get_row(int x, int y){ int X, Y, W, H; int rh, rw, t, CY; // Determine if row was clicked and highlight it client_area(X, Y, W, H); if (label()) { rh = row_height(-3); if (Y <= y && y <= Y + rh) return -3; Y += rh; H -= rh; } if (row_header()) { rh = row_height(-1); if (Y <= y && y <= Y + rh) return -1; Y += rh; H -= rh; } if (row_footer()) { rh = row_height(-2); if (Y + H >= y && y > Y + H - rh) return -2; H -= rh; } rw = row_width(); if (!rw) rw = W; if (x < X || x > X + W || y < Y || y >= Y + H || x > X - vrow_offset + rw) return -4; // Out of bounds for (CY = Y, t = vtop_row; t < vrows && CY < Y + H; t++, CY += rh) { rh = row_height(t); if (CY <= y && y <= CY + rh) return t; } return -4; // In grey area?}// get trickle down stylevoidFlv_List::get_style(Flv_Style & s, int R, int){ Flv_Style *rows;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -