htmlgrid 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/History.txt +6 -0
  2. data/LICENCE.txt +515 -0
  3. data/Manifest.txt +82 -0
  4. data/README.txt +30 -0
  5. data/Rakefile +28 -0
  6. data/ext/htmlgrid/MANIFEST +3 -0
  7. data/ext/htmlgrid/Makefile +150 -0
  8. data/ext/htmlgrid/extconf.rb +33 -0
  9. data/ext/htmlgrid/grid.c +881 -0
  10. data/ext/htmlgrid/grid.o +0 -0
  11. data/ext/htmlgrid/htmlgrid.c +30 -0
  12. data/ext/htmlgrid/htmlgrid.o +0 -0
  13. data/ext/htmlgrid/htmlgrid.so +0 -0
  14. data/ext/htmlgrid/include/grid.h +79 -0
  15. data/ext/htmlgrid/include/htmlgrid.h +33 -0
  16. data/install.rb +1098 -0
  17. data/lib/htmlgrid/booleanvalue.rb +41 -0
  18. data/lib/htmlgrid/button.rb +36 -0
  19. data/lib/htmlgrid/centeredcomposite.rb +47 -0
  20. data/lib/htmlgrid/component.rb +232 -0
  21. data/lib/htmlgrid/composite.rb +350 -0
  22. data/lib/htmlgrid/datevalue.rb +39 -0
  23. data/lib/htmlgrid/div.rb +37 -0
  24. data/lib/htmlgrid/divcomposite.rb +52 -0
  25. data/lib/htmlgrid/divform.rb +35 -0
  26. data/lib/htmlgrid/divlist.rb +26 -0
  27. data/lib/htmlgrid/divtemplate.rb +12 -0
  28. data/lib/htmlgrid/dojotoolkit.rb +173 -0
  29. data/lib/htmlgrid/errormessage.rb +70 -0
  30. data/lib/htmlgrid/form.rb +93 -0
  31. data/lib/htmlgrid/formlist.rb +42 -0
  32. data/lib/htmlgrid/grid.rb +286 -0
  33. data/lib/htmlgrid/image.rb +43 -0
  34. data/lib/htmlgrid/infomessage.rb +41 -0
  35. data/lib/htmlgrid/input.rb +59 -0
  36. data/lib/htmlgrid/inputcheckbox.rb +41 -0
  37. data/lib/htmlgrid/inputcurrency.rb +36 -0
  38. data/lib/htmlgrid/inputdate.rb +38 -0
  39. data/lib/htmlgrid/inputfile.rb +40 -0
  40. data/lib/htmlgrid/inputradio.rb +37 -0
  41. data/lib/htmlgrid/inputtext.rb +37 -0
  42. data/lib/htmlgrid/javascript.rb +22 -0
  43. data/lib/htmlgrid/label.rb +90 -0
  44. data/lib/htmlgrid/labeltext.rb +35 -0
  45. data/lib/htmlgrid/link.rb +54 -0
  46. data/lib/htmlgrid/list.rb +170 -0
  47. data/lib/htmlgrid/namedcomponent.rb +52 -0
  48. data/lib/htmlgrid/pass.rb +38 -0
  49. data/lib/htmlgrid/passthru.rb +44 -0
  50. data/lib/htmlgrid/popuplink.rb +66 -0
  51. data/lib/htmlgrid/reset.rb +36 -0
  52. data/lib/htmlgrid/richtext.rb +26 -0
  53. data/lib/htmlgrid/select.rb +53 -0
  54. data/lib/htmlgrid/span.rb +37 -0
  55. data/lib/htmlgrid/spancomposite.rb +45 -0
  56. data/lib/htmlgrid/spanlist.rb +15 -0
  57. data/lib/htmlgrid/staticinput.rb +40 -0
  58. data/lib/htmlgrid/submit.rb +36 -0
  59. data/lib/htmlgrid/template.rb +130 -0
  60. data/lib/htmlgrid/text.rb +36 -0
  61. data/lib/htmlgrid/textarea.rb +49 -0
  62. data/lib/htmlgrid/ulcomposite.rb +49 -0
  63. data/lib/htmlgrid/ullist.rb +15 -0
  64. data/lib/htmlgrid/urllink.rb +65 -0
  65. data/lib/htmlgrid/value.rb +36 -0
  66. data/test/rebuild.rb +39 -0
  67. data/test/stub/cgi.rb +44 -0
  68. data/test/suite.rb +32 -0
  69. data/test/test_component.rb +138 -0
  70. data/test/test_composite.rb +201 -0
  71. data/test/test_datevalue.rb +60 -0
  72. data/test/test_form.rb +123 -0
  73. data/test/test_formlist.rb +111 -0
  74. data/test/test_grid.rb +395 -0
  75. data/test/test_input.rb +70 -0
  76. data/test/test_label.rb +116 -0
  77. data/test/test_list.rb +146 -0
  78. data/test/test_select.rb +78 -0
  79. data/test/test_template.rb +97 -0
  80. data/test/test_text.rb +63 -0
  81. data/usage-en.txt +112 -0
  82. data/widget/Tooltip.js +85 -0
  83. metadata +180 -0
@@ -0,0 +1,881 @@
1
+ /*
2
+ * HtmlGrid -- HyperTextMarkupLanguage Framework
3
+ * Copyright (C) 2003 ywesee - intellectual capital connected
4
+ * Andreas Schrafl, Benjamin Fay, Hannes Wyss, Markus Huggler
5
+ *
6
+ * This library is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with this library; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ *
20
+ * ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Zuerich, Switzerland
21
+ * htmlgrid@ywesee.com, www.ywesee.com
22
+ */
23
+
24
+ #include "grid.h"
25
+ #ifdef RUBY_19
26
+ # include "ruby/st.h"
27
+ # include "ruby/encoding.h"
28
+ #else
29
+ # include "st.h"
30
+ #endif
31
+
32
+ void Init_Grid()
33
+ {
34
+ grid = rb_define_class_under(htmlgrid, "Grid", rb_cObject);
35
+ rb_define_singleton_method(grid, "new", grid_new, -1);
36
+ rb_define_method(grid, "initialize", grid_initialize, 1);
37
+ rb_define_method(grid, "height", grid_height, 0);
38
+ rb_define_method(grid, "width", grid_width, 0);
39
+ rb_define_method(grid, "to_html", grid_to_html, 1);
40
+ rb_define_method(grid, "add", grid_add, -1);
41
+ rb_define_method(grid, "add_column", grid_add_column, 3);
42
+ rb_define_method(grid, "add_field", grid_add_field, 3);
43
+ rb_define_method(grid, "add_row", grid_add_row, 3);
44
+ rb_define_method(grid, "add_attribute", grid_add_attribute, -1);
45
+ rb_define_method(grid, "set_row_attributes",
46
+ grid_row_set_attributes, -1);
47
+ rb_define_method(grid, "add_tag", grid_add_tag, -1);
48
+ rb_define_method(grid, "add_style", grid_add_style, -1);
49
+ rb_define_method(grid, "add_component_style",
50
+ grid_add_component_style, -1);
51
+ rb_define_method(grid, "push", grid_push, 1);
52
+ rb_define_method(grid, "set_colspan", grid_set_colspan, -1);
53
+ rb_define_method(grid, "set_attribute", grid_set_attribute, 2);
54
+ rb_define_method(grid, "set_attributes", grid_set_attributes, 1);
55
+ rb_define_method(grid, "insert_row", grid_insert_row, 2);
56
+ rb_define_method(grid, "field_attribute", grid_field_attribute, 3);
57
+ }
58
+
59
+ long grid_pos(cg, xpos, ypos)
60
+ cGrid *cg;
61
+ long xpos, ypos;
62
+ {
63
+ return ypos * cg->width + xpos;
64
+ }
65
+
66
+ long grid_coordinate(input, name)
67
+ VALUE input;
68
+ const char* name;
69
+ {
70
+ long output = NUM2LONG(input);
71
+ if(output < 0)
72
+ rb_raise(rb_eArgError, "invalid %s %li", name, output);
73
+ return output;
74
+ }
75
+
76
+ VALUE rb_hsh_store_pair(pair, hsh)
77
+ VALUE pair, hsh;
78
+ {
79
+ VALUE key, value;
80
+ key = rb_ary_entry(pair, 0);
81
+ value = rb_ary_entry(pair, 1);
82
+ return rb_hash_aset(hsh, key, value);
83
+ }
84
+
85
+ cField * grid_create_field()
86
+ {
87
+ cField * cf;
88
+ cf = ALLOC(cField);
89
+ cf->attributes = Qnil;
90
+ cf->colspan = 1;
91
+ cf->capacity = 1;
92
+ cf->content = ALLOC_N(VALUE, cf->capacity);
93
+ cf->content_count = 0;
94
+ strcpy(cf->tag, "TD");
95
+ return cf;
96
+ }
97
+
98
+ void grid_set_dimensions(cg, width, height)
99
+ cGrid *cg;
100
+ long width, height;
101
+ {
102
+ if(cg->width >= width && cg->height >= height) return;
103
+
104
+ long stop, fields, idx, xval, yval, mwidth, mheight;
105
+
106
+ /* make space for more rows */
107
+ if(height > cg->height)
108
+ {
109
+ if(height > cg->row_capacity)
110
+ {
111
+ while(height > cg->row_capacity)
112
+ cg->row_capacity *= 2;
113
+ REALLOC_N(cg->row_attributes, VALUE, cg->row_capacity);
114
+ }
115
+ for(yval=cg->height; yval < height; yval++)
116
+ {
117
+ cg->row_attributes[yval] = Qnil;
118
+ }
119
+ }
120
+
121
+ mheight = (height > cg->height) ? height : cg->height;
122
+ mwidth = (width > cg->width) ? width : cg->width;
123
+
124
+ stop = mwidth * mheight;
125
+ fields = cg->width * cg->height;
126
+ cField *tmp[cg->capacity];
127
+ for(idx=0; idx < fields; idx++)
128
+ {
129
+ tmp[idx] = cg->fields[idx];
130
+ }
131
+
132
+ /* sufficient capacity? */
133
+ if(stop > cg->capacity)
134
+ {
135
+ while(stop > cg->capacity)
136
+ {
137
+ cg->capacity *= 2;
138
+ }
139
+ //printf("reallocating %li fields\n", cg->capacity);
140
+ REALLOC_N(cg->fields, cField *, cg->capacity);
141
+ }
142
+
143
+ /* has the maximum width changed? */
144
+ if(mwidth > cg->width)
145
+ {
146
+ for(yval=0, idx=0; yval < mheight; yval++)
147
+ {
148
+ for(xval=0; xval < mwidth; xval++)
149
+ {
150
+ if(yval < cg->height && xval < cg->width)
151
+ {
152
+ cg->fields[idx] = tmp[grid_pos(cg, xval, yval)];
153
+ }
154
+ else
155
+ {
156
+ cg->fields[idx] = grid_create_field();
157
+ }
158
+ idx++;
159
+ }
160
+ }
161
+ }
162
+ /* ..otherwise use the slightly more efficient algo */
163
+ else
164
+ {
165
+ for(idx=0; idx < fields; idx++)
166
+ {
167
+ cg->fields[idx] = tmp[idx];
168
+ }
169
+ //printf("initializing fields %li to %li\n", fields, stop);
170
+ for(idx=fields; idx < stop; idx++)
171
+ {
172
+ //printf("creating new field at idx: %i\n", idx);
173
+ cg->fields[idx] = grid_create_field();
174
+ }
175
+ }
176
+
177
+ cg->height = mheight;
178
+ cg->width = mwidth;
179
+ }
180
+
181
+ cGrid *grid_create()
182
+ {
183
+ long init_cap = 4;
184
+ cGrid * cg;
185
+ cg = ALLOC(cGrid);
186
+ cg->attributes = rb_hash_new();
187
+ cg->width = 1;
188
+ cg->height = 1;
189
+ cg->capacity = init_cap;
190
+ cg->row_capacity = init_cap;
191
+ cg->fields = ALLOC_N(cField *, init_cap);
192
+ cg->fields[0] = grid_create_field();
193
+ cg->row_attributes = ALLOC_N(VALUE, init_cap);
194
+ cg->row_attributes[0] = Qnil;
195
+ return cg;
196
+ }
197
+
198
+ void grid_mark(cg)
199
+ cGrid * cg;
200
+ {
201
+ cField * cf;
202
+ long idx, cdx, stop;
203
+ stop = cg->height * cg->width;
204
+
205
+ rb_gc_mark(cg->attributes);
206
+ for(idx=0; idx<stop; idx++)
207
+ {
208
+ cf = cg->fields[idx];
209
+ rb_gc_mark(cf->attributes);
210
+ for(cdx=0; cdx < cf->content_count; cdx++)
211
+ {
212
+ rb_gc_mark(cf->content[cdx]);
213
+ }
214
+ }
215
+ for(idx=0; idx < cg->height; idx++)
216
+ {
217
+ rb_gc_mark(cg->row_attributes[idx]);
218
+ }
219
+ }
220
+
221
+ void grid_free(cg)
222
+ cGrid * cg;
223
+ {
224
+ long idx;
225
+ cField * cf;
226
+ for(idx=0; idx < (cg->width * cg->height); idx++)
227
+ {
228
+ cf = cg->fields[idx];
229
+ free(cf->content);
230
+ free(cf);
231
+ }
232
+ free(cg->row_attributes);
233
+ free(cg->fields);
234
+ free(cg);
235
+ }
236
+
237
+ VALUE grid_new(argc, argv, klass)
238
+ long argc;
239
+ VALUE *argv;
240
+ VALUE klass;
241
+ {
242
+ VALUE instance, attr, argv2[1];
243
+ cGrid *internal;
244
+
245
+ rb_scan_args(argc, argv, "01", &attr);
246
+ argv2[0] = (attr == Qnil) ? rb_hash_new() : attr;
247
+
248
+ internal = grid_create();
249
+ instance = Data_Wrap_Struct(klass, grid_mark, grid_free, internal);
250
+ rb_obj_call_init(instance, 1, argv2);
251
+
252
+ return instance;
253
+ }
254
+
255
+ VALUE grid_initialize(self, attr)
256
+ VALUE self, attr;
257
+ {
258
+ VALUE key;
259
+ cGrid * cg;
260
+ Data_Get_Struct(self, cGrid, cg);
261
+
262
+ key = rb_str_new2("cellspacing");
263
+ if(!st_lookup(RHASH_TBL(attr), key, 0))
264
+ {
265
+ rb_hash_aset(attr, key, rb_str_new2("0"));
266
+ }
267
+ cg->attributes = attr;
268
+
269
+ return self;
270
+ }
271
+
272
+ VALUE grid_height(self)
273
+ VALUE self;
274
+ {
275
+ cGrid * cg;
276
+ Data_Get_Struct(self, cGrid, cg);
277
+ return LONG2NUM(cg->height);
278
+ }
279
+
280
+ VALUE grid_width(self)
281
+ VALUE self;
282
+ {
283
+ cGrid * cg;
284
+ Data_Get_Struct(self, cGrid, cg);
285
+ return INT2NUM(cg->width);
286
+ }
287
+
288
+ VALUE grid_cat_attribute(pair, string)
289
+ VALUE pair, string;
290
+ {
291
+ VALUE val;
292
+ char *key, *value;
293
+ long len;
294
+ val = rb_ary_entry(pair, 1);
295
+ if(val == Qnil)
296
+ return string;
297
+ key = STR2CSTR(rb_ary_entry(pair, 0));
298
+ value = STR2CSTR(rb_funcall(val, rb_intern("to_s"), 0));
299
+ char attr[strlen(key) + strlen(value) + 5];
300
+ len = sprintf(attr, " %s=\"%s\"", key, value);
301
+ return rb_str_cat(string, attr, len);
302
+ }
303
+
304
+ void grid_cat_starttag(string, tagname, attributes)
305
+ VALUE string, attributes;
306
+ char *tagname;
307
+ {
308
+ char tagstart[strlen(tagname) + 2];
309
+ long len;
310
+ len = sprintf(tagstart, "<%s", tagname);
311
+ rb_str_cat(string, (char *)tagstart, len);
312
+ rb_iterate(rb_each, attributes, grid_cat_attribute, string);
313
+ rb_str_cat(string, ">", 1);
314
+ }
315
+
316
+ void grid_cat_endtag(string, tagname)
317
+ VALUE string;
318
+ char *tagname;
319
+ {
320
+ char tag[strlen(tagname) + 4];
321
+ long len;
322
+ len = sprintf(tag, "</%s>", tagname);
323
+ rb_str_cat(string, tag, len);
324
+ }
325
+
326
+ VALUE rb_hsh_update(hsh1, hsh2)
327
+ VALUE hsh1, hsh2;
328
+ {
329
+ return rb_iterate(rb_each, hsh2, rb_hsh_store_pair, hsh1);
330
+ }
331
+
332
+ VALUE grid_store_allowed_attribute(pair, attrs)
333
+ VALUE pair, attrs;
334
+ {
335
+ char* key;
336
+
337
+ key = STR2CSTR(rb_ary_entry(pair, 0));
338
+ if( strcasecmp(key, "align") == 0
339
+ || strcasecmp(key, "class") == 0
340
+ || strcasecmp(key, "colspan") == 0
341
+ || strcasecmp(key, "style") == 0
342
+ || strcasecmp(key, "tag") == 0
343
+ || strcasecmp(key, "title") == 0)
344
+ {
345
+ return rb_hsh_store_pair(pair, attrs);
346
+ }
347
+ else
348
+ {
349
+ return Qnil;
350
+ }
351
+ }
352
+
353
+ const char * tr_open = "<TR>";
354
+ const char * tr_close = "</TR>";
355
+
356
+ VALUE grid_to_html(self, cgi)
357
+ VALUE self, cgi;
358
+ {
359
+ cGrid * cg;
360
+ cField * cf;
361
+ VALUE item, result, attrs;
362
+ ID id_backtrace = rb_intern("backtrace");
363
+ ID id_to_html = rb_intern("to_html");
364
+ ID id_to_s = rb_intern("to_s");
365
+ //ID id_attributes = rb_intern("attributes");
366
+ ID id_message = rb_intern("message");
367
+ long idx, cdx, xval, yval, spanplus, len;
368
+ Data_Get_Struct(self, cGrid, cg);
369
+ //attrs = rb_iv_get(self, "@attributes");
370
+ result = rb_str_new2("");
371
+ grid_cat_starttag(result, "TABLE", cg->attributes);
372
+ for(idx=0, yval=0; yval < cg->height; yval++)
373
+ {
374
+ if(cg->row_attributes[yval] == Qnil)
375
+ rb_str_cat(result, tr_open, 4);
376
+ else
377
+ grid_cat_starttag(result, "TR", cg->row_attributes[yval]);
378
+
379
+ for(xval=0; xval < cg->width; xval++, idx++)
380
+ {
381
+ //printf("writing out field at idx:%i\n", idx);
382
+ cf = cg->fields[idx];
383
+ if((spanplus = cf->colspan - 1))
384
+ {
385
+ xval += spanplus;
386
+ idx += spanplus;
387
+ }
388
+ attrs = rb_hash_new();
389
+ /*
390
+ for(cdx=0; cdx<cf->content_count; cdx++)
391
+ {
392
+ item = cf->content[cdx];
393
+ if(rb_respond_to(item, attributes))
394
+ {
395
+ rb_warn("Outward Propagation of attributes is deprecated");
396
+ rb_iterate(rb_each, rb_funcall(item, attributes, 0),
397
+ grid_store_allowed_attribute, attrs);
398
+ }
399
+ }
400
+ */
401
+ if(cf->attributes != Qnil)
402
+ rb_hsh_update(attrs, cf->attributes);
403
+ if(cf->colspan > 1)
404
+ {
405
+ char spanstr[cf->colspan/10];
406
+ len = sprintf(spanstr, "%li", cf->colspan);
407
+ rb_hash_aset(attrs, rb_str_new2("colspan"),
408
+ rb_str_new(spanstr, len));
409
+ }
410
+
411
+ grid_cat_starttag(result, cf->tag, attrs);
412
+ if(cf->content_count == 0)
413
+ rb_str_cat(result, "&nbsp;", 6);
414
+ else
415
+ {
416
+ for(cdx=0; cdx<cf->content_count; cdx++)
417
+ {
418
+ item = cf->content[cdx];
419
+ if(rb_obj_class(item) == rb_cString)
420
+ rb_str_concat(result, item);
421
+ else if(rb_respond_to(item, id_to_html))
422
+ {
423
+ VALUE item_html = rb_funcall(item, id_to_html, 1, cgi);
424
+ if(rb_obj_is_kind_of(item_html, rb_cString) == Qtrue)
425
+ rb_str_concat(result, item_html);
426
+ }
427
+ else if(rb_obj_is_kind_of(item, rb_eException) == Qtrue)
428
+ {
429
+ rb_str_cat(result, "<!--\n", 5);
430
+ rb_str_concat(result,
431
+ rb_funcall(rb_obj_class(item), id_to_s, 0));
432
+ rb_str_cat(result, "\n", 1);
433
+ rb_str_concat(result,
434
+ rb_funcall(item, id_message, 0));
435
+ rb_str_cat(result, "\n", 1);
436
+ VALUE bt = rb_funcall(item, id_backtrace, 0);
437
+ rb_str_concat(result, rb_funcall(bt, rb_intern("join"),
438
+ 1, rb_str_new2("\n")));
439
+ rb_str_cat(result, "-->\n", 4);
440
+ }
441
+ else
442
+ rb_str_concat(result, rb_funcall(item, id_to_s, 0));
443
+ }
444
+ }
445
+ grid_cat_endtag(result, cf->tag);
446
+ }
447
+ rb_str_cat(result, tr_close, 5);
448
+ }
449
+ rb_str_cat(result, "</TABLE>", 8);
450
+ return result;
451
+ }
452
+
453
+ void grid_field_add_content(cf, content)
454
+ cField * cf;
455
+ VALUE content;
456
+ {
457
+ long pos;
458
+ if(cf->capacity <= cf->content_count)
459
+ {
460
+ cf->capacity *= 2;
461
+ REALLOC_N(cf->content, VALUE, cf->capacity);
462
+ }
463
+ pos = cf->content_count;
464
+ cf->content_count++;
465
+ cf->content[pos] = content;
466
+ }
467
+
468
+ VALUE grid_label2ary(item, ary)
469
+ VALUE item, ary;
470
+ {
471
+ return rb_ary_push(ary, item);
472
+ }
473
+
474
+ VALUE grid_iterate_add_field(item, args)
475
+ VALUE item, args[3];
476
+ {
477
+ if(Qnil == item)
478
+ {
479
+ args[1] = LONG2NUM(NUM2LONG(args[1]) + 1);
480
+ return Qnil;
481
+ }
482
+ else
483
+ {
484
+ return grid_add_field(args[0], item, args[1], args[2]);
485
+ }
486
+ }
487
+
488
+ VALUE grid_add(argc, argv, self)
489
+ long argc;
490
+ VALUE *argv, self;
491
+ {
492
+ VALUE item, xval, yval, colflag;
493
+
494
+ rb_scan_args(argc, argv, "31", &item, &xval, &yval, &colflag);
495
+ if(rb_mod_include_p(rb_obj_class(item), rb_mEnumerable) == Qtrue)
496
+ {
497
+ VALUE tmp;
498
+ if(rb_obj_class(item) == rb_cString)
499
+ {
500
+ return grid_add_field(self, item, xval, yval);
501
+ }
502
+ else if(rb_obj_class(item) == rb_cArray)
503
+ {
504
+ VALUE args[3];
505
+ args[0] = self;
506
+ args[1] = xval;
507
+ args[2] = yval;
508
+
509
+ return rb_iterate(rb_each, item, grid_iterate_add_field, (VALUE)args);
510
+ }
511
+ else
512
+ {
513
+ tmp = rb_ary_new();
514
+ rb_iterate(rb_each, item, grid_label2ary, tmp);
515
+ }
516
+
517
+ if(colflag == Qtrue)
518
+ return grid_add_column(self, tmp, xval, yval);
519
+ else
520
+ return grid_add_row(self, tmp, xval, yval);
521
+ }
522
+
523
+ return grid_add_field(self, item, xval, yval);
524
+ }
525
+
526
+ VALUE grid_add_field(self, item, xval, yval)
527
+ VALUE self, item, xval, yval;
528
+ {
529
+ cGrid *cg;
530
+ cField *cf;
531
+ long xpos, ypos;
532
+ Data_Get_Struct(self, cGrid, cg);
533
+
534
+ xpos = grid_coordinate(xval, "x-position");
535
+ ypos = grid_coordinate(yval, "y-position");
536
+ grid_set_dimensions(cg, xpos + 1, ypos + 1);
537
+
538
+ cf = cg->fields[grid_pos(cg, xpos, ypos)];
539
+ if(item == Qnil)
540
+ {
541
+ return Qnil;
542
+ }
543
+ else
544
+ {
545
+ grid_field_add_content(cf, item);
546
+ return item;
547
+ }
548
+ }
549
+
550
+ VALUE grid_add_row(self, item, xval, yval)
551
+ VALUE self, item, xval, yval;
552
+ {
553
+ cGrid *cg;
554
+ cField *cf;
555
+ long xpos, ypos, pos, len, stop, idx;
556
+ Data_Get_Struct(self, cGrid, cg);
557
+
558
+ len = RARRAY_LEN(item);
559
+ xpos = grid_coordinate(xval, "x-position");
560
+ ypos = grid_coordinate(yval, "y-position");
561
+ stop = xpos + len;
562
+ grid_set_dimensions(cg, stop, ypos + 1);
563
+
564
+ for(pos = xpos, idx = 0; pos < stop; pos++, idx++)
565
+ {
566
+ cf = cg->fields[grid_pos(cg, pos, ypos)];
567
+ grid_field_add_content(cf, rb_ary_entry(item, idx));
568
+ }
569
+ return item;
570
+ }
571
+
572
+ VALUE grid_add_column(self, item, xval, yval)
573
+ VALUE self, item, xval, yval;
574
+ {
575
+ cGrid *cg;
576
+ cField *cf;
577
+ long xpos, ypos, pos, len, stop, idx;
578
+ Data_Get_Struct(self, cGrid, cg);
579
+
580
+ len = RARRAY_LEN(item);
581
+ xpos = grid_coordinate(xval, "x-position");
582
+ ypos = grid_coordinate(yval, "y-position");
583
+ stop = ypos + len;
584
+ grid_set_dimensions(cg, xpos + 1, stop);
585
+
586
+ for(pos = ypos, idx=0 ; pos < stop; pos++, idx++)
587
+ {
588
+ cf = cg->fields[grid_pos(cg, xpos, pos)];
589
+ grid_field_add_content(cf, rb_ary_entry(item, idx));
590
+ }
591
+ return item;
592
+ }
593
+
594
+ VALUE grid_push(self, item)
595
+ VALUE self, item;
596
+ {
597
+ cGrid *cg;
598
+ cField * cf;
599
+ Data_Get_Struct(self, cGrid, cg);
600
+
601
+ long height = cg->height;
602
+ grid_set_dimensions(cg, cg->width, height + 1);
603
+ cf = cg->fields[grid_pos(cg, 0, height)];
604
+ grid_field_add_content(cf, item);
605
+ cf->colspan = cg->width;
606
+ return item;
607
+ }
608
+
609
+ VALUE grid_set_colspan(argc, argv, self)
610
+ long argc;
611
+ VALUE *argv, self;
612
+ {
613
+ VALUE xval, yval, span;
614
+
615
+ cGrid *cg;
616
+ cField * cf;
617
+ Data_Get_Struct(self, cGrid, cg);
618
+ long xpos, ypos, spanval;
619
+
620
+ rb_scan_args(argc, argv, "21", &xval, &yval, &span);
621
+ xpos = grid_coordinate(xval, "x-position");
622
+ ypos = grid_coordinate(yval, "y-position");
623
+ if(span == Qnil)
624
+ spanval = cg->width - xpos;
625
+ else
626
+ spanval = grid_coordinate(span, "span-value");
627
+ grid_set_dimensions(cg, xpos + spanval, ypos + 1);
628
+ cf = cg->fields[grid_pos(cg, xpos, ypos)];
629
+ cf->colspan = spanval;
630
+ return span;
631
+ }
632
+
633
+ VALUE grid_set_attribute(self, key, value)
634
+ VALUE self, key, value;
635
+ {
636
+ cGrid * cg;
637
+ Data_Get_Struct(self, cGrid, cg);
638
+ return rb_hash_aset(cg->attributes, key, value);
639
+ }
640
+
641
+ VALUE grid_set_attribute_pair(pair, cg)
642
+ VALUE pair;
643
+ cGrid *cg;
644
+ {
645
+ return rb_hsh_store_pair(pair, cg->attributes);
646
+ }
647
+
648
+ VALUE grid_set_attributes(self, attr)
649
+ VALUE self, attr;
650
+ {
651
+ cGrid * cg;
652
+ Data_Get_Struct(self, cGrid, cg);
653
+ rb_iterate(rb_each, attr, grid_set_attribute_pair, (VALUE)cg);
654
+ return attr;
655
+ }
656
+
657
+ VALUE grid_insert_row(self, yval, item)
658
+ VALUE self, yval, item;
659
+ {
660
+ cGrid *cg;
661
+ cField *cf;
662
+ long yint, move, idx, tmpx, first, last;
663
+ Data_Get_Struct(self, cGrid, cg);
664
+ VALUE argv[3];
665
+
666
+ yint = grid_coordinate(yval, "y-position");
667
+ move = (cg->height - yint) * cg->width;
668
+ grid_set_dimensions(cg, cg->width, cg->height + 1);
669
+ first = (cg->height * cg->width);
670
+ last = first-move;
671
+ for(idx = first-1, tmpx=idx-cg->width; idx >= last; idx--, tmpx--)
672
+ {
673
+ cf = cg->fields[idx];
674
+ cg->fields[idx] = cg->fields[tmpx];
675
+ cg->fields[tmpx] = cf;
676
+ }
677
+ first = cg->width * yint;
678
+ last = yint + cg->width;
679
+
680
+ argv[0] = item;
681
+ argv[1] = INT2FIX(0);
682
+ argv[2] = yval;
683
+ grid_add(3, argv, self);
684
+ return item;
685
+ }
686
+
687
+ void grid_block_iterate(cg, xint, yint, wint, hint, callback, arg)
688
+ cGrid * cg;
689
+ long xint, yint, wint, hint;
690
+ void * callback ();
691
+ VALUE arg;
692
+ {
693
+ cField * cf;
694
+ long yend, ypos, pos, idx;
695
+
696
+ yend = yint + hint;
697
+ grid_set_dimensions(cg, xint + wint, yend);
698
+ for(ypos = yint; ypos < yend; ypos++)
699
+ {
700
+ pos = grid_pos(cg, xint, ypos);
701
+ for(idx=0; idx < wint; idx++, pos++)
702
+ {
703
+ cf = cg->fields[pos];
704
+ callback(cf, arg);
705
+ }
706
+ }
707
+ }
708
+
709
+ VALUE grid_iterate(argc, argv, self, callback, creative)
710
+ long argc;
711
+ VALUE *argv, self;
712
+ void * callback();
713
+ int creative;
714
+ {
715
+ VALUE value, xval, yval, wval, hval;
716
+ cGrid *cg;
717
+ long xint, yint, wint, hint;
718
+
719
+ rb_scan_args(argc, argv, "32", &value, &xval, &yval, &wval, &hval);
720
+ Data_Get_Struct(self, cGrid, cg);
721
+ xint = grid_coordinate(xval, "x-position");
722
+ yint = grid_coordinate(yval, "y-position");
723
+ if(wval == Qnil)
724
+ wint = 1;
725
+ else
726
+ wint = grid_coordinate(wval, "width");
727
+ if(hval == Qnil)
728
+ hint = 1;
729
+ else
730
+ hint = grid_coordinate(hval, "height");
731
+
732
+ if(!creative)
733
+ {
734
+ if(xint >= cg->width || yint >= cg->height)
735
+ return Qnil;
736
+ if((xint + wint) > cg->width)
737
+ wint = cg->width - xint;
738
+ if((yint + hint) > cg->height)
739
+ hint = cg->height - yint;
740
+ }
741
+
742
+ grid_block_iterate(cg, xint, yint, wint, hint,
743
+ callback, value);
744
+
745
+ return value;
746
+ }
747
+
748
+ void grid_field_add_tag(cf, tagname)
749
+ cField * cf;
750
+ VALUE tagname;
751
+ {
752
+ strcpy(cf->tag, STR2CSTR(tagname));
753
+ }
754
+
755
+ VALUE grid_add_tag(argc, argv, self)
756
+ long argc;
757
+ VALUE *argv, self;
758
+ {
759
+ return grid_iterate(argc, argv, self, grid_field_add_tag, 1);
760
+ }
761
+
762
+ void grid_field_add_attribute(cf, pair)
763
+ cField * cf;
764
+ VALUE pair;
765
+ {
766
+ if(cf->attributes == Qnil)
767
+ cf->attributes = rb_hash_new();
768
+ rb_hsh_store_pair(pair, cf->attributes);
769
+ }
770
+
771
+ //VALUE grid_row_set_attributes(self, ahash, yval)
772
+ // VALUE self, ahash, yval;
773
+ VALUE grid_row_set_attributes(argc, argv, self)
774
+ long argc;
775
+ VALUE *argv, self;
776
+ {
777
+ VALUE ahash, yval, hval;
778
+
779
+ rb_scan_args(argc, argv, "21", &ahash, &yval, &hval);
780
+
781
+ cGrid * cg;
782
+ long ypos, hint, idx;
783
+ Data_Get_Struct(self, cGrid, cg);
784
+
785
+ if(hval == Qnil)
786
+ hint = 1;
787
+ else
788
+ hint = grid_coordinate(hval, "height");
789
+
790
+ ypos = grid_coordinate(yval, "y-position");
791
+ grid_set_dimensions(cg, cg->width, ypos + hint);
792
+ for(idx = 0; idx < hint; idx++) {
793
+ cg->row_attributes[ypos+idx] = ahash;
794
+ }
795
+
796
+ return ahash;
797
+ }
798
+
799
+ VALUE grid_add_attribute(argc, argv, self)
800
+ long argc;
801
+ VALUE *argv, self;
802
+ {
803
+ long argc2, idx;
804
+ argc2 = argc - 1;
805
+ VALUE key, value, xval, yval, wval, hval, pair;
806
+ VALUE argv2[argc2];
807
+ rb_scan_args(argc, argv, "42",
808
+ &key, &value, &xval, &yval, &wval, &hval);
809
+
810
+ pair = rb_ary_new();
811
+ rb_ary_push(pair, key);
812
+ rb_ary_push(pair, value);
813
+
814
+ argv2[0] = pair;
815
+ for(idx=1; idx<argc2; idx++)
816
+ {
817
+ argv2[idx] = argv[idx + 1];
818
+ }
819
+
820
+ return grid_iterate(argc2, argv2, self,
821
+ grid_field_add_attribute, 1);
822
+ }
823
+
824
+ void grid_field_add_component_style(cf, style)
825
+ cField * cf;
826
+ VALUE style;
827
+ {
828
+ ID set_attribute = rb_intern("set_attribute");
829
+ VALUE item;
830
+ long idx;
831
+ VALUE str_class = rb_str_new2("class");
832
+ for(idx=0; idx<cf->content_count; idx++)
833
+ {
834
+ item = cf->content[idx];
835
+ if(rb_respond_to(item, set_attribute))
836
+ {
837
+ rb_funcall(item, set_attribute, 2,
838
+ str_class, style);
839
+ }
840
+ }
841
+ }
842
+
843
+ VALUE grid_add_component_style(argc, argv, self)
844
+ long argc;
845
+ VALUE *argv, self;
846
+ {
847
+ return grid_iterate(argc, argv, self,
848
+ grid_field_add_component_style, 0);
849
+ }
850
+
851
+ void grid_field_add_style(cf, style)
852
+ cField * cf;
853
+ VALUE style;
854
+ {
855
+ if(cf->attributes == Qnil)
856
+ cf->attributes = rb_hash_new();
857
+ rb_hash_aset(cf->attributes, rb_str_new2("class"), style);
858
+ }
859
+
860
+ VALUE grid_add_style(argc, argv, self)
861
+ long argc;
862
+ VALUE *argv, self;
863
+ {
864
+ return grid_iterate(argc, argv, self, grid_field_add_style, 1);
865
+ }
866
+
867
+ VALUE grid_field_attribute(self, name, xval, yval)
868
+ VALUE self, name, xval, yval;
869
+ {
870
+ cGrid * cg;
871
+ cField * cf;
872
+ long xpos, ypos;
873
+ Data_Get_Struct(self, cGrid, cg);
874
+ xpos = grid_coordinate(xval, "x-position");
875
+ ypos = grid_coordinate(yval, "y-position");
876
+
877
+ if((xpos >= cg->width) || (ypos >= cg->height))
878
+ return Qnil;
879
+ cf = cg->fields[grid_pos(cg, xpos, ypos)];
880
+ return rb_hash_aref(cf->attributes, name);
881
+ }