4 * Copyright (c) 2009-2012 project bchan
6 * This software is provided 'as-is', without any express or implied
7 * warranty. In no event will the authors be held liable for any damages
8 * arising from the use of this software.
10 * Permission is granted to anyone to use this software for any purpose,
11 * including commercial applications, and to alter it and redistribute it
12 * freely, subject to the following restrictions:
14 * 1. The origin of this software must not be misrepresented; you must not
15 * claim that you wrote the original software. If you use this software
16 * in a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source
27 #include "subjectlayout.h"
28 #include "subjectlist.h"
34 #include <btron/btron.h>
38 #ifdef BCHANL_CONFIG_DEBUG
39 # define DP(arg) printf arg
40 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
43 # define DP_ER(msg, err) /**/
46 LOCAL TC dec[] = {TK_0,TK_1,TK_2,TK_3,TK_4,TK_5,TK_6,TK_7,TK_8,TK_9};
48 LOCAL W WtoTCS(W num, TC *dest)
50 W digit,draw = 0,i = 0;
52 digit = num / 1000000000 % 10;
53 if ((digit != 0)||(draw != 0)) {
54 dest[i++] = dec[digit];
57 digit = num / 100000000 % 10;
58 if ((digit != 0)||(draw != 0)) {
59 dest[i++] = dec[digit];
62 digit = num / 10000000 % 10;
63 if ((digit != 0)||(draw != 0)) {
64 dest[i++] = dec[digit];
67 digit = num / 1000000 % 10;
68 if ((digit != 0)||(draw != 0)) {
69 dest[i++] = dec[digit];
72 digit = num / 100000 % 10;
73 if ((digit != 0)||(draw != 0)) {
74 dest[i++] = dec[digit];
77 digit = num / 10000 % 10;
78 if ((digit != 0)||(draw != 0)) {
79 dest[i++] = dec[digit];
82 digit = num / 1000 % 10;
83 if ((digit != 0)||(draw != 0)) {
84 dest[i++] = dec[digit];
87 digit = num / 100 % 10;
88 if ((digit != 0)||(draw != 0)) {
89 dest[i++] = dec[digit];
92 digit = num / 10 % 10;
93 if ((digit != 0)||(draw != 0)) {
94 dest[i++] = dec[digit];
98 dest[i++] = dec[digit];
105 LOCAL W DATE_TIMtoTCS(DATE_TIM *dtim, TC *dest)
109 len = WtoTCS(dtim->d_year + 1900, dest);
110 dest[len++] = TK_SLSH;
111 len += WtoTCS(dtim->d_month, dest + len);
112 dest[len++] = TK_SLSH;
113 len += WtoTCS(dtim->d_day, dest + len);
119 LOCAL W VIGORtoTCS(W vigor, TC *dest)
125 i = WtoTCS(n0, dest);
127 i += WtoTCS(n1, dest + i);
140 typedef struct sbjtlayout_thread_t_ sbjtlayout_thread_t;
141 struct sbjtlayout_thread_t_ {
142 sbjtlist_tuple_t *tuple;
144 W view_l,view_t,view_r,view_b;
150 #define SBJTLAYOUT_FLAG_RESNUM_DISPLAY 0x00000001
151 #define SBJTLAYOUT_FLAG_SINCE_DISPLAY 0x00000002
152 #define SBJTLAYOUT_FLAG_VIGOR_DISPLAY 0x00000004
154 struct sbjtlayout_t_ {
156 W draw_l,draw_t,draw_r,draw_b;
157 sbjtlayout_thread_t **layout_thread; /* should be QUEUE? */
164 LOCAL sbjtlayout_thread_t* sbjtlayout_thread_new(sbjtlist_tuple_t *thread)
166 sbjtlayout_thread_t *layout_thread;
168 layout_thread = (sbjtlayout_thread_t*)malloc(sizeof(sbjtlayout_thread_t));
169 if (layout_thread == NULL) {
172 layout_thread->tuple = thread;
173 layout_thread->view_l = 0;
174 layout_thread->view_t = 0;
175 layout_thread->view_r = 0;
176 layout_thread->view_b = 0;
178 return layout_thread;
181 LOCAL VOID sbjtlayout_thread_delete(sbjtlayout_thread_t *layout_thread)
186 LOCAL W sbjtlayout_thread_calcindexdrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
191 sbjtlist_tuple_getnumber(layout_thread->tuple, &num);
193 len = WtoTCS(num, str);
194 str[len++] = TK_COLN;
197 err = gget_stw(gid, str, len, NULL, NULL);
202 err = gget_sth(gid, str, len, NULL, NULL);
211 LOCAL W sbjtlayout_thread_calctitledrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
215 sbjtlist_tuple_gettitle(layout_thread->tuple, &str, &len);
216 return tadlib_calcdrawsize(str, len, gid, sz);
219 LOCAL W sbjtlayout_thread_calcresnumdrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
223 sbjtlist_tuple_getresnumberstr(layout_thread->tuple, &str, &len);
224 return tadlib_calcdrawsize(str, len, gid, sz);
227 LOCAL W sbjtlayout_thread_calcsincedrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
232 sbjtlist_tuple_getsince(layout_thread->tuple, &dtim);
233 len = DATE_TIMtoTCS(&dtim, str);
234 return tadlib_calcdrawsize(str, len, gid, sz);
237 LOCAL W sbjtlayout_thread_calcvigordrawsize(sbjtlayout_thread_t *layout_thread, GID gid, SIZE *sz)
242 sbjtlist_tuple_getvigor(layout_thread->tuple, &vigor);
243 len = VIGORtoTCS(vigor, str);
244 return tadlib_calcdrawsize(str, len, gid, sz);
247 LOCAL W sbjtlayout_thread_calcsize(sbjtlayout_thread_t *layout_res, GID gid, W top, sbjtlayout_t *layout)
249 SIZE sz_index, sz_title, sz_resnum, sz_since, sz_vigor;
253 err = sbjtlayout_thread_calcindexdrawsize(layout_res, gid, &sz_index);
257 err = sbjtlayout_thread_calctitledrawsize(layout_res, gid, &sz_title);
261 err = sbjtlayout_thread_calcresnumdrawsize(layout_res, gid, &sz_resnum);
265 err = sbjtlayout_thread_calcsincedrawsize(layout_res, gid, &sz_since);
269 err = sbjtlayout_thread_calcvigordrawsize(layout_res, gid, &sz_vigor);
274 layout_res->sz_title = sz_title;
276 layout_res->view_t = top + 2;
277 layout_res->view_l = 0;
278 layout_res->view_b = layout_res->view_t + sz_title.v + 16;
279 layout_res->view_r = 16*6 + sz_title.h;
280 ok = sbjtlayout_getresnumberdisplay(layout);
282 layout_res->view_r += sz_resnum.h;
284 ok = sbjtlayout_getsincedisplay(layout);
286 layout_res->view_r += 16 + sz_since.h;
288 ok = sbjtlayout_getvigordisplay(layout);
290 layout_res->view_r += 16 + sz_vigor.h;
293 layout_res->baseline = 20;
294 layout_res->vframe.c.left = sz_index.h + 16;
295 layout_res->vframe.c.top = layout_res->baseline - sz_title.v - 1;
296 layout_res->vframe.c.right = layout_res->vframe.c.left + sz_title.h + 21;
297 layout_res->vframe.c.bottom = layout_res->baseline + 3;
302 //#define sbjtlayout_fontconfig_class FTC_MINCHO
303 //#define sbjtlayout_fontconfig_class 0x000000c0 /* gothic */
304 #define sbjtlayout_fontconfig_class FTC_DEFAULT
306 LOCAL W sbjtlayout_setupgid(sbjtlayout_t *layout, GID gid)
308 return gset_fon(gid, &layout->fspec);
311 EXPORT W sbjtlayout_appendthread(sbjtlayout_t *layout, sbjtlist_tuple_t *tuple)
313 sbjtlayout_thread_t *layout_thread;
316 layout_thread = sbjtlayout_thread_new(tuple);
317 if (layout_thread == NULL) {
318 return -1; /* TODO */
321 len = layout->len + 1;
322 layout->layout_thread = (sbjtlayout_thread_t**)realloc(layout->layout_thread, sizeof(sbjtlayout_thread_t*)*len);
323 layout->layout_thread[layout->len] = layout_thread;
326 sbjtlayout_setupgid(layout, layout->target);
328 sbjtlayout_thread_calcsize(layout_thread, layout->target, layout->draw_b, layout);
331 if (layout->draw_l > layout_thread->view_l) {
332 layout->draw_l = layout_thread->view_l;
334 if (layout->draw_t > layout_thread->view_t) {
335 layout->draw_t = layout_thread->view_t;
337 if (layout->draw_r < layout_thread->view_r) {
338 layout->draw_r = layout_thread->view_r;
340 if (layout->draw_b < layout_thread->view_b) {
341 layout->draw_b = layout_thread->view_b;
347 EXPORT VOID sbjtlayout_getdrawrect(sbjtlayout_t *layout, W *l, W *t, W *r, W *b)
355 EXPORT VOID sbjtlayout_clear(sbjtlayout_t *layout)
359 if (layout->layout_thread != NULL) {
360 for (i=0;i<layout->len;i++) {
361 sbjtlayout_thread_delete(layout->layout_thread[i]);
363 free(layout->layout_thread);
369 layout->layout_thread = NULL;
373 EXPORT VOID sbjtlayout_setfsspec(sbjtlayout_t *layout, FSSPEC *fspec)
375 memcpy(&layout->fspec, fspec, sizeof(FSSPEC));
378 EXPORT VOID sbjtlayout_setvobjbgcol(sbjtlayout_t *layout, COLOR color)
380 layout->vobjbgcol = color;
383 EXPORT COLOR sbjtlayout_getvobjbgcol(sbjtlayout_t *layout)
385 return layout->vobjbgcol;
388 EXPORT VOID sbjtlayout_setresnumberdisplay(sbjtlayout_t *layout, Bool display)
390 if (display == False) {
391 layout->flag = layout->flag & ~SBJTLAYOUT_FLAG_RESNUM_DISPLAY;
393 layout->flag |= SBJTLAYOUT_FLAG_RESNUM_DISPLAY;
397 EXPORT VOID sbjtlayout_setsincedisplay(sbjtlayout_t *layout, Bool display)
399 if (display == False) {
400 layout->flag = layout->flag & ~SBJTLAYOUT_FLAG_SINCE_DISPLAY;
402 layout->flag |= SBJTLAYOUT_FLAG_SINCE_DISPLAY;
406 EXPORT VOID sbjtlayout_setvigordisplay(sbjtlayout_t *layout, Bool display)
408 if (display == False) {
409 layout->flag = layout->flag & ~SBJTLAYOUT_FLAG_VIGOR_DISPLAY;
411 layout->flag |= SBJTLAYOUT_FLAG_VIGOR_DISPLAY;
415 EXPORT Bool sbjtlayout_getresnumberdisplay(sbjtlayout_t *layout)
417 if ((layout->flag & SBJTLAYOUT_FLAG_RESNUM_DISPLAY) != 0) {
424 EXPORT Bool sbjtlayout_getsincedisplay(sbjtlayout_t *layout)
426 if ((layout->flag & SBJTLAYOUT_FLAG_SINCE_DISPLAY) != 0) {
433 EXPORT Bool sbjtlayout_getvigordisplay(sbjtlayout_t *layout)
435 if ((layout->flag & SBJTLAYOUT_FLAG_VIGOR_DISPLAY) != 0) {
442 EXPORT sbjtlayout_t* sbjtlayout_new(GID gid)
444 sbjtlayout_t *layout;
446 layout = (sbjtlayout_t*)malloc(sizeof(sbjtlayout_t));
447 if (layout == NULL) {
450 layout->target = gid;
455 layout->layout_thread = NULL;
457 layout->fspec.name[0] = TNULL;
458 layout->fspec.attr = FT_PROP|FT_GRAYSCALE;
459 layout->fspec.fclass = sbjtlayout_fontconfig_class;
460 layout->fspec.size.h = 16;
461 layout->fspec.size.v = 16;
462 layout->vobjbgcol = 0x10000000;
468 EXPORT VOID sbjtlayout_delete(sbjtlayout_t *layout)
472 if (layout->layout_thread != NULL) {
473 for (i=0;i<layout->len;i++) {
474 sbjtlayout_thread_delete(layout->layout_thread[i]);
476 free(layout->layout_thread);
482 sbjtlayout_t *layout;
483 W view_l, view_t, view_r, view_b;
486 LOCAL W sbjtdraw_entrydraw_drawtitle(sbjtlayout_thread_t *entry, GID gid, W dh, W dv)
490 sbjtlist_tuple_gettitle(entry->tuple, &str, &len);
491 return tadlib_drawtext(str, len, gid, dh, dv);
494 LOCAL W sbjtdraw_entrydraw_drawresnum(sbjtlayout_thread_t *entry, GID gid, W dh, W dv)
498 sbjtlist_tuple_getresnumberstr(entry->tuple, &str, &len);
499 return tadlib_drawtext(str, len, gid, dh, dv);
502 LOCAL W sbjtdraw_entrydraw_resnumber(sbjtlayout_thread_t *entry, W resnum, GID target)
508 len = WtoTCS(resnum, str);
509 return gdra_str(target, str, len, G_STORE);
512 LOCAL W sbjtdraw_entrydraw_drawsince(sbjtlayout_thread_t *entry, GID gid, W dh, W dv)
517 sbjtlist_tuple_getsince(entry->tuple, &dtim);
518 len = DATE_TIMtoTCS(&dtim, str);
519 return gdra_str(gid, str, len, G_STORE);
522 LOCAL W sbjtdraw_entrydraw_drawvigor(sbjtlayout_thread_t *entry, GID gid, W dh, W dv)
527 sbjtlist_tuple_getvigor(entry->tuple, &vigor);
528 len = VIGORtoTCS(vigor, str);
529 return gdra_str(gid, str, len, G_STORE);
532 LOCAL int sectrect_tmp(RECT a, W left, W top, W right, W bottom)
534 return (a.c.left<right && left<a.c.right && a.c.top<bottom && top<a.c.bottom);
537 LOCAL W sbjtdraw_drawthread(sbjtlayout_thread_t *entry, GID target, RECT *r, W dh, W dv, COLOR vobjbgcol, sbjtlayout_t *layout)
540 RECT view, vframe, vframe_b;
558 sect = sectrect_tmp(*r, entry->view_l - dh, entry->view_t - dv, entry->view_r - dh, entry->view_b - dv);
563 view.c.left = entry->view_l - dh;
564 view.c.top = entry->view_t - dv;
565 view.c.right = entry->view_r - dh;
566 view.c.bottom = entry->view_b - dv;
568 sbjtlist_tuple_getnumber(entry->tuple, &num);
570 err = gset_chp(target, - dh, entry->view_t + entry->baseline - dv, 1);
574 err = sbjtdraw_entrydraw_resnumber(entry, num, target);
578 err = gdra_chr(target, TK_COLN, G_STORE);
583 err = gset_chp(target, 16, 0, 0);
588 vframe.c.left = entry->vframe.c.left + view.c.left;
589 vframe.c.top = entry->vframe.c.top + view.c.top;
590 vframe.c.right = entry->vframe.c.right + view.c.left;
591 vframe.c.bottom = entry->vframe.c.bottom + view.c.top;
592 vframe_b.c.left = vframe.c.left + 2;
593 vframe_b.c.top = vframe.c.top + 2;
594 vframe_b.c.right = vframe.c.right + 2;
595 vframe_b.c.bottom = vframe.c.bottom + 2;
596 pat1.spat.fgcol = vobjbgcol;
597 gfra_rec(target, vframe_b, 1, &pat0, 0, G_STORE);
598 gfil_rec(target, vframe, &pat1, 0, G_STORE);
599 gfra_rec(target, vframe, 1, &pat0, 0, G_STORE);
600 gset_chc(target, 0x10000000, vobjbgcol);
602 err = gset_chp(target, entry->vframe.c.left+view.c.left+10, entry->baseline + view.c.top, 1);
607 err = sbjtdraw_entrydraw_drawtitle(entry, target, dh, dv);
612 gset_chc(target, 0x10000000, 0x10FFFFFF);
613 ok = sbjtlayout_getresnumberdisplay(layout);
614 err = gset_chp(target, 16, 0, 0);
619 err = sbjtdraw_entrydraw_drawresnum(entry, target, dh, dv);
624 ok = sbjtlayout_getsincedisplay(layout);
626 err = gset_chp(target, 16, 0, 0);
630 err = sbjtdraw_entrydraw_drawsince(entry, target, dh, dv);
635 ok = sbjtlayout_getvigordisplay(layout);
637 err = gset_chp(target, 16, 0, 0);
641 err = sbjtdraw_entrydraw_drawvigor(entry, target, dh, dv);
650 EXPORT W sbjtdraw_draw(sbjtdraw_t *draw, RECT *r)
654 sbjtlayout_t *layout;
656 layout = draw->layout;
657 target = layout->target;
659 for (i=0;i < layout->len;i++) {
660 sbjtlayout_setupgid(layout, layout->target);
661 err = sbjtdraw_drawthread(layout->layout_thread[i], target, r, draw->view_l, draw->view_t, layout->vobjbgcol, layout);
670 EXPORT W sbjtdraw_findthread(sbjtdraw_t *draw, PNT rel_pos, sbjtlist_tuple_t **thread, RECT *vframe)
672 W i,abs_x,abs_y,l,t,r,b;
673 sbjtlayout_t *layout;
674 sbjtlayout_thread_t *sbjt_thread;
676 layout = draw->layout;
677 abs_x = rel_pos.x + draw->view_l;
678 abs_y = rel_pos.y + draw->view_t;
680 for (i=0;i < layout->len;i++) {
681 sbjt_thread = layout->layout_thread[i];
682 l = sbjt_thread->view_l + sbjt_thread->vframe.c.left;
683 t = sbjt_thread->view_t + sbjt_thread->vframe.c.top;
684 r = sbjt_thread->view_l + sbjt_thread->vframe.c.right;
685 b = sbjt_thread->view_t + sbjt_thread->vframe.c.bottom;
686 if ((l <= abs_x)&&(abs_x < r)
687 &&(t <= abs_y)&&(abs_y < b)) {
688 *thread = sbjt_thread->tuple;
689 if (vframe != NULL) {
690 vframe->c.left = l - draw->view_l;
691 vframe->c.top = t - draw->view_t;
692 vframe->c.right = r - draw->view_l;
693 vframe->c.bottom = b - draw->view_t;
702 EXPORT VOID sbjtdraw_setviewrect(sbjtdraw_t *draw, W l, W t, W r, W b)
710 EXPORT VOID sbjtdraw_getviewrect(sbjtdraw_t *draw, W *l, W *t, W *r, W *b)
718 EXPORT VOID sbjtdraw_scrollviewrect(sbjtdraw_t *draw, W dh, W dv)
726 EXPORT sbjtdraw_t* sbjtdraw_new(sbjtlayout_t *layout)
730 draw = (sbjtdraw_t*)malloc(sizeof(sbjtdraw_t));
734 draw->layout = layout;
743 EXPORT VOID sbjtdraw_delete(sbjtdraw_t *draw)