1 /* grid.cpp is part of UDAV
2 * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17 #include <FL/Fl.H>
18 #include <FL/Fl_Window.H>
19 #include <FL/Fl_Int_Input.H>
20 #include <FL/Fl_Value_Slider.H>
21 #include <FL/fl_draw.H>
22 #include "mgllab.h"
23 //-----------------------------------------------------------------------------
24 Fl_Callback input_cb;
25 //-----------------------------------------------------------------------------
input_cb(Fl_Widget *,void * v)26 void input_cb(Fl_Widget*, void* v) { ((Fl_Data_Table*)v)->set_value(); }
27 //-----------------------------------------------------------------------------
Fl_Data_Table(int x,int y,int w,int h,const char * l)28 Fl_Data_Table::Fl_Data_Table(int x, int y, int w, int h, const char *l) : Fl_Table(x,y,w,h,l)
29 {
30 callback(&event_callback, (void*)this);
31 input = new Fl_Input(w/2,h/2,0,0);
32 input->hide();
33 input->callback(input_cb, (void*)this);
34 input->when(FL_WHEN_ENTER_KEY_ALWAYS);
35 input->maximum_size(16);
36 nx=ny=sl = 0; row=col=-1; data = NULL;
37 // (new Fl_Box(9999,9999,0,0))->hide(); // HACK: prevent flickering in Fl_Scroll
38 end();
39 }
40 //-----------------------------------------------------------------------------
41 // Handle drawing all cells in table
draw_cell(TableContext context,int R,int C,int X,int Y,int W,int H)42 void Fl_Data_Table::draw_cell(TableContext context, int R, int C, int X, int Y, int W, int H)
43 {
44 static char s[64];
45 fl_push_clip(X, Y, W, H);
46 switch ( context )
47 {
48 case CONTEXT_COL_HEADER:
49 fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
50 fl_font(FL_HELVETICA | FL_BOLD, 14);
51 fl_color(FL_BLACK); snprintf(s,32,"%d",C);
52 fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER);
53 break;
54 case CONTEXT_ROW_HEADER:
55 fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
56 fl_font(FL_HELVETICA | FL_BOLD, 14);
57 fl_color(FL_BLACK); snprintf(s,32,"%d",R);
58 fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER);
59 break;
60 case CONTEXT_CELL:
61 if (R == row && C == col && input->visible()) break;
62 fl_draw_box(FL_THIN_DOWN_BOX, X, Y, W, H, FL_WHITE);
63 fl_pop_clip();
64 fl_push_clip(X+3, Y+3, W-6, H-6);
65 fl_font(FL_HELVETICA, 14);
66 if(mgl_isnan(data->v(C,R,sl))) strcpy(s,"nan");
67 else if(mgl_isbad(data->v(C,R,sl))) strcpy(s,data->v(C,R,sl)>0?"inf":"-inf");
68 else mgl_strncpy(s,mgl_str_num(data->vc(C,R,sl)).c_str(),64);
69 { dual vc = data->vc(C,R,sl);
70 mreal v = data->v(C,R,sl);
71 std::vector<mreal> vn;
72 if(C>0) vn.push_back(data->v(C-1,R,sl));
73 if(R>0) vn.push_back(data->v(C,R-1,sl));
74 if(C<data->GetNx()-1) vn.push_back(data->v(C+1,R,sl));
75 if(R<data->GetNy()-1) vn.push_back(data->v(C,R+1,sl));
76 bool v1=true, v2=true;
77 for(size_t i=0;i<vn.size();i++) { if(vn[i]<=v) v1=false; if(vn[i]>=v) v2=false; }
78 if(v2) fl_color(FL_MAGENTA);
79 else if(v1) fl_color(FL_CYAN);
80 else if(real(vc)>0) fl_color(FL_RED);
81 else if(real(vc)<0) fl_color(FL_BLUE);
82 else if(imag(vc)>0) fl_color(FL_DARK_MAGENTA);
83 else if(imag(vc)<0) fl_color(FL_DARK_CYAN);
84 else fl_color(FL_BLACK); }
85 fl_draw(s, X+3, Y+3, W-6, H-6, FL_ALIGN_RIGHT);
86 break;
87 case CONTEXT_RC_RESIZE:
88 if (!input->visible()) break;
89 find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
90 if (X!=input->x() || Y!=input->y() || W!=input->w() || H!=input->h())
91 input->resize(X,Y,W,H);
92 break;
93 default: break;
94 }
95 fl_pop_clip();
96 }
97 //-----------------------------------------------------------------------------
cell_click()98 void Fl_Data_Table::cell_click()
99 {
100 int R = callback_row(), C = callback_col();
101 TableContext context = callback_context();
102
103 if(context==CONTEXT_CELL)
104 {
105 if (input->visible()) set_value();
106 row = R; col = C;
107 int XX,YY,WW,HH;
108 find_cell(CONTEXT_CELL, R, C, XX, YY, WW, HH);
109 input->resize(XX,YY,WW,HH);
110 std::string s;
111 if(mgl_isnan(data->v(C,R,sl))) s = "nan";
112 else if(mgl_isbad(data->v(C,R,sl))) s = data->v(C,R,sl)>0?"inf":"-inf";
113 else s = mgl_str_num(data->vc(C,R,sl));
114 input->value(s.c_str()); input->show();
115 input->take_focus();
116 }
117 }
118 //-----------------------------------------------------------------------------
set_value()119 void Fl_Data_Table::set_value()
120 {
121 const char *s = input->value();
122 if(s[0]==0 || !strcmp(s,"nan")) data->set_v(NAN, col,row,sl);
123 else if(!strcmp(s,"inf")) data->set_v(INFINITY, col,row,sl);
124 else if(!strcmp(s,"-inf")) data->set_v(-INFINITY, col,row,sl);
125 else
126 {
127 dual v = mgl_atoc(s,true);
128 if(imag(v)==0) data->set_v(real(v), col,row,sl);
129 else
130 {
131 HADT c = dynamic_cast<HADT>(data);
132 if(c) c->a[col+c->nx*(row+c->ny*sl)] = v;
133 else data->set_v(abs(v),col,row,sl);
134 }
135 }
136 }
137 //-----------------------------------------------------------------------------
138