📄 flv_table.cxx
字号:
// ======================================================================// File: Flv_Table.cxx - Flv_Table implementation// Program: Flv_Table - FLTK Table Widget// Version: 0.1.0// Started: 11/21/99//// Copyright (C) 1999 Laurence Charlton//// Description:// Flv_Table implements a table/grid. No data is stored// in the widget. Supports headers/footers for rows and columns,// natively supports a single row height and column width per table.// Row and column grids can be turned on and off. Supports no scroll// bars as well as horizontal/vertical automatic or always on scroll bars.// Also support cell selection and row selection modes. In row selection// mode it acts like a pumped-up list widget.// Uses absolute cell 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.// ======================================================================#include <Flek/Flv_Table.H>#include <FL/Enumerations.H>#include <FL/fl_draw.H>#include <stdio.h>#ifdef PIXIL#include <nxapp.h>#endif#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) ((callback_when() & (x))==(x))// Resizing constants#define FUDGE 2#define MOVE_X 1#define MOVE_Y 2#define MOVE_XY (MOVE_X|MOVE_Y)#ifndef max#define max(a,b) ((a)>(b)?(a):(b))#endif#ifndef min#define min(a,b) ((a)<(b)?(a):(b))#endifstatic Fl_Cursor last_cursor = FL_CURSOR_DEFAULT;static int drag_col = -4;static int drag_row = -4;static int anchor_left;static int anchor_top;Flv_Table::Flv_Table(int X, int Y, int W, int H, const char *l):Flv_List(X, Y, W, H, l){ edit_col = -1; vcol = 0; vcols = 0; vcol_width = 40; vmove_on_enter = FLV_MOVE_ON_ENTER_COL_ROW; vselect_col = 0; vbuttons = FLV_BUTTON1 | FLV_BUTTON2 | FLV_BUTTON3;}Flv_Table::~Flv_Table(){}// Probbably won't need to over-ride this for future table widgetsvoidFlv_Table::draw_row(int Offset, int &X, int &Y, int &, int &H, int R){ int c, cw, CX, FW; int dX, dY, dW, dH; int TX, TY, TW, TH; // Calculate clipping height client_area(dX, dY, dW, dH); FW = (col_footer()? col_width(-2) : 0); CX = X; // Draw column header if (col_header()) { cw = col_width(-1); // Column width TX = CX; TY = Y; TW = cw; TH = H; draw_cell(0, TX, TY, TW, TH, R, -1); CX += cw; dX += cw; dW -= cw; } dW -= FW; // Draw column footer if (FW) { TX = dX + dW; TY = Y; TW = FW; TH = H; draw_cell(0, TX, TY, TW, TH, R, -2); } fl_clip(dX, Y, dW, H); // Clip data area for (c = 0; c < vcols && CX - Offset < dX + dW; c++, CX += cw) { cw = col_width(c); // Column width if (CX - Offset + cw < dX) // Before left continue; fl_clip(CX - Offset, Y, cw, H); TX = CX; TY = Y; TW = cw; TH = H; draw_cell(Offset, TX, TY, TW, TH, R, c); fl_pop_clip(); } // If we're selecting a row, put the box around it. if (R == row() && select_row()) { fl_color(fl_contrast(FL_BLACK, selection_color())); fl_rect(dX, Y, dW, H); } // Fill-in area at right of list if (CX - Offset < dX + dW) { cw = dX + dW - (CX - Offset); fl_color(dead_space_color()); fl_rectf(CX - Offset, Y, cw, H); } fl_pop_clip();}#include <FL/Fl_Box.H>// You will certainly want to override thisvoidFlv_Table::draw_cell(int Offset, int &X, int &Y, int &W, int &H, int R, int C){ Fl_Boxtype bt; Flv_Style s; X -= Offset; get_style(s, R, C); if (Fl::focus() == this || persist_select()) add_selection_style(s, R, C); if (row_divider()) s.border(s.border() | FLVB_BOTTOM); if (col_divider()) s.border(s.border() | FLVB_RIGHT); 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()); // Normally you would use the next lines to get the client area to draw X += (Fl::box_dx(bt)); Y += (Fl::box_dy(bt)); W -= (Fl::box_dw(bt)); H -= (Fl::box_dh(bt));#endif // Drawing selection rectangle for cell if (R > -1 && C > -1 && R == row() && C == col() && !select_row() && (Fl::focus() == this || persist_select())) { //fl_color( fl_contrast(text_color(), selection_color()) ); fl_color(FL_RED); fl_rect(X, Y, W, H); } X += s.x_margin(); Y += s.y_margin(); W -= s.x_margin() * 2; H -= s.y_margin() * 2; X += Offset;#ifdef PIXIL NxApp::Instance()->DefaultFont();#else fl_font(s.font(), s.font_size());#endif 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());}boolFlv_Table::get_cell_bounds(int &X, int &Y, int &W, int &H, int R, int C){ int x, y, w, h, r, rh, B, cx; cell_area(x, y, w, h); B = y + h; for (r = top_row(); r < rows() && r < R; y += rh, r++) { rh = row_height(r); if (y > B) break; } if (r != R) return false; Y = y; H = row_height(R); if (Y + H > B) H = B - Y; cx = x - row_offset(); for (r = 0; r < cols() && r < C; cx += rh, r++) { rh = col_width(r); if (cx > x + w) break; } rh = col_width(r); if (r != C || cx + rh < x) { X = Y = W = H = 0; return false; } X = cx; if (X < x) { rh -= (x - X); X = x; } if (X + rh > x + w) rh = (x + w) - X; if (rh > w) rh = w; if (rh < 0) rh = 0; W = rh; return true;}voidFlv_Table::draw(void){ int r, rh, rw; int X, Y, W, H, B, FW; int CX, CY, CW, CH; Flv_Style s; int t, c; // Initially verify we aren't on a locked cell r = row(); c = col(); while (!select_locked()) { get_style(s, r, c); if (!s.locked()) { row(r); col(c); break; } c++; if (c == cols()) { c = 0; if (r == rows()) break; else r++; } } // Make sure we have an editor if editing! /* DF patch if (!veditor && vediting) switch_editor(row(),col()); */ // We need to know what the row width will be // so we'll calculate that and then let normal drawing // take over. if (!feature_test(FLVF_MULTI_SELECT)) select_start_col(vcol); for (c = cols(), rw = t = 0; t < c; t++) rw += col_width(t); if (col_header()) rw += col_width(-1); if (col_footer()) rw += col_width(-2); row_width(rw); // Set the row width so we can draw intelligently start_draw(X, Y, W, H, rw); // This is why draw is here and we're not using the code from // Flv_List... It sucks, but I really didn't like the flickering // from the column footers getting erased and then redrawn... FW = (col_footer()? col_width(-2) : 0); B = W - (rw - row_offset()) - FW; // Fill-in area at right of list if (B > 0) { fl_color(dead_space_color()); fl_rectf(X + rw - row_offset(), Y, B, H); } B = Y + H; fl_clip(X, Y, W, H); // Draw rows for (r = top_row(); Y < B && r < rows(); r++, Y += rh) { rh = row_height(r); if (vlast_row == row() || (vlast_row != row() && (r == vlast_row || r == row()))) { fl_clip(X, Y, W, rh); CX = X; CY = Y; CW = rw; CH = rh; draw_row(row_offset(), CX, CY, CW, CH, r); fl_pop_clip(); } } vlast_row = row(); // Fill-in area at bottom of list if (Y < B) { if (parent()) fl_color(parent()->color()); else fl_color(FL_WHITE); fl_rectf(X, Y, W, B - Y); } fl_pop_clip();// Maybe for internal editors// if (veditor && vediting)// {// veditor->damage(FL_DAMAGE_ALL);// veditor->draw(); // So editor will overlay table// }}voidFlv_Table::add_selection_style(Flv_Style & s, int R, int C){ if (!multi_select()) // If not multi row selection { select_start_row(row()); select_start_col(col()); } if (R > -1 && C > -1) if ((select_row() && row_selected(R)) || (!select_row() && cell_selected(R, C))) {#ifdef PIXIL s.background(NxApp::GlobalColor(HILIGHT));#else s.background(selection_color());#endif s.foreground(selection_text_color()); }}voidFlv_Table::cell_area(int &X, int &Y, int &W, int &H){ client_area(X, Y, W, H); if (label() && *label()) { Y += row_height(FLV_TITLE); H -= row_height(FLV_TITLE); } if (row_header()) { Y += row_height(FLV_ROW_HEADER); H -= row_height(FLV_ROW_HEADER); } if (row_footer()) { H -= row_height(FLV_ROW_FOOTER); } if (col_header()) { X += col_width(FLV_COL_HEADER); W -= col_width(FLV_COL_HEADER); } if (col_footer()) { W -= col_width(FLV_COL_FOOTER); }}boolFlv_Table::cell_selected(int R, int C){ return (col_selected(C) && row_selected(R));}intFlv_Table::col_width(int C) // Get column width{ int fw = vcol_width; Flv_Style *cols; if (global_style.width_defined()) fw = global_style.width(); cols = col_style.find(C); if (cols) if (cols->width_defined()) fw = cols->width(); return fw;}intFlv_Table::col_width(int n, int c) // Set column width{ int cw = col_width(c); if (c < -3) c = -3; if (c >= vcols) c = vcols - 1; if (n < 0) n = 0; if (n != cw) { col_style[c].width(n); damage(FL_DAMAGE_CHILD); } return col_width(c);}voidFlv_Table::get_style(Flv_Style & s, int R, int C){ Flv_Style *rows, *cols, *cells; Flv_List::get_style(s, R); rows = row_style.skip_to(R); if (R != -3) { cols = col_style.skip_to(C); if (cols) s = *cols; } if (C < 0 || R < 0) // Headers/Labels have different default { // Note: we can still override at cell level if (parent()) s.background(parent()->color()); else s.background(FL_WHITE); s.frame(FL_THIN_UP_BOX); s.border(FLVB_NONE); s.border_spacing(0); } cells = (rows ? rows->cell_style.skip_to(C) : NULL); if (cells) s = *cells;}intFlv_Table::handle(int event){ int stat = 0, x, y, X, Y, W, H, r, c; switch (event) { case FL_RELEASE: case FL_DRAG: if (!vediting || !veditor) break; case FL_PUSH:#if FL_MAJOR_VERSION == 2 if (Fl::event_button1() == 0)#else if (Fl::event_state() & FL_BUTTON1 == 0)#endif break; if (drag_row != 4 || drag_col != 4) break; x = Fl::event_x(); y = Fl::event_y(); if (!veditor) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -