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