Fl_TableBox.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. #include <FL/Fl.H>
  2. #include <FL/Fl_TableBox.H>
  3. #include <cassert>
  4. Fl_TableBox::Fl_TableBox (int _x, int _y, int _w, int _h) : Fl_Group (_x, _y, _w, _h)
  5. {
  6. t = new TABLE;
  7. t->gap = new CELL_GAP;
  8. Type (TABLEBOX);
  9. Size (1, 1);
  10. Gap (5, 5);
  11. cur_row = 0;
  12. cur_col = 0;
  13. set_changed();
  14. }
  15. Fl_TableBox::~Fl_TableBox ()
  16. {
  17. delete t->gap;
  18. delete t;
  19. }
  20. void Fl_TableBox::draw()
  21. {
  22. if(changed()) //first time draw()
  23. {
  24. resize(x(),y(),w(),h());
  25. clear_changed();
  26. };
  27. Fl_Group::draw();
  28. };
  29. uint Fl_TableBox::fixed_width()
  30. {
  31. uint fw = 0;
  32. for (uint i = 0; i < t->cols; i++)
  33. {
  34. uint x_fixed = 0;
  35. for (uint j = 0; j < t->rows; j++)
  36. {
  37. TABLE_CELL & curr_cell = t->cell [j][i];
  38. if (curr_cell.x_expand) x_fixed += t->gap->w;
  39. else if (curr_cell.w > x_fixed) x_fixed = curr_cell.w;
  40. }
  41. fw += x_fixed + t->gap->w;
  42. }
  43. return fw ? fw + t->gap->w : 0;
  44. }
  45. uint Fl_TableBox::fixed_height()
  46. {
  47. uint fh = 0;
  48. for (uint i = 0; i < t->rows; i++)
  49. {
  50. uint h_fixed = 0;
  51. for (uint j = 0; j < t->cols; j++)
  52. {
  53. TABLE_CELL & curr_cell = t->cell [j][i];
  54. if (curr_cell.y_expand) h_fixed += t->gap->h;
  55. else if(curr_cell.h > h_fixed) h_fixed = curr_cell.h;
  56. }
  57. fh += h_fixed+t->gap->h;
  58. }
  59. return fh ? fh + t->gap->h : 0;
  60. }
  61. void Fl_TableBox::resize(int i_x, int i_y, int i_w, int i_h)
  62. {
  63. //Fl_Group::resize(i_x,i_y,i_w,i_h); // make new xywh values visible for children
  64. Fl_Widget::resize(i_x,i_y,i_w,i_h);
  65. uint x_expand_items = 0;
  66. uint x_expand_size_item = 0;
  67. uint x_fixed_size_item [t->cols];
  68. uint y_expand_items = 0;
  69. uint y_expand_size_item = 0;
  70. uint y_fixed_size_item [t->rows];
  71. uint x_fixed_size_all_items = 0;
  72. uint y_fixed_size_all_items = 0;
  73. uint _x = x()+t->gap->w;
  74. uint _y = y()+t->gap->h;
  75. // x-axes
  76. for (uint i = 0; i < t->cols; i++)
  77. {
  78. x_fixed_size_item [i] = 0;
  79. for (uint j = 0; j < t->rows; j++)
  80. {
  81. TABLE_CELL & curr_cell = t->cell [j][i];
  82. if (curr_cell.x_expand)
  83. {
  84. x_expand_items++;
  85. x_fixed_size_item [i] = 0;
  86. for (uint k = i; k < t->cols; k++)
  87. x_fixed_size_item [k] = 0;
  88. break;
  89. }
  90. else
  91. {
  92. if (x_fixed_size_item [i] < curr_cell.w)
  93. x_fixed_size_item [i] = curr_cell.w;
  94. }
  95. }
  96. }
  97. for (uint i = 0; i < t->cols; i++)
  98. if (x_fixed_size_item [i] > 0)
  99. x_fixed_size_all_items += x_fixed_size_item [i];
  100. if (x_expand_items > 0)
  101. x_expand_size_item = (uint)((w () -t->gap->w - x_fixed_size_all_items -
  102. (t->cols ) * t->gap->w) / x_expand_items);
  103. // y-axes
  104. for (uint j = 0; j < t->rows; j++)
  105. {
  106. y_fixed_size_item [j] = 0;
  107. for (uint i = 0; i < t->cols; i++)
  108. {
  109. TABLE_CELL & curr_cell = t->cell [j][i];
  110. if (curr_cell.y_expand)
  111. {
  112. y_expand_items++;
  113. y_fixed_size_item [j] = 0;
  114. for (uint k = j; k < t->rows; k++)
  115. y_fixed_size_item [k] = 0;
  116. break;
  117. }
  118. else
  119. {
  120. if (y_fixed_size_item [j] < curr_cell.h)
  121. y_fixed_size_item [j] = curr_cell.h;
  122. }
  123. }
  124. }
  125. for (uint j = 0; j < t->rows; j++)
  126. if (y_fixed_size_item [j] > 0)
  127. y_fixed_size_all_items += y_fixed_size_item [j];
  128. if (y_expand_items > 0)
  129. y_expand_size_item = (uint)((h() -t->gap->h - y_fixed_size_all_items -
  130. (t->rows ) * t->gap->h) / y_expand_items);
  131. uint Wv, Wm, Xm;
  132. uint Hv, Hm, Ym;
  133. // packing
  134. for (uint j = 0; j < t->rows; j++)
  135. {
  136. for (uint i = 0; i < t->cols; i++)
  137. {
  138. TABLE_CELL & curr_cell = t->cell [j][i];
  139. // w
  140. if (x_fixed_size_item [i] > 0) Wv = x_fixed_size_item [i];
  141. else Wv = x_expand_size_item;
  142. // x span
  143. if (curr_cell.x_span > 1)
  144. {
  145. for (uint k=1; k < curr_cell.x_span; k++)
  146. {
  147. if (x_fixed_size_item [i+k] > 0) Wv += x_fixed_size_item [i+k]
  148. + t->gap->w;
  149. else Wv += x_expand_size_item + t->gap->w;
  150. }
  151. }
  152. // x fill
  153. if (curr_cell.x_fill) Wm = Wv;
  154. else if (Wv > curr_cell.w) Wm = curr_cell.w;
  155. else Wm = Wv;
  156. Xm = (uint)(curr_cell.x_align * (Wv - Wm));
  157. // h
  158. if (y_fixed_size_item [j] > 0) Hv = y_fixed_size_item [j];
  159. else Hv = y_expand_size_item;
  160. // y span
  161. if (curr_cell.y_span > 1)
  162. {
  163. for (uint k=1; k < curr_cell.y_span; k++)
  164. {
  165. if (y_fixed_size_item [j+k] > 0) Hv += y_fixed_size_item [j+k]
  166. + t->gap->h;
  167. else Hv += y_expand_size_item + t->gap->h;
  168. }
  169. }
  170. // y fill
  171. if (curr_cell.y_fill) Hm = Hv;
  172. else if (Hv > curr_cell.h) Hm = curr_cell.h;
  173. else Hm = Hv;
  174. Ym = (uint)(curr_cell.y_align * (Hv - Hm));
  175. // resizing / positioning
  176. if (curr_cell.o != 0)
  177. {
  178. curr_cell.o->resize (_x + Xm, _y + Ym, Wm, Hm);
  179. //printf("%s %d:%d:%d:%d:%d:%d\n", curr_cell.o->label(),
  180. // _x, _y, _x + Xm, _y + Ym, Wm, Hm);
  181. }
  182. //if (curr_cell.o && curr_cell.o->as_group () && !curr_cell.o->as_window ())
  183. // curr_cell.o->layout ();
  184. // update X
  185. if (x_fixed_size_item [i] > 0) _x += x_fixed_size_item [i] + t->gap->w;
  186. else _x += x_expand_size_item + t->gap->w;
  187. }
  188. // beginning of next row
  189. _x = x()+t->gap->w;
  190. // update Y
  191. if (y_fixed_size_item [j] > 0) _y += y_fixed_size_item [j] + t->gap->h;
  192. else _y += y_expand_size_item + t->gap->h;
  193. }
  194. }
  195. // get
  196. Fl_TableBox::TableBox_Type Fl_TableBox::Type ()
  197. {
  198. return __type;
  199. }
  200. void Fl_TableBox::Size (uint * _rows, uint * _cols)
  201. {
  202. *_rows = t->rows;
  203. *_cols = t->cols;
  204. }
  205. uint Fl_TableBox::Size ()
  206. {
  207. if (Type () == VBOX)
  208. return t->rows;
  209. else if (Type () == HBOX)
  210. return t->cols;
  211. else
  212. return 0;
  213. }
  214. uint Fl_TableBox::Rows ()
  215. {
  216. return t->rows;
  217. }
  218. uint Fl_TableBox::Cols ()
  219. {
  220. return t->rows;
  221. }
  222. Fl_TableBox::CELL_GAP * Fl_TableBox::Gap ()
  223. {
  224. return t->gap;
  225. }
  226. void Fl_TableBox::Gap (uint * _w, uint * _h)
  227. {
  228. *_w = t->gap->w;
  229. *_h = t->gap->h;
  230. }
  231. Fl_Widget * Fl_TableBox::Widget (uint _row, uint _col)
  232. {
  233. assert(_row < t->rows && _col < t->cols);
  234. return t->cell [_row][_col].o;
  235. }
  236. Fl_TableBox::TABLE_CELL * Fl_TableBox::Cell (uint _row, uint _col)
  237. {
  238. assert(_row < t->rows && _col < t->cols);
  239. return & t->cell [_row][_col];
  240. }
  241. // set
  242. void Fl_TableBox::Type (TableBox_Type _type)
  243. {
  244. __type = _type;
  245. }
  246. void Fl_TableBox::Size (uint _rows, uint _cols)
  247. {
  248. t->rows = _rows;
  249. t->cols = _cols;
  250. t->cell.size (t->rows);
  251. for (uint j=0; j<t->rows; j++)
  252. t->cell [j].size (t->cols);
  253. }
  254. bool Fl_TableBox::Size (uint _len)
  255. {
  256. if (Type () == VBOX)
  257. Rows (_len);
  258. else if (Type () == HBOX)
  259. Cols (_len);
  260. else
  261. return false; //error condition
  262. return true; //ok done
  263. }
  264. void Fl_TableBox::Rows (uint _len)
  265. {
  266. t->rows = _len;
  267. Size ((uint)t->rows, (uint)t->cols);
  268. }
  269. void Fl_TableBox::Cols (uint _len)
  270. {
  271. t->cols = _len;
  272. Size ((uint)t->rows, (uint)t->cols);
  273. }
  274. void Fl_TableBox::AddCell (uint _len)
  275. {
  276. Size (Size () + 1);
  277. }
  278. void Fl_TableBox::Gap (CELL_GAP * _gap)
  279. {
  280. t->gap = _gap;
  281. }
  282. void Fl_TableBox::Gap (uint _w, uint _h)
  283. {
  284. t->gap->w = _w;
  285. t->gap->h = _h;
  286. }
  287. void Fl_TableBox::Widget (Fl_Widget * _widget, uint _row, uint _col)
  288. {
  289. assert(_row < t->rows && _col < t->cols);
  290. t->cell [_row][_col].o = _widget;
  291. }
  292. void Fl_TableBox::Cell (TABLE_CELL * _cell, uint _row, uint _col)
  293. {
  294. assert(_row < t->rows && _col < t->cols);
  295. t->cell [_row][_col] = * _cell;
  296. }
  297. void Fl_TableBox::Attach (const TABLE_CELL & _cell, uint _row, uint _col)
  298. {
  299. assert(_row < t->rows && _col < t->cols);
  300. t->cell [_row] [_col] = _cell;
  301. for (uint j = 0; j < _cell.y_span; j++)
  302. {
  303. assert((_row+j) < t->rows);
  304. for (uint i = 0; i < _cell.x_span; i++)
  305. {
  306. assert((_col+i) < t->cols);
  307. TABLE_CELL &cell = t->cell [_row+j] [_col+i];
  308. cell.x_align = _cell.x_align;
  309. cell.y_align = _cell.y_align;
  310. cell.x_expand = _cell.x_expand;
  311. cell.y_expand = _cell.y_expand;
  312. }
  313. }
  314. }
  315. Fl_Widget * Fl_TableBox::Attach (
  316. Fl_Widget * _widget,
  317. uint _row, uint _col,
  318. uint _w, uint _h,
  319. Expand_Type _x_prop,
  320. Expand_Type _y_prop,
  321. uint _x_span, uint _y_span,
  322. float _x_align, float _y_align
  323. )
  324. {
  325. assert(_row < t->rows && _col < t->cols);
  326. TABLE_CELL cell;
  327. cell.o = _widget;
  328. cell.w = _w;
  329. cell.h = _h;
  330. cell.x_fill = _x_prop & FILL;
  331. cell.y_fill = _y_prop & FILL;
  332. cell.x_span = _x_span;
  333. cell.y_span = _y_span;
  334. cell.x_align = _x_align;
  335. cell.y_align = _y_align;
  336. cell.x_expand = _x_prop & EXPAND;
  337. cell.y_expand = _y_prop & EXPAND;
  338. Attach(cell, _row, _col);
  339. return _widget;
  340. }
  341. Fl_Widget * Fl_TableBox::Add (
  342. Fl_Widget * _widget,
  343. uint _w, uint _h,
  344. Expand_Type _x_prop,
  345. Expand_Type _y_prop,
  346. uint _x_span,
  347. uint _y_span,
  348. float _x_align, float _y_align
  349. )
  350. {
  351. uint _row = cur_row;
  352. uint _col = cur_col;
  353. TABLE_CELL &cell = t->cell [_row] [_col];
  354. cell.o = _widget;
  355. cell.w = _w;
  356. cell.h = _h;
  357. cell.x_fill = _x_prop & FILL;
  358. cell.y_fill = _y_prop & FILL;
  359. cell.x_span = _x_span;
  360. cell.y_span = _y_span;
  361. cell.x_align = _x_align;
  362. cell.y_align = _y_align;
  363. for (uint j = 0; j < _y_span; j++)
  364. {
  365. assert((_row+j) < t->rows);
  366. for (uint i = 0; i < _x_span; i++)
  367. {
  368. assert((_col+i) < t->cols);
  369. TABLE_CELL &cell = t->cell [_row+j] [_col+i];
  370. cell.x_expand = _x_prop & EXPAND;
  371. cell.y_expand = _y_prop & EXPAND;
  372. }
  373. }
  374. if (Type () == VBOX)
  375. cur_row++;
  376. else if (Type () == HBOX)
  377. cur_col++;
  378. return _widget;
  379. }