00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <ctype.h>
00038
00039 #include "contiki.h"
00040
00041 #include "ctk/ctk.h"
00042 #include "ctk-draw.h"
00043
00044 #ifndef NULL
00045 #define NULL (void *)0
00046 #endif
00047
00048 static unsigned char sizex, sizey;
00049
00050 unsigned char ctk_draw_windowborder_height = 1;
00051 unsigned char ctk_draw_windowborder_width = 1;
00052 unsigned char ctk_draw_windowtitle_height = 1;
00053
00054
00055
00056 static unsigned char
00057 cputsn(char *str, unsigned char len)
00058 {
00059 unsigned char cnt = 0;
00060 char c;
00061
00062 while(cnt < len) {
00063 c = *str;
00064 if(c == 0) {
00065 break;
00066 }
00067 cputc(c);
00068 ++str;
00069 ++cnt;
00070 }
00071 return cnt;
00072 }
00073
00074 void
00075 ctk_draw_init(void)
00076 {
00077 (void)bgcolor(SCREENCOLOR);
00078 (void)bordercolor(BORDERCOLOR);
00079 (void)textcolor(WINDOWCOLOR_FOCUS);
00080 screensize(&sizex, &sizey);
00081 ctk_draw_clear(0, sizey);
00082 gotoxy(0, 0);
00083 }
00084
00085 static void
00086 draw_widget(struct ctk_widget *w,
00087 unsigned char x, unsigned char y,
00088 unsigned char clipx, unsigned char clipy,
00089 unsigned char clipy1, unsigned char clipy2,
00090 unsigned char focus)
00091 {
00092 unsigned char xpos, ypos, xscroll;
00093 unsigned char i, j;
00094 char c, *text;
00095 unsigned char wfocus;
00096 #if CTK_CONF_ICONS
00097 unsigned char len;
00098 #endif
00099
00100 wfocus = 0;
00101 if(focus & CTK_FOCUS_WINDOW) {
00102 (void)textcolor(WIDGETCOLOR_FWIN);
00103 if(focus & CTK_FOCUS_WIDGET) {
00104 (void)textcolor(WIDGETCOLOR_FOCUS);
00105 wfocus = 1;
00106 }
00107 #if CTK_CONF_WINDOWS
00108 } else if(focus & CTK_FOCUS_DIALOG) {
00109 (void)textcolor(WIDGETCOLOR_DIALOG);
00110 if(focus & CTK_FOCUS_WIDGET) {
00111 (void)textcolor(WIDGETCOLOR_FOCUS);
00112 wfocus = 1;
00113 }
00114 #endif
00115 } else {
00116 (void)textcolor(WIDGETCOLOR);
00117 }
00118
00119 xpos = x + w->x;
00120 ypos = y + w->y;
00121
00122 switch(w->type) {
00123 case CTK_WIDGET_SEPARATOR:
00124 if(ypos >= clipy1 && ypos < clipy2) {
00125 chlinexy(xpos, ypos, w->w);
00126 }
00127 break;
00128 case CTK_WIDGET_LABEL:
00129 text = w->widget.label.text;
00130 for(j = 0; j < w->h; ++j) {
00131 if(ypos >= clipy1 && ypos < clipy2) {
00132 gotoxy(xpos, ypos);
00133 i = cputsn(text, w->w);
00134 if(w->w - i > 0) {
00135 cclear(w->w - i);
00136 }
00137 }
00138 ++ypos;
00139 text += w->w;
00140 }
00141 break;
00142 case CTK_WIDGET_BUTTON:
00143 if(ypos >= clipy1 && ypos < clipy2) {
00144 revers(wfocus != 0);
00145 cputcxy(xpos, ypos, '[');
00146 cputsn(w->widget.button.text, w->w);
00147 cputc(']');
00148 revers(0);
00149 }
00150 break;
00151 case CTK_WIDGET_HYPERLINK:
00152 if(ypos >= clipy1 && ypos < clipy2) {
00153 revers(wfocus == 0);
00154 gotoxy(xpos, ypos);
00155 (void)textcolor(WIDGETCOLOR_HLINK);
00156 cputsn(w->widget.button.text, w->w);
00157 revers(0);
00158 }
00159 break;
00160 case CTK_WIDGET_TEXTENTRY:
00161 text = w->widget.textentry.text;
00162 xscroll = 0;
00163 if(w->widget.textentry.xpos >= w->w - 1) {
00164 xscroll = w->widget.textentry.xpos - w->w + 1;
00165 }
00166 for(j = 0; j < w->h; ++j) {
00167 if(ypos >= clipy1 && ypos < clipy2) {
00168 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
00169 w->widget.textentry.ypos == j) {
00170 revers(0);
00171 cputcxy(xpos, ypos, '>');
00172 c = 1;
00173 for(i = 0; i < w->w; ++i) {
00174 if(c != 0) {
00175 c = text[i + xscroll];
00176 }
00177 revers(i == w->widget.textentry.xpos - xscroll);
00178 if(c == 0) {
00179 cputc(' ');
00180 } else {
00181 cputc(c);
00182 }
00183 }
00184 revers(0);
00185 cputc('<');
00186 } else {
00187 revers(wfocus != 0 && j == w->widget.textentry.ypos);
00188 cvlinexy(xpos, ypos, 1);
00189 gotoxy(xpos + 1, ypos);
00190 i = cputsn(text, w->w);
00191 if(w->w - i > 0) {
00192 cclear(w->w - i);
00193 }
00194 cvline(1);
00195 }
00196 }
00197 ++ypos;
00198 text += w->widget.textentry.len + 1;
00199 }
00200 revers(0);
00201 break;
00202 #if CTK_CONF_ICONS
00203 case CTK_WIDGET_ICON:
00204 if(ypos >= clipy1 && ypos < clipy2) {
00205 revers(wfocus != 0);
00206 #if CTK_CONF_ICON_TEXTMAPS
00207 if(w->widget.icon.textmap != NULL) {
00208 for(i = 0; i < 3; ++i) {
00209 gotoxy(xpos, ypos);
00210 if(ypos >= clipy1 && ypos < clipy2) {
00211 cputc(w->widget.icon.textmap[0 + 3 * i]);
00212 cputc(w->widget.icon.textmap[1 + 3 * i]);
00213 cputc(w->widget.icon.textmap[2 + 3 * i]);
00214 }
00215 ++ypos;
00216 }
00217 }
00218 #endif
00219
00220 len = (unsigned char)strlen(w->widget.icon.title);
00221 if(xpos + len >= sizex) {
00222 xpos = sizex - len;
00223 }
00224
00225 gotoxy(xpos, ypos);
00226 if(ypos >= clipy1 && ypos < clipy2) {
00227 cputs(w->widget.icon.title);
00228 }
00229 revers(0);
00230 }
00231 break;
00232 #endif
00233
00234 default:
00235 break;
00236 }
00237 }
00238
00239 void
00240 ctk_draw_widget(struct ctk_widget *w, unsigned char focus,
00241 unsigned char clipy1, unsigned char clipy2)
00242 {
00243 struct ctk_window *win = w->window;
00244 unsigned char posx, posy;
00245
00246 #if CTK_CONF_WINDOWS
00247 posx = win->x + 1;
00248 posy = win->y + 1 + CTK_CONF_MENUS;
00249 #else
00250 posx = 0;
00251 posy = 0;
00252 #endif
00253
00254 if(w == win->focused) {
00255 focus |= CTK_FOCUS_WIDGET;
00256 }
00257
00258 draw_widget(w, posx, posy, posx + win->w, posy + win->h, clipy1, clipy2, focus);
00259
00260 #ifdef CTK_CONIO_CONF_UPDATE
00261 CTK_CONIO_CONF_UPDATE();
00262 #endif
00263 }
00264
00265 void
00266 ctk_draw_clear_window(struct ctk_window *window, unsigned char focus,
00267 unsigned char clipy1, unsigned char clipy2)
00268 {
00269 unsigned char i;
00270 #if CTK_CONF_WINDOWS
00271 unsigned char h;
00272 #endif
00273
00274 if(focus & CTK_FOCUS_WINDOW) {
00275 (void)textcolor(WINDOWCOLOR_FOCUS);
00276 } else {
00277 (void)textcolor(WINDOWCOLOR);
00278 }
00279
00280 #if CTK_CONF_WINDOWS
00281 h = window->y + 1 + CTK_CONF_MENUS + window->h;
00282
00283
00284 for(i = window->y + 1 + CTK_CONF_MENUS; i < h; ++i) {
00285 if(i >= clipy1 && i < clipy2) {
00286 cclearxy(window->x + 1, i, window->w);
00287 }
00288 }
00289 #else
00290 for(i = 0; i < window->h; ++i) {
00291 if(i >= clipy1 && i < clipy2) {
00292 cclearxy(0, i, window->w);
00293 }
00294 }
00295 #endif
00296 }
00297
00298 static void
00299 draw_window_contents(struct ctk_window *window, unsigned char focus,
00300 unsigned char clipy1, unsigned char clipy2,
00301 unsigned char x1, unsigned char x2,
00302 unsigned char y1, unsigned char y2)
00303 {
00304 struct ctk_widget *w;
00305 unsigned char wfocus;
00306
00307
00308 for(w = window->inactive; w != NULL; w = w->next) {
00309 draw_widget(w, x1, y1, x2, y2, clipy1, clipy2, focus);
00310 }
00311
00312
00313 for(w = window->active; w != NULL; w = w->next) {
00314 wfocus = focus;
00315 if(w == window->focused) {
00316 wfocus |= CTK_FOCUS_WIDGET;
00317 }
00318
00319 draw_widget(w, x1, y1, x2, y2, clipy1, clipy2, wfocus);
00320 }
00321
00322 #ifdef CTK_CONIO_CONF_UPDATE
00323 CTK_CONIO_CONF_UPDATE();
00324 #endif
00325 }
00326
00327 void
00328 ctk_draw_window(struct ctk_window *window, unsigned char focus,
00329 unsigned char clipy1, unsigned char clipy2,
00330 unsigned char draw_borders)
00331 {
00332 #if CTK_CONF_WINDOWS
00333 unsigned char x, y;
00334 unsigned char x1, y1, x2, y2;
00335 unsigned char h;
00336
00337 if(window->y + CTK_CONF_MENUS >= clipy2) {
00338 return;
00339 }
00340
00341 x = window->x;
00342 y = window->y + CTK_CONF_MENUS;
00343 x1 = x + 1;
00344 y1 = y + 1;
00345 x2 = x1 + window->w;
00346 y2 = y1 + window->h;
00347
00348 if(draw_borders) {
00349
00350
00351 if(focus & CTK_FOCUS_WINDOW) {
00352 (void)textcolor(WINDOWCOLOR_FOCUS);
00353 } else {
00354 (void)textcolor(WINDOWCOLOR);
00355 }
00356
00357 if(y >= clipy1) {
00358 cputcxy(x, y, (char)CH_ULCORNER);
00359 gotoxy(wherex() + window->titlelen + CTK_CONF_WINDOWMOVE * 2, wherey());
00360 chline(window->w - (wherex() - x) - 2);
00361 cputcxy(x2, y, (char)CH_URCORNER);
00362 }
00363
00364 h = window->h;
00365
00366 if(clipy1 > y1) {
00367 if(clipy1 - y1 < h) {
00368 h = clipy1 - y1;
00369 y1 = clipy1;
00370 } else {
00371 h = 0;
00372 }
00373 }
00374
00375 if(clipy2 < y1 + h) {
00376 if(y1 >= clipy2) {
00377 h = 0;
00378 } else {
00379 h = clipy2 - y1;
00380 }
00381 }
00382
00383 cvlinexy(x, y1, h);
00384 cvlinexy(x2, y1, h);
00385
00386 if(y + window->h >= clipy1 && y + window->h < clipy2) {
00387 cputcxy(x, y2, (char)CH_LLCORNER);
00388 chlinexy(x1, y2, window->w);
00389 cputcxy(x2, y2, (char)CH_LRCORNER);
00390 }
00391 }
00392
00393 draw_window_contents(window, focus, clipy1, clipy2, x1, x2, y + 1, y2);
00394
00395 #else
00396
00397 draw_window_contents(window, focus, clipy1, clipy2, 0, window->w, 0, window->h);
00398
00399 #endif
00400 }
00401
00402 #if CTK_CONF_WINDOWS
00403 void
00404 ctk_draw_dialog(struct ctk_window *dialog)
00405 {
00406 unsigned char x, y;
00407 unsigned char i;
00408 unsigned char x1, y1, x2, y2;
00409
00410 (void)textcolor(DIALOGCOLOR);
00411
00412 x = dialog->x;
00413 y = dialog->y + CTK_CONF_MENUS;
00414
00415 x1 = x + 1;
00416 y1 = y + 1;
00417 x2 = x1 + dialog->w;
00418 y2 = y1 + dialog->h;
00419
00420
00421 cvlinexy(x, y1, dialog->h);
00422 cvlinexy(x2, y1, dialog->h);
00423
00424 chlinexy(x1, y, dialog->w);
00425 chlinexy(x1, y2, dialog->w);
00426
00427 cputcxy(x, y, (char)CH_ULCORNER);
00428 cputcxy(x, y2, (char)CH_LLCORNER);
00429 cputcxy(x2, y, (char)CH_URCORNER);
00430 cputcxy(x2, y2, (char)CH_LRCORNER);
00431
00432
00433 for(i = y1; i < y2; ++i) {
00434 cclearxy(x1, i, dialog->w);
00435 }
00436
00437 draw_window_contents(dialog, CTK_FOCUS_DIALOG, 0, sizey, x1, x2, y1, y2);
00438 }
00439 #endif
00440
00441 void
00442 ctk_draw_clear(unsigned char y1, unsigned char y2)
00443 {
00444 unsigned char i;
00445
00446 for(i = y1; i < y2; ++i) {
00447 cclearxy(0, i, sizex);
00448 }
00449 }
00450
00451 #if CTK_CONF_MENUS
00452 static void
00453 draw_menu(struct ctk_menu *m, unsigned char open)
00454 {
00455 unsigned char x, x2, y;
00456
00457 if(open) {
00458 x = x2 = wherex();
00459 if(x2 + CTK_CONF_MENUWIDTH > sizex) {
00460 x2 = sizex - CTK_CONF_MENUWIDTH;
00461 }
00462
00463 for(y = 0; y < m->nitems; ++y) {
00464 if(y == m->active) {
00465 (void)textcolor(ACTIVEMENUITEMCOLOR);
00466 revers(0);
00467 } else {
00468 (void)textcolor(MENUCOLOR);
00469 revers(1);
00470 }
00471 gotoxy(x2, y + 1);
00472 if(m->items[y].title[0] == '-') {
00473 chline(CTK_CONF_MENUWIDTH);
00474 } else {
00475 cputs(m->items[y].title);
00476 }
00477 if(x2 + CTK_CONF_MENUWIDTH > wherex()) {
00478 cclear(x2 + CTK_CONF_MENUWIDTH - wherex());
00479 }
00480 }
00481
00482 gotoxy(x, 0);
00483 (void)textcolor(OPENMENUCOLOR);
00484 revers(0);
00485 }
00486
00487 cputs(m->title);
00488 cputc(' ');
00489 (void)textcolor(MENUCOLOR);
00490 revers(1);
00491 }
00492
00493 void
00494 ctk_draw_menus(struct ctk_menus *menus)
00495 {
00496 struct ctk_menu *m;
00497
00498
00499 (void)textcolor(MENUCOLOR);
00500 gotoxy(0, 0);
00501 revers(1);
00502 cputc(' ');
00503 for(m = menus->menus->next; m != NULL; m = m->next) {
00504 draw_menu(m, m == menus->open);
00505 }
00506
00507
00508 if(wherex() + strlen(menus->desktopmenu->title) + 1 >= sizex) {
00509 gotoxy(sizex - (unsigned char)strlen(menus->desktopmenu->title) - 1, 0);
00510 } else {
00511 cclear(sizex - wherex() -
00512 (unsigned char)strlen(menus->desktopmenu->title) - 1);
00513 }
00514 draw_menu(menus->desktopmenu, menus->desktopmenu == menus->open);
00515
00516 revers(0);
00517 }
00518 #endif
00519
00520 unsigned char
00521 ctk_draw_height(void)
00522 {
00523 return sizey;
00524 }
00525
00526 unsigned char
00527 ctk_draw_width(void)
00528 {
00529 return sizex;
00530 }
00531