Flv_Table.cxx 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663
  1. // ======================================================================
  2. // File: Flv_Table.cxx - Flv_Table implementation
  3. // Program: Flv_Table - FLTK Table Widget
  4. // Version: 0.1.0
  5. // Started: 11/21/99
  6. //
  7. // Copyright (C) 1999 Laurence Charlton
  8. //
  9. // Description:
  10. // Flv_Table implements a table/grid. No data is stored
  11. // in the widget. Supports headers/footers for rows and columns,
  12. // natively supports a single row height and column width per table.
  13. // Row and column grids can be turned on and off. Supports no scroll
  14. // bars as well as horizontal/vertical automatic or always on scroll bars.
  15. // Also support cell selection and row selection modes. In row selection
  16. // mode it acts like a pumped-up list widget.
  17. // Uses absolute cell references.
  18. //
  19. // row -1 is defined as the row header
  20. // row -2 is defined as the row footer
  21. //
  22. // This library is free software; you can redistribute it and/or
  23. // modify it under the terms of the GNU Library General Public
  24. // License as published by the Free Software Foundation; either
  25. // version 2 of the License, or (at your option) any later version.
  26. //
  27. // This library is distributed in the hope that it will be useful,
  28. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  29. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  30. // Library General Public License for more details.
  31. //
  32. // You should have received a copy of the GNU Library General Public
  33. // License along with this library; if not, write to the Free Software
  34. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  35. // USA.
  36. // ======================================================================
  37. #include <FL/Flv_Table.H>
  38. #include <FL/Enumerations.H>
  39. #include <FL/fl_draw.H>
  40. #include <stdio.h>
  41. #define DOcb(x) ((callback_when() & (x))==(x))
  42. // Resizing constants
  43. #define FUDGE 2
  44. #define MOVE_X 1
  45. #define MOVE_Y 2
  46. #define MOVE_XY (MOVE_X|MOVE_Y)
  47. #ifndef max
  48. #define max(a,b) ((a)>(b)?(a):(b))
  49. #endif
  50. #ifndef min
  51. #define min(a,b) ((a)<(b)?(a):(b))
  52. #endif
  53. static Fl_Cursor last_cursor = FL_CURSOR_DEFAULT;
  54. static int drag_col=-4, drag_row=-4, anchor_left, anchor_top;
  55. Flv_Table::Flv_Table( int X, int Y, int W, int H, const char *l ) :
  56. Flv_List(X,Y,W,H,l)
  57. {
  58. edit_col = -1;
  59. vcol = 0;
  60. vcols = 0;
  61. vcol_width = 40;
  62. vmove_on_enter = FLV_MOVE_ON_ENTER_COL_ROW;
  63. vselect_col = 0;
  64. vbuttons = FLV_BUTTON1 | FLV_BUTTON2 | FLV_BUTTON3;
  65. }
  66. Flv_Table::~Flv_Table()
  67. {
  68. }
  69. // Probbably won't need to over-ride this for future table widgets
  70. void Flv_Table::draw_row( int Offset, int &X, int &Y, int &, int &H, int R )
  71. {
  72. int c, cw, CX, FW;
  73. int dX, dY, dW, dH;
  74. int TX, TY, TW, TH;
  75. Flv_Style s;
  76. // Calculate clipping height
  77. client_area(dX,dY,dW,dH);
  78. FW = (col_footer()?col_width(-2):0);
  79. CX = X;
  80. // Draw column header
  81. if (col_header())
  82. {
  83. cw = col_width(-1); // Column width
  84. TX = CX;
  85. TY = Y;
  86. TW = cw;
  87. TH = H;
  88. draw_cell( 0, TX, TY, TW, TH, R, -1 );
  89. CX += cw;
  90. dX += cw;
  91. dW -= cw;
  92. }
  93. dW -= FW;
  94. // Draw column footer
  95. if (FW)
  96. {
  97. TX = dX+dW;
  98. TY = Y;
  99. TW = FW;
  100. TH = H;
  101. draw_cell( 0, TX, TY, TW, TH, R, -2 );
  102. }
  103. fl_clip( dX, Y, dW, H ); // Clip data area
  104. for (c=0; c<vcols && CX-Offset<dX+dW; c++, CX+=cw )
  105. {
  106. cw = col_width(c); // Column width
  107. if (CX-Offset+cw<dX) // Before left
  108. continue;
  109. fl_clip( CX-Offset, Y, cw, H );
  110. TX = CX;
  111. TY = Y;
  112. TW = cw;
  113. TH = H;
  114. draw_cell( Offset, TX, TY, TW, TH, R, c );
  115. fl_pop_clip();
  116. }
  117. // If we're selecting a row, put the box around it.
  118. if (R==row() && select_row() )
  119. {
  120. fl_color( fl_contrast(FL_BLACK, selection_color()) );
  121. fl_rect( dX, Y, dW, H );
  122. }
  123. // Fill-in area at right of list
  124. if (CX-Offset<dX+dW)
  125. {
  126. cw = dX+dW-(CX-Offset);
  127. fl_color( dead_space_color() );
  128. fl_rectf( CX-Offset, Y, cw, H );
  129. }
  130. fl_pop_clip();
  131. }
  132. // You will certainly want to override this
  133. void Flv_Table::draw_cell( int Offset, int &X, int &Y, int &W, int &H, int R, int C )
  134. {
  135. Fl_Boxtype bt;
  136. Flv_Style s;
  137. X -= Offset;
  138. get_style(s, R, C);
  139. if (Fl::focus()==this || persist_select())
  140. add_selection_style(s, R, C);
  141. if (row_divider())
  142. s.border( s.border()|FLVB_BOTTOM );
  143. if (col_divider())
  144. s.border( s.border()|FLVB_RIGHT );
  145. draw_border( s, X, Y, W, H );
  146. bt = s.frame();
  147. fl_color( s.background() );
  148. fl_rectf(X,Y,W,H );
  149. #ifdef FLTK_2
  150. bt->draw(X,Y,W,H,s.background());
  151. // Normally you would use the next line to get the client area to draw
  152. bt->inset( X, Y, W, H );
  153. #else
  154. draw_box( bt, X, Y, W, H, s.background() );
  155. // Normally you would use the next lines to get the client area to draw
  156. X+= (Fl::box_dx(bt));
  157. Y+= (Fl::box_dy(bt));
  158. W-= (Fl::box_dw(bt));
  159. H-= (Fl::box_dh(bt));
  160. #endif
  161. // Drawing selection rectangle for cell
  162. if (R>-1 && C>-1 && R==row() && C==col() && !select_row() &&
  163. (Fl::focus()==this || persist_select()))
  164. {
  165. fl_color( fl_contrast(text_color(), selection_color()) );
  166. fl_rect( X, Y, W, H);
  167. }
  168. X+=s.x_margin();
  169. Y+=s.y_margin();
  170. W-=s.x_margin()*2;
  171. H-=s.y_margin()*2;
  172. X += Offset;
  173. // Get set-up to draw text
  174. fl_font( s.font(), s.font_size() );
  175. if (!active())
  176. s.foreground( fl_inactive(s.foreground()) );
  177. fl_color(s.foreground());
  178. }
  179. bool Flv_Table::get_cell_bounds( int &X, int &Y, int &W, int &H, int R, int C )
  180. {
  181. int x, y, w, h, r, rh, B, cx;
  182. X = Y = W = H = 0;
  183. cell_area(x,y,w,h);
  184. B = y+h;
  185. for (r=top_row(); r<rows() && r<R; y += rh, r++ )
  186. {
  187. rh = row_height(r);
  188. if (y>B)
  189. break;
  190. }
  191. if (r!=R)
  192. return false;
  193. Y = y;
  194. H = row_height(R);
  195. if (Y+H>B)
  196. H = B-Y;
  197. cx = x - row_offset();
  198. for (r=0; r<cols() && r<C; cx += rh, r++ )
  199. {
  200. rh = col_width(r);
  201. if (cx>x+w)
  202. break;
  203. }
  204. rh = col_width(r);
  205. if (r!=C || cx+rh<x)
  206. {
  207. X = Y = W = H = 0;
  208. return false;
  209. }
  210. X = cx;
  211. if (X<x)
  212. {
  213. rh -= (x-X);
  214. X = x;
  215. }
  216. if (X+rh>x+w)
  217. rh = (x+w)-X;
  218. if (rh>w)
  219. rh = w;
  220. if (rh<0)
  221. rh = 0;
  222. W = rh;
  223. return true;
  224. }
  225. void Flv_Table::draw(void)
  226. {
  227. int r, rh, rw;
  228. int X, Y, W, H, B, FW;
  229. int CX, CY, CW, CH;
  230. Flv_Style s;
  231. int t, c;
  232. //char buf[30];
  233. // Initially verify we aren't on a locked cell
  234. r = row();
  235. c = col();
  236. while(!select_locked())
  237. {
  238. get_style(s,r,c);
  239. if (!s.locked())
  240. {
  241. row(r);
  242. col(c);
  243. break;
  244. }
  245. c++;
  246. if (c==cols())
  247. {
  248. c = 0;
  249. r++;
  250. if (r==rows())
  251. break;
  252. }
  253. }
  254. // Make sure we have an editor if editing!
  255. // if (!veditor && vediting)
  256. // switch_editor(row(),col());
  257. // We need to know what the row width will be
  258. // so we'll calculate that and then let normal drawing
  259. // take over.
  260. if (!feature_test(FLVF_MULTI_SELECT))
  261. select_start_col(vcol);
  262. for (c=cols(), rw=t=0; t<c; t++ )
  263. rw += col_width(t);
  264. if (col_header())
  265. rw += col_width(-1);
  266. if (col_footer())
  267. rw += col_width(-2);
  268. row_width(rw); // Set the row width so we can draw intelligently
  269. start_draw(X,Y,W,H,rw);
  270. // This is why draw is here and we're not using the code from
  271. // Flv_List... It sucks, but I really didn't like the flickering
  272. // from the column footers getting erased and then redrawn...
  273. FW = (col_footer()?col_width(-2):0);
  274. B = W-(rw-row_offset())-FW;
  275. // Fill-in area at right of list
  276. if (B>0)
  277. {
  278. fl_color( dead_space_color() );
  279. fl_rectf( X+rw-row_offset(), Y, B, H );
  280. }
  281. B = Y + H;
  282. fl_clip( X, Y, W, H );
  283. // Draw rows
  284. for ( r=top_row(); Y<B && r<rows(); r++, Y+=rh )
  285. {
  286. rh = row_height(r);
  287. if ( vlast_row==row() || (vlast_row!=row() && (r==vlast_row || r==row())) )
  288. {
  289. fl_clip( X, Y, W, rh);
  290. CX=X;
  291. CY=Y;
  292. CW=rw;
  293. CH=rh;
  294. draw_row( row_offset(), CX, CY, CW, CH, r );
  295. fl_pop_clip();
  296. }
  297. }
  298. vlast_row = row();
  299. // Fill-in area at bottom of list
  300. if (Y<B)
  301. {
  302. fl_color( dead_space_color() );
  303. fl_rectf( X, Y, W, B-Y );
  304. }
  305. fl_pop_clip();
  306. }
  307. void Flv_Table::add_selection_style( Flv_Style &s, int R, int C )
  308. {
  309. if (!multi_select()) // If not multi row selection
  310. {
  311. select_start_row( row() );
  312. select_start_col( col() );
  313. }
  314. if (R>-1 && C>-1)
  315. if ( (select_row() && row_selected(R)) ||
  316. (!select_row() && cell_selected(R,C)) )
  317. {
  318. if(Fl::focus() != this)
  319. {
  320. s.background( fl_color_average(selection_color(), FL_WHITE, 0.4) );
  321. s.foreground( text_color());
  322. }
  323. else
  324. {
  325. s.background( selection_color() );
  326. s.foreground( selection_text_color());
  327. }
  328. }
  329. }
  330. void Flv_Table::cell_area(int &X, int &Y, int &W, int &H )
  331. {
  332. client_area(X,Y,W,H);
  333. if (label() && *label())
  334. {
  335. Y += row_height(FLV_TITLE);
  336. H -= row_height(FLV_TITLE);
  337. }
  338. if (row_header())
  339. {
  340. Y += row_height(FLV_ROW_HEADER);
  341. H -= row_height(FLV_ROW_HEADER);
  342. }
  343. if (row_footer())
  344. {
  345. H -= row_height(FLV_ROW_FOOTER);
  346. }
  347. if (col_header())
  348. {
  349. X += col_width(FLV_COL_HEADER);
  350. W -= col_width(FLV_COL_HEADER);
  351. }
  352. if (col_footer())
  353. {
  354. W -= col_width(FLV_COL_FOOTER);
  355. }
  356. }
  357. bool Flv_Table::cell_selected(int R, int C)
  358. {
  359. return (col_selected(C) && row_selected(R));
  360. }
  361. int Flv_Table::col_width(int C) // Get column width
  362. {
  363. int fw = vcol_width;
  364. Flv_Style *cols;
  365. if (global_style.width_defined())
  366. fw = global_style.width();
  367. cols = col_style.find(C);
  368. if (cols)
  369. if (cols->width_defined())
  370. fw = cols->width();
  371. return fw;
  372. }
  373. int Flv_Table::col_width(int n, int c) // Set column width
  374. {
  375. int cw = col_width(c);
  376. if (c<-3) c=-3;
  377. if (c>=vcols) c=vcols-1;
  378. if (n<0) n=0;
  379. if (n!=cw)
  380. {
  381. col_style[c].width(n);
  382. damage(FL_DAMAGE_CHILD);
  383. }
  384. return col_width(c);
  385. }
  386. void Flv_Table::get_style( Flv_Style &s, int R, int C )
  387. {
  388. Flv_Style *rows, *cols, *cells;
  389. Flv_List::get_style( s, R );
  390. rows = row_style.skip_to(R);
  391. if (R!=-3)
  392. {
  393. cols = col_style.skip_to(C);
  394. if (cols) s = *cols;
  395. }
  396. if (C<0 || R<0) // Headers/Labels have different default
  397. {
  398. // Note: we can still override at cell level
  399. if (parent())
  400. s.background( parent()->color() );
  401. else
  402. s.background( FL_WHITE );
  403. s.frame(FL_THIN_UP_BOX);
  404. s.border( FLVB_NONE );
  405. s.border_spacing(0);
  406. }
  407. cells = (rows?rows->cell_style.skip_to(C):NULL);
  408. if (cells) s = *cells;
  409. }
  410. int Flv_Table::handle(int event)
  411. {
  412. int stat=0, x, y, X,Y,W,H, r, c;
  413. Flv_Style s;
  414. switch(event)
  415. {
  416. case FL_RELEASE:
  417. case FL_DRAG:
  418. if (!vediting || !veditor)
  419. break;
  420. case FL_PUSH:
  421. if (Fl::event_button1()==0)
  422. break;
  423. if (drag_row!=-4 || drag_col!=-4)
  424. break;
  425. x = Fl::event_x();
  426. y = Fl::event_y();
  427. if (!vediting)
  428. {
  429. if (edit_when()==FLV_EDIT_MANUAL)
  430. break;
  431. r = row();
  432. c = col();
  433. if (r<0 || c<0)
  434. break;
  435. cell_area(X,Y,W,H);
  436. stat = internal_handle(event);
  437. if (stat && r==row() && c==col() && x>=X && x<X+W && y>=Y && y<Y+H )
  438. {
  439. start_edit();
  440. return 1;
  441. }
  442. return 0;
  443. }
  444. // If these are occur outside the editor, we don't want the
  445. // child widget processing them
  446. if (x<veditor->x() || y<veditor->y() || x>veditor->x()+veditor->w() ||
  447. y>veditor->y()+veditor->h())
  448. break;
  449. stat = veditor->handle(event);
  450. if (stat)
  451. {
  452. veditor->draw();
  453. return 1;
  454. }
  455. break;
  456. }
  457. if (event==FL_SHORTCUT && vediting)
  458. {
  459. if (Fl::event_key()==FL_Enter)
  460. {
  461. end_edit(); // Save editor/ quit editing
  462. Fl::focus(this);
  463. // take_focus();
  464. internal_handle(FL_KEYBOARD);
  465. damage(FL_DAMAGE_CHILD);
  466. return 1;
  467. }
  468. switch( Fl::event_key() )
  469. {
  470. case FL_Shift_L:
  471. case FL_Shift_R:
  472. case FL_Control_L:
  473. case FL_Control_R:
  474. case FL_Meta_L:
  475. case FL_Meta_R:
  476. case FL_Alt_L:
  477. case FL_Alt_R:
  478. break;
  479. default:
  480. stat = internal_handle(FL_KEYBOARD);
  481. }
  482. }
  483. else
  484. {
  485. stat = internal_handle(event);
  486. if (!stat)
  487. {
  488. // Jump start editing if automatic
  489. if (event==FL_KEYBOARD && !vediting && edit_when()==FLV_EDIT_AUTOMATIC )
  490. {
  491. switch( Fl::event_key() )
  492. {
  493. case FL_Shift_L:
  494. case FL_Shift_R:
  495. case FL_Control_L:
  496. case FL_Control_R:
  497. case FL_Meta_L:
  498. case FL_Meta_R:
  499. case FL_Alt_L:
  500. case FL_Alt_R:
  501. break;
  502. default:
  503. start_edit();
  504. if (veditor)
  505. {
  506. stat = veditor->handle(event);
  507. if (stat)
  508. {
  509. Fl::focus(veditor);
  510. // veditor->take_focus();
  511. veditor->draw();
  512. return 1;
  513. }
  514. }
  515. cancel_edit();
  516. }
  517. }
  518. }
  519. }
  520. if (veditor && Fl::focus()==this)
  521. {
  522. Fl::focus(veditor);
  523. // veditor->take_focus();
  524. veditor->handle(FL_FOCUS);
  525. }
  526. if (stat && veditor)
  527. veditor->draw();
  528. return stat;
  529. }
  530. static int _last_click_y = 0;
  531. static int _scroll_direction = 0;
  532. static int _timeout_count = 0;
  533. static void _scrollerCB(void *ud)
  534. {
  535. if(_timeout_count){
  536. _timeout_count--;
  537. Flv_Table *table = (Flv_Table*)ud;
  538. Fl::repeat_timeout( 0.05, _scrollerCB, table );
  539. //redraw();
  540. Fl::e_keysym = _scroll_direction < 0 ? FL_Up : FL_Down;
  541. table->handle(FL_KEYBOARD);
  542. }
  543. }
  544. int Flv_Table::internal_handle(int event)
  545. {
  546. int TX, TY, r, c, cd, rd;
  547. Flv_Style s;
  548. static int LX, LY;
  549. switch( event )
  550. {
  551. case FL_KEYBOARD:
  552. break;
  553. case FL_ENTER:
  554. case FL_LEAVE:
  555. vclicks = 0;
  556. return Fl_Group::handle(event);
  557. case FL_FOCUS:
  558. if(rows() == 0) return 0;
  559. case FL_UNFOCUS:
  560. if(rows() > 0) redraw();
  561. return 1;
  562. case FL_MOVE:
  563. TY = Fl::event_y();
  564. TX = Fl::event_x();
  565. if ( LX-TX<-3 || LX-TX>3 || LY-TY<-3 || LY-TY>3 )
  566. {
  567. LX = TX;
  568. LY = TY;
  569. vclicks = 0;
  570. }
  571. check_cursor();
  572. return Fl_Group::handle(event);
  573. case FL_RELEASE:
  574. if(is_dragging){
  575. is_dragging = false;
  576. /*
  577. int time_span = Fl::getMilliSpan(last_click_timestamp);
  578. if(time_span <= 50){
  579. _scroll_direction = Fl::event_y() - _last_click_y;
  580. _timeout_count = (50-time_span)/2;
  581. Fl::add_timeout( 0.1, _scrollerCB, this );
  582. }
  583. */
  584. }
  585. drag_row = drag_col = -4;
  586. Fl_Group::handle(event);
  587. return 1;
  588. case FL_DRAG:
  589. vclicks=0;
  590. is_dragging = true;
  591. if (check_resize())
  592. return 1;
  593. case FL_PUSH:
  594. last_click_timestamp = Fl::getMilliCount();
  595. _timeout_count = 0;
  596. if(!is_dragging)_last_click_y = Fl::event_y();
  597. // Dragging not clicking
  598. if (drag_row!=-4 || drag_col != -4)
  599. return 1;
  600. r = 0;
  601. if (Fl::event_button1() && (buttons() & FLV_BUTTON1)) r=1;
  602. if (Fl::event_button2() && (buttons() & FLV_BUTTON2)) r=1;
  603. if (Fl::event_button3() && (buttons() & FLV_BUTTON3)) r=1;
  604. if (r==0)
  605. {
  606. vclicks = 0;
  607. return 0;
  608. }
  609. // Determine if col was clicked and highlight it
  610. TY = Fl::event_y();
  611. TX = Fl::event_x();
  612. r = get_row(TX,TY);
  613. c = get_col(TX,TY);
  614. //bug that prevents handle click on scrollbars
  615. //if (r==-4 && c==-4)
  616. if (r<0 && c<0)
  617. {
  618. vclicks = 0;
  619. return Fl_Group::handle(event);
  620. }
  621. if ( LX-TX>-3 && LX-TX<3 && LY-TY>-3 && LY-TY<3)
  622. vclicks++;
  623. else
  624. {
  625. vclicks=1;
  626. LX = TX;
  627. LY = TY;
  628. }
  629. damage(FL_DAMAGE_CHILD);
  630. rd = (r>row()?1:r==row()?0:-1);
  631. cd = (c>col()?1:c==col()?0:-1);
  632. if (r>=0)
  633. row(r);
  634. if (c>=0)
  635. col(c);
  636. if (!multi_select() ||
  637. (event==FL_PUSH && !Fl::event_state(FL_SHIFT)))
  638. {
  639. select_start_row(row());
  640. select_start_col(col());
  641. }
  642. // At least one header clicked
  643. if (r<0 || c<0)
  644. {
  645. if (r>-4 && c>-4 && r<0 && c<0 && r!=-3)
  646. {
  647. if ( DOcb(FLVEcb_ALL_CLICKED) )
  648. {
  649. vwhy_event = FLVE_ALL_CLICKED;
  650. do_callback(this, user_data());
  651. vwhy_event = 0;
  652. }
  653. return 1;
  654. }
  655. if ( c>=0 || r==-3 )
  656. {
  657. vwhy_event = 0;
  658. switch( r )
  659. {
  660. case -3:
  661. if (DOcb(FLVEcb_TITLE_CLICKED))
  662. vwhy_event = FLVE_TITLE_CLICKED;
  663. break;
  664. case -2:
  665. if (DOcb(FLVEcb_ROW_FOOTER_CLICKED))
  666. vwhy_event = FLVE_ROW_FOOTER_CLICKED;
  667. break;
  668. case -1:
  669. if (DOcb(FLVEcb_ROW_HEADER_CLICKED))
  670. vwhy_event = FLVE_ROW_HEADER_CLICKED;
  671. break;
  672. }
  673. if (vwhy_event)
  674. {
  675. do_callback(this, user_data());
  676. vwhy_event = 0;
  677. return 1;
  678. }
  679. }
  680. if ( r>=0 )
  681. {
  682. vwhy_event = 0;
  683. switch( c )
  684. {
  685. case -2:
  686. if (DOcb(FLVEcb_COL_FOOTER_CLICKED))
  687. vwhy_event = FLVE_COL_FOOTER_CLICKED;
  688. break;
  689. case -1:
  690. if (DOcb(FLVEcb_COL_HEADER_CLICKED))
  691. vwhy_event = FLVE_COL_HEADER_CLICKED;
  692. break;
  693. }
  694. if (vwhy_event)
  695. {
  696. do_callback(this, user_data());
  697. vwhy_event = 0;
  698. return 1;
  699. }
  700. }
  701. return 0;
  702. }
  703. if (event==FL_PUSH && (rd || cd))
  704. {
  705. // Skip over locked cells
  706. while(!select_locked())
  707. {
  708. get_style(s,r,c);
  709. if (!s.locked())
  710. {
  711. if (r!=row() || c!=col())
  712. vclicks=0;
  713. row(r);
  714. col(c);
  715. break;
  716. }
  717. r += rd;
  718. c += cd;
  719. if ( r<0 || r>=rows() || c<0 || c>=cols() )
  720. break;
  721. }
  722. }
  723. if (event==FL_PUSH)
  724. {
  725. if (DOcb(FLVEcb_CLICKED))
  726. {
  727. vwhy_event = FLVE_CLICKED;
  728. do_callback(this, user_data());
  729. vwhy_event = 0;
  730. }
  731. if (vclicks>=vmax_clicks)
  732. vclicks=0;
  733. }
  734. return 1;
  735. default:
  736. return Fl_Group::handle(event);
  737. }
  738. switch(Fl::event_key())
  739. {
  740. case FL_Enter:
  741. switch( vmove_on_enter)
  742. {
  743. case FLV_MOVE_ON_ENTER_ROW_COL:
  744. if (!move_row(1))
  745. {
  746. row(0);
  747. col(col()+1);
  748. if (!select_locked())
  749. {
  750. //get_style(s,r,col());
  751. get_style(s,r,col());
  752. if (!s.locked())
  753. move_row(1);
  754. }
  755. }
  756. return 1;
  757. case FLV_MOVE_ON_ENTER_COL_ROW:
  758. if (!move_col(1))
  759. {
  760. col(0);
  761. row(row()+1);
  762. if (!select_locked())
  763. {
  764. get_style(s,r,col());
  765. if (!s.locked())
  766. move_row(1);
  767. }
  768. }
  769. return 1;
  770. }
  771. return 0;
  772. case FL_Up:
  773. if (Fl::event_state(FL_CTRL))
  774. move_row(-row());
  775. else
  776. move_row(-1);
  777. break;
  778. case FL_Down:
  779. if (Fl::event_state(FL_CTRL))
  780. move_row(rows());
  781. else
  782. move_row(1);
  783. break;
  784. case FL_Page_Down:
  785. if (Fl::event_state(FL_CTRL))
  786. move_row( rows() );
  787. else
  788. move_row(page_size());
  789. break;
  790. case FL_Page_Up:
  791. if (Fl::event_state(FL_CTRL))
  792. move_row(-row());
  793. else
  794. move_row(-page_size());
  795. break;
  796. case FL_Home:
  797. // Adjust rows before columns so we redraw everything
  798. if (Fl::event_state(FL_CTRL))
  799. move_row(-rows());
  800. move_col(-cols());
  801. break;
  802. case FL_End:
  803. // Adjust rows before columns so we redraw everything
  804. if (Fl::event_state(FL_CTRL))
  805. move_row(rows());
  806. move_col(cols());
  807. break;
  808. case FL_Right:
  809. if (select_row())
  810. return 0;
  811. if (Fl::event_state(FL_CTRL))
  812. move_col(cols());
  813. else
  814. move_col(1);
  815. break;
  816. case FL_Left:
  817. if (select_row())
  818. return 0;
  819. if (Fl::event_state(FL_CTRL))
  820. move_col(-col());
  821. else
  822. move_col(-1);
  823. break;
  824. default:
  825. return Fl_Group::handle(event);
  826. }
  827. if (!multi_select() || !Fl::event_state(FL_SHIFT))
  828. {
  829. select_start_col(col());
  830. select_start_row(row());
  831. }
  832. return 1;
  833. }
  834. int Flv_Table::row(int n)
  835. {
  836. int X,Y,W,H;
  837. if (n>=rows())
  838. n=rows()-1;
  839. if (n<0)
  840. n=0;
  841. if (n!=vrow)
  842. {
  843. vrow = n;
  844. client_area(X,Y,W,H);
  845. update_top_row(H);
  846. end_edit();
  847. if (edit_when()==FLV_EDIT_ALWAYS)
  848. switch_editor( row(), col() );
  849. vlast_row = vrow;
  850. if (DOcb(FLVEcb_ROW_CHANGED))
  851. {
  852. vwhy_event = FLVE_ROW_CHANGED;
  853. do_callback(this, user_data());
  854. vwhy_event = 0;
  855. }
  856. damage(FL_DAMAGE_CHILD);
  857. }
  858. return vrow;
  859. }
  860. int Flv_Table::col( int n )
  861. {
  862. Flv_Style s;
  863. if (n>=vcols)
  864. n=vcols-1;
  865. if (n<0)
  866. n=0;
  867. if(n==0)
  868. {
  869. if(hscrollbar.value())
  870. {
  871. hscrollbar.value(0);
  872. hscrollbar.do_callback();
  873. }
  874. }
  875. if (n!=vcol)
  876. {
  877. vcol = n;
  878. end_edit();
  879. if (edit_when()==FLV_EDIT_ALWAYS)
  880. switch_editor( row(), col() );
  881. adjust_for_cell();
  882. if (DOcb(FLVEcb_COL_CHANGED))
  883. {
  884. vwhy_event = FLVE_COL_CHANGED;
  885. do_callback(this, user_data());
  886. vwhy_event = 0;
  887. }
  888. damage(FL_DAMAGE_CHILD);
  889. }
  890. return vcol;
  891. }
  892. bool Flv_Table::col_resizable(int c) // Get/set column locked status
  893. {
  894. Flv_Style *s;
  895. bool l=true;
  896. if (global_style.resizable_defined())
  897. l = global_style.resizable();
  898. s = col_style.find(c);
  899. if (s)
  900. if (s->resizable_defined())
  901. l = s->resizable();
  902. return l;
  903. }
  904. bool Flv_Table::col_resizable( bool n, int c)
  905. {
  906. col_style[c].resizable(n);
  907. return n;
  908. }
  909. int Flv_Table::cols( int n )
  910. {
  911. if (n>=0 && n!=vcols)
  912. {
  913. vcols = n;
  914. if (vcol>=vcols)
  915. col(vcols-1);
  916. if (vselect_col>vcol)
  917. select_start_col(vcol);
  918. update_width();
  919. if (DOcb(FLVEcb_COLS_CHANGED))
  920. {
  921. vwhy_event = FLVE_COLS_CHANGED;
  922. do_callback(this, user_data());
  923. vwhy_event = 0;
  924. }
  925. damage(FL_DAMAGE_CHILD);
  926. }
  927. return vcols;
  928. }
  929. bool Flv_Table::col_selected(int n)
  930. {
  931. if (vselect_col<vcol)
  932. return (vselect_col<=n && n<=vcol);
  933. else
  934. return (vcol<=n && n<=vselect_col);
  935. }
  936. // Get column from x,y
  937. int Flv_Table::get_col( int x, int y )
  938. {
  939. int X, Y, W, H, CX;
  940. int rw, cw, t, Offset;
  941. client_area(X,Y,W,H);
  942. if (label())
  943. {
  944. cw = row_height(-3);
  945. Y+=cw;
  946. H-=cw;
  947. }
  948. if (col_header())
  949. {
  950. cw = col_width(-1);
  951. if (X<=x && x<=X+cw)
  952. return -1;
  953. X+=cw;
  954. W-=cw;
  955. }
  956. if (col_footer())
  957. {
  958. cw = col_width(-2);
  959. if (X+W>=x && x>=X+W-cw)
  960. return -2;
  961. W -= cw;
  962. }
  963. rw = row_width();
  964. if (!rw)
  965. rw = W;
  966. if ( x<X || x>=X+W || y<Y || y>=Y+H || x>X-row_offset()+rw)
  967. return -4;
  968. Offset = row_offset();
  969. for (CX=X, t=0; t<vcols && CX-Offset<X+W; t++, CX+=cw )
  970. {
  971. cw = col_width(t);
  972. if (x>=CX-Offset && x<CX-Offset+cw)
  973. return t;
  974. }
  975. return -4; // In grey area at bottom?
  976. }
  977. int Flv_Table::select_start_col(int n)
  978. {
  979. if (n>=vcols)
  980. n=vcols-1;
  981. if (n<0)
  982. n=0;
  983. if (n!=vselect_col)
  984. {
  985. vselect_col = n;
  986. if (DOcb(FLVEcb_SELECTION_CHANGED))
  987. {
  988. vwhy_event = FLVE_SELECTION_CHANGED;
  989. do_callback(this, user_data());
  990. vwhy_event = 0;
  991. }
  992. damage(FL_DAMAGE_CHILD);
  993. }
  994. return vselect_col;
  995. }
  996. void Flv_Table::update_width()
  997. {
  998. int rw, n;
  999. for (rw=n=0; n<vcols; n++ )
  1000. rw+=(col_width(n));
  1001. if (col_header())
  1002. rw+=col_width(-1);
  1003. if (col_footer())
  1004. rw+=col_width(-2);
  1005. if (rw!=row_width())
  1006. {
  1007. row_width(rw);
  1008. damage(FL_DAMAGE_CHILD);
  1009. }
  1010. }
  1011. void Flv_Table::adjust_for_cell()
  1012. {
  1013. int n, o, cw;
  1014. int X, Y, W, H;
  1015. for (n=o=0; n<col(); n++ )
  1016. o+=col_width(n);
  1017. if (row_offset()>o)
  1018. row_offset(o);
  1019. else
  1020. {
  1021. client_area(X,Y,W,H);
  1022. if (col_footer())
  1023. W -= col_width(-2);
  1024. if (col_header())
  1025. W -= col_width(-2);
  1026. cw = col_width(col());
  1027. if (o+cw-row_offset()>W)
  1028. {
  1029. row_offset(o+cw-W);
  1030. damage(FL_DAMAGE_CHILD);
  1031. }
  1032. }
  1033. }
  1034. bool Flv_Table::check_resize(void)
  1035. {
  1036. int ex, ey, v;
  1037. int X, Y, W, H;
  1038. if (drag_row<-3 && drag_col<-2)
  1039. return false;
  1040. client_area(X,Y,W,H);
  1041. ex = Fl::event_x();
  1042. ey = Fl::event_y();
  1043. if (drag_row==-3)
  1044. {
  1045. v = ey-anchor_top;
  1046. if (v<2) v=2;
  1047. row_style[drag_row].height(v);
  1048. damage(FL_DAMAGE_CHILD);
  1049. return true;
  1050. }
  1051. if (label() && *label())
  1052. {
  1053. Y += row_height(-3);
  1054. H -= row_height(-3);
  1055. }
  1056. if (drag_col>-3)
  1057. {
  1058. if (drag_col==-2)
  1059. {
  1060. v = anchor_left - ex + col_width(drag_col);
  1061. if (col_header())
  1062. {
  1063. X += col_width(-1);
  1064. W -= col_width(-1);
  1065. }
  1066. if (v>W-1)
  1067. {
  1068. v = W-1;
  1069. anchor_left = X+W-v;
  1070. }
  1071. if (v<2)
  1072. {
  1073. v=2;
  1074. anchor_left = X+W-2;
  1075. }
  1076. col_style[drag_col].width(v);
  1077. damage(FL_DAMAGE_CHILD);
  1078. if (v!=W-1 && v!=2)
  1079. anchor_left = ex;
  1080. }
  1081. else
  1082. {
  1083. v = ex-anchor_left;
  1084. if (drag_col==-1)
  1085. {
  1086. // Make sure it's in the grid
  1087. if (col_footer())
  1088. W-=col_width(-2);
  1089. if (v > W-1 )
  1090. v = W-1;
  1091. }
  1092. if (v<2)
  1093. v=2;
  1094. col_width(v,drag_col);
  1095. damage(FL_DAMAGE_CHILD);
  1096. }
  1097. }
  1098. // Resize row
  1099. if (drag_row>-4)
  1100. {
  1101. if (drag_row==-2)
  1102. {
  1103. v = anchor_top - ey + row_height(drag_row);
  1104. if (row_header())
  1105. {
  1106. H-=row_height(-1);
  1107. Y+=row_height(-1);
  1108. }
  1109. if (v>H-1)
  1110. {
  1111. v = H-1;
  1112. anchor_top = Y+H-v;
  1113. }
  1114. if (v<2)
  1115. {
  1116. v = 2;
  1117. anchor_top = Y+H-2;
  1118. }
  1119. row_style[drag_row].height(v);
  1120. damage(FL_DAMAGE_CHILD);
  1121. if (v!=2 && v!=H-1)
  1122. anchor_top = ey;
  1123. }
  1124. else
  1125. {
  1126. v = ey-anchor_top;
  1127. if (drag_row==-1)
  1128. {
  1129. if (row_footer())
  1130. H-=row_height(-2);
  1131. if (v>H-1)
  1132. v = H-1;
  1133. }
  1134. if (v<2) v=2;
  1135. row_height(v,drag_row);
  1136. damage(FL_DAMAGE_CHILD);
  1137. }
  1138. }
  1139. return true;
  1140. }
  1141. // See if we can resize, if so change cursor
  1142. void Flv_Table::check_cursor(void)
  1143. {
  1144. int X, Y, W, H, R, ey, ex, move=0, WW, size;
  1145. int v;
  1146. bool resize, inh, inv;
  1147. Fl_Cursor cursor;
  1148. // Assume total miss
  1149. drag_row = drag_col = -4;
  1150. cursor = FL_CURSOR_DEFAULT;
  1151. ex = Fl::event_x();
  1152. ey = Fl::event_y();
  1153. client_area(X,Y,W,H);
  1154. inh = (ex>=X && ex<X+W);
  1155. inv = (ey>=Y && ey<Y+H);
  1156. if (label() && *label())
  1157. {
  1158. size = row_height(-3);
  1159. Y+=size;
  1160. H-=size;
  1161. resize = (ey>=Y-FUDGE && ey<=Y+FUDGE && inh);
  1162. if (resize)
  1163. {
  1164. if (row_resizable(-3))
  1165. {
  1166. drag_row = -3;
  1167. anchor_top = Y-size;
  1168. move |= MOVE_Y;
  1169. }
  1170. }
  1171. }
  1172. // Trival tests to see if we're in region
  1173. resize = full_resize();
  1174. if (!resize)
  1175. {
  1176. if (row_header())
  1177. {
  1178. size = row_height(-1);
  1179. resize |= (ey>=Y && ey<=Y+size+FUDGE && inh);
  1180. }
  1181. if (!resize)
  1182. {
  1183. if (row_footer())
  1184. {
  1185. size = row_height(-2);
  1186. resize |= (ey<=Y+H && ey>=Y+H-size-FUDGE && inh);
  1187. }
  1188. if (!resize)
  1189. {
  1190. if (col_header())
  1191. {
  1192. size = col_width(-1);
  1193. resize |= (ex>=X && ex<=X+size+FUDGE && inh);
  1194. }
  1195. if (!resize)
  1196. {
  1197. if (col_footer())
  1198. {
  1199. size = col_width(-2);
  1200. resize |= (ex<=X+W && ex>=X+W-size-FUDGE && inh);
  1201. }
  1202. }
  1203. }
  1204. }
  1205. }
  1206. if (!resize) // In general region?
  1207. {
  1208. if (cursor!=last_cursor)
  1209. {
  1210. fl_cursor(cursor,FL_BLACK,FL_WHITE);
  1211. last_cursor = cursor;
  1212. }
  1213. return;
  1214. }
  1215. // ==================================================================
  1216. // Sweep columns
  1217. WW = X;
  1218. if (col_header())
  1219. {
  1220. size = col_width(-1);
  1221. if (ex>=WW+size-FUDGE && ex<=WW+size+FUDGE && inv)
  1222. {
  1223. if (col_resizable(-1) && (move & MOVE_Y)==0)
  1224. {
  1225. drag_col = -1;
  1226. anchor_left = WW;
  1227. move |= MOVE_X;
  1228. }
  1229. }
  1230. WW += size;
  1231. X += size;
  1232. W -= size;
  1233. }
  1234. if (col_footer())
  1235. {
  1236. size = col_width(-2);
  1237. if (ex>=X+W-size-FUDGE && ex<=X+W-size+FUDGE && inv)
  1238. {
  1239. if (col_resizable(-2))
  1240. {
  1241. drag_col = -2;
  1242. anchor_left = ex;
  1243. move |= MOVE_X;
  1244. }
  1245. }
  1246. W -= size;
  1247. }
  1248. if ( (move & MOVE_X)==0 )
  1249. {
  1250. R = X-row_offset()+row_width()+FUDGE; // Right edge of row
  1251. for (WW-=row_offset(), v=0; WW<R && WW<X+W && v<cols(); WW+=size, v++ )
  1252. {
  1253. size = col_width(v);
  1254. if (WW+size<X) // Off left
  1255. continue;
  1256. if (ex>=WW+size-FUDGE && ex<=WW+size+FUDGE && inv)
  1257. {
  1258. if (col_resizable(v))
  1259. {
  1260. drag_col = v;
  1261. anchor_left = WW;
  1262. move |= MOVE_X; // Moving col
  1263. }
  1264. break;
  1265. }
  1266. }
  1267. }
  1268. if (col_header())
  1269. {
  1270. X-=col_width(-1);
  1271. W+=col_width(-1);
  1272. }
  1273. if (col_footer())
  1274. W+=col_width(-2);
  1275. // ==================================================================
  1276. // Sweep rows
  1277. WW = Y;
  1278. if (row_header())
  1279. {
  1280. size = row_height(-1);
  1281. if (ey>=WW+size-FUDGE && ey<=WW+size+FUDGE && inh)
  1282. {
  1283. if (row_resizable(-1))
  1284. {
  1285. drag_row = -1;
  1286. anchor_top = WW;
  1287. move |= MOVE_Y;
  1288. }
  1289. }
  1290. WW += size;
  1291. Y += size;
  1292. H -= size;
  1293. }
  1294. if (row_footer())
  1295. {
  1296. size = row_height(-2);
  1297. if (ey>=Y+H-size-FUDGE && ey<=Y+H-size+FUDGE && inh)
  1298. {
  1299. if (row_resizable(-2))
  1300. {
  1301. drag_row = -2;
  1302. anchor_top = ey;
  1303. move |= MOVE_Y;
  1304. }
  1305. }
  1306. H -= size;
  1307. }
  1308. if ( (move & MOVE_Y)==0 )
  1309. {
  1310. for (v=top_row(); v<rows(); WW+=size, v++ )
  1311. {
  1312. size = row_height(v);
  1313. if (WW+size-FUDGE>=Y+H)
  1314. break;
  1315. if (ey>=WW+size-FUDGE && ey<=WW+size+FUDGE && inh)
  1316. {
  1317. if (row_resizable(v))
  1318. {
  1319. drag_row = v;
  1320. anchor_top = WW;
  1321. move |= MOVE_Y; // Moving
  1322. }
  1323. break;
  1324. }
  1325. }
  1326. }
  1327. switch( move )
  1328. {
  1329. case MOVE_X:
  1330. cursor = FL_CURSOR_WE;
  1331. drag_row=-4;
  1332. break;
  1333. case MOVE_Y:
  1334. cursor = FL_CURSOR_NS;
  1335. drag_col=-4;
  1336. break;
  1337. case MOVE_XY:
  1338. cursor = FL_CURSOR_NWSE;
  1339. break;
  1340. default:
  1341. drag_row = drag_col = -4;
  1342. cursor = FL_CURSOR_DEFAULT;
  1343. break;
  1344. }
  1345. if (cursor!=last_cursor)
  1346. {
  1347. fl_cursor(cursor,FL_BLACK,FL_WHITE);
  1348. last_cursor = cursor;
  1349. }
  1350. }
  1351. bool Flv_Table::move_row( int amount )
  1352. {
  1353. Flv_Style s;
  1354. int r = row();
  1355. if (!amount)
  1356. return true;
  1357. r += amount;
  1358. if (r>=rows())
  1359. r = rows()-1;
  1360. if (r<0)
  1361. r = 0;
  1362. while(!select_locked())
  1363. {
  1364. get_style(s,r,col());
  1365. if (!s.locked())
  1366. break;
  1367. r += (amount<0?-1:1);
  1368. if ( r<0 || r>=rows() )
  1369. return false;
  1370. }
  1371. if (r!=row())
  1372. {
  1373. row(r);
  1374. return true;
  1375. }
  1376. return false;
  1377. }
  1378. bool Flv_Table::move_col( int amount )
  1379. {
  1380. Flv_Style s;
  1381. int c = col();
  1382. if (!amount)
  1383. return true;
  1384. c += amount;
  1385. if (c>=cols())
  1386. c = cols()-1;
  1387. if (c<0)
  1388. c = 0;
  1389. while(!select_locked())
  1390. {
  1391. get_style(s,row(),c);
  1392. if (!s.locked())
  1393. break;
  1394. c += (amount<0?-1:1);
  1395. if ( c<0 || c>=rows() )
  1396. return false;
  1397. }
  1398. if (c!=col())
  1399. {
  1400. col(c);
  1401. return true;
  1402. }
  1403. return false;
  1404. }
  1405. int Flv_Table::edit_when( int v )
  1406. {
  1407. int wfocused = (Fl::focus()==veditor);
  1408. if (v!=vedit_when)
  1409. {
  1410. vedit_when = v;
  1411. if (vedit_when!=FLV_EDIT_ALWAYS)
  1412. end_edit();
  1413. else
  1414. start_edit();
  1415. }
  1416. if (wfocused && !vediting)
  1417. {
  1418. Fl::focus(this);
  1419. // take_focus();
  1420. redraw();
  1421. }
  1422. return vedit_when;
  1423. }
  1424. void Flv_Table::start_edit(void) // Start editing
  1425. {
  1426. if (!vediting)
  1427. {
  1428. vediting = true;
  1429. switch_editor( row(), col() );
  1430. }
  1431. }
  1432. void Flv_Table::end_edit(void)
  1433. {
  1434. int wfocused = (Fl::focus()==veditor);
  1435. if (veditor)
  1436. switch_editor(-1,-1);
  1437. if (wfocused && !vediting)
  1438. {
  1439. Fl::focus(this);
  1440. // take_focus();
  1441. redraw();
  1442. }
  1443. }
  1444. void Flv_Table::cancel_edit(void) // Cancel editing
  1445. {
  1446. int wfocused = (Fl::focus()==veditor);
  1447. if (veditor)
  1448. {
  1449. veditor->hide();
  1450. veditor->draw();
  1451. }
  1452. veditor = NULL;
  1453. edit_row = -1;
  1454. edit_col = -1;
  1455. vediting = false;
  1456. // switch_editor(-1, -1);
  1457. if (wfocused && !vediting)
  1458. {
  1459. Fl::focus(this);
  1460. // take_focus();
  1461. redraw();
  1462. }
  1463. }
  1464. void Flv_Table::switch_editor( int nr, int nc )
  1465. {
  1466. Flv_Style s;
  1467. int x, y, w, h, wfocused;
  1468. //char buf[30];
  1469. wfocused = (Fl::focus()==veditor);
  1470. if (veditor)
  1471. {
  1472. if (edit_row>-1 && edit_col>-1)
  1473. save_editor( veditor, edit_row, edit_col );
  1474. edit_row=-1;
  1475. edit_col=-1;
  1476. veditor->hide();
  1477. veditor->draw();
  1478. veditor = NULL;
  1479. }
  1480. if (edit_when()==FLV_EDIT_ALWAYS)
  1481. {
  1482. vediting = true;
  1483. if (nr<0)
  1484. nr = row();
  1485. if (nc<0)
  1486. nc = col();
  1487. }
  1488. if (nr>-1 && nc>-1 && vediting)
  1489. {
  1490. get_style( s, nr, nc );
  1491. if (s.editor_defined() && !s.locked())
  1492. {
  1493. veditor = s.editor();
  1494. if (veditor)
  1495. {
  1496. edit_row = nr;
  1497. edit_col = nc;
  1498. veditor->hide();
  1499. get_cell_bounds(x,y,w,h,nr,nc);
  1500. position_editor(veditor, x,y,w,h, s);
  1501. load_editor( veditor, nr, nc );
  1502. veditor->show();
  1503. Fl::focus(veditor);
  1504. // veditor->take_focus();
  1505. veditor->handle(FL_FOCUS);
  1506. veditor->damage(FL_DAMAGE_ALL);
  1507. veditor->draw();
  1508. }
  1509. }
  1510. }
  1511. if (!veditor)
  1512. {
  1513. vediting=false;
  1514. edit_row=-1;
  1515. edit_col=-1;
  1516. }
  1517. if (!veditor && wfocused)
  1518. {
  1519. Fl::focus(this);
  1520. // take_focus();
  1521. handle(FL_FOCUS);
  1522. }
  1523. }