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
00037
00038
00039
00040
00041
00042
00043 #include "ctk/ctk.h"
00044 #include "ctk/ctk-draw.h"
00045 #include "contiki-conf.h"
00046 #include "ctk/ctk_arch.h"
00047 #include <string.h>
00048
00049 #ifndef NULL
00050 #define NULL (void *)0
00051 #endif
00052
00053
00054 static char cursx, cursy;
00055 static unsigned char reversed;
00056 static char cy1, cy2;
00057
00058 unsigned char ctk_draw_windowtitle_height = 1;
00059
00060
00061 #define revers(c) reversed = c
00062 #define clip(y1, y2) cy1 = y1; cy2 = y2
00063 #define OFFSET(x, y) y * SCREEN_WIDTH + x
00064
00065
00066 void cputc(char c) {
00067 if (cursy >= cy1 && cursy <= cy2
00068 && cursy >= 0 && cursy <= SCREEN_HEIGHT
00069 && cursx >= 0 && cursx < SCREEN_WIDTH) {
00070 unsigned int offset = OFFSET(cursx, cursy);
00071 *((char *) VRAM_CHAR + offset) = c;
00072 *((char *) VRAM_ATTR + offset) = reversed ? COLOR_REVERSED : COLOR_NORMAL;
00073 }
00074 cursx++;
00075 }
00076
00077
00078 void cputs(char *str) {
00079 while (*str != 0) {
00080 cputc(*str);
00081 str++;
00082 }
00083 }
00084
00085 void cputsn(char *str, unsigned char len) {
00086 while ((len > 0) && (*str != 0)) {
00087 cputc(*str);
00088 str++;
00089 len--;
00090 }
00091 }
00092
00093 void chline(unsigned char length) {
00094 while (length > 0) {
00095 cputc(CH_HOLILINE);
00096 length--;
00097 }
00098 }
00099
00100
00101
00102
00103 void cvline(unsigned char length) {
00104 while (length > 0) {
00105 cputc(CH_VERTLINE);
00106 ++cursy;
00107 --cursx;
00108 length--;
00109 }
00110 }
00111
00112 void gotoxy(unsigned char x, unsigned char y) {
00113 cursx = x;
00114 cursy = y;
00115 }
00116
00117 void clearTo(char x) {
00118 while (cursx < x) {
00119 cputc(CH_SPACE);
00120 }
00121 cursx = x;
00122 }
00123
00124
00125 void ctk_draw_clear(unsigned char clipy1, unsigned char clipy2) {
00126 while (clipy1 < clipy2) {
00127 gotoxy(0, clipy1);
00128 clearTo(SCREEN_WIDTH);
00129 clipy1++;
00130 }
00131 }
00132
00133
00134 void ctk_draw_init(void) {
00135 clip(0, SCREEN_HEIGHT);
00136 ctk_draw_clear(0, SCREEN_HEIGHT);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 void
00147 draw_widget(struct ctk_widget *w,
00148 unsigned char x, unsigned char y,
00149 unsigned char focus) {
00150 unsigned char xpos, ypos, xscroll;
00151 unsigned char i, j;
00152 char c, *text;
00153 #if CTK_CONF_ICONS
00154 unsigned char len;
00155 #endif
00156
00157 xpos = x + w->x;
00158 ypos = y + w->y;
00159
00160 revers(focus & CTK_FOCUS_WIDGET);
00161 gotoxy(xpos, ypos);
00162
00163 if (w->type == CTK_WIDGET_SEPARATOR) {
00164 chline(w->w);
00165 } else if (w->type == CTK_WIDGET_LABEL) {
00166 text = w->widget.label.text;
00167 for(i = 0; i < w->h; ++i) {
00168 gotoxy(xpos, ypos);
00169 cputsn(text, w->w);
00170 clearTo(xpos + w->w);
00171 ++ypos;
00172 text += w->w;
00173 }
00174 } else if (w->type == CTK_WIDGET_BUTTON) {
00175 cputc('[');
00176 cputsn(w->widget.button.text, w->w);
00177 cputc(']');
00178 } else if (w->type == CTK_WIDGET_HYPERLINK) {
00179 cputsn(w->widget.hyperlink.text, w->w);
00180 } else if (w->type == CTK_WIDGET_TEXTENTRY) {
00181 text = w->widget.textentry.text;
00182 xscroll = 0;
00183 if(w->widget.textentry.xpos >= w->w - 1) {
00184 xscroll = w->widget.textentry.xpos - w->w + 1;
00185 }
00186 for(j = 0; j < w->h; ++j) {
00187 gotoxy(xpos, ypos);
00188 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
00189 w->widget.textentry.ypos == j) {
00190 revers(0);
00191 cputc('>');
00192 for(i = 0; i < w->w; ++i) {
00193 c = text[i + xscroll];
00194 revers(i == w->widget.textentry.xpos - xscroll);
00195 cputc((c == 0) ? CH_SPACE : c);
00196 }
00197 revers(0);
00198 cputc('<');
00199 } else {
00200 cputc(CH_VERTLINE);
00201 cputsn(text, w->w);
00202 clearTo(xpos + w->w + 1);
00203 cputc(CH_VERTLINE);
00204 }
00205 ++ypos;
00206 text += w->w;
00207 }
00208 #if CTK_CONF_ICONS
00209 } else if (w->type == CTK_WIDGET_ICON) {
00210 if(w->widget.icon.textmap != NULL) {
00211 for(i = 0; i < 3; ++i) {
00212 gotoxy(xpos, ypos);
00213 cputc(w->widget.icon.textmap[0 + 3 * i]);
00214 cputc(w->widget.icon.textmap[1 + 3 * i]);
00215 cputc(w->widget.icon.textmap[2 + 3 * i]);
00216 ++ypos;
00217 }
00218 x = xpos;
00219
00220 len = strlen(w->widget.icon.title);
00221 if(x + len >= SCREEN_WIDTH) {
00222 x = SCREEN_WIDTH - len;
00223 }
00224 gotoxy(x, ypos);
00225 cputs(w->widget.icon.title);
00226 }
00227 #endif
00228 }
00229 revers(0);
00230
00231 }
00232
00233 void
00234 ctk_draw_widget(struct ctk_widget *w,
00235 unsigned char focus,
00236 unsigned char clipy1,
00237 unsigned char clipy2) {
00238
00239 struct ctk_window *win = w->window;
00240 unsigned char posx, posy;
00241 clip(clipy1, clipy2);
00242
00243 posx = win->x + 1;
00244 posy = win->y + 2;
00245
00246 if(w == win->focused) {
00247 focus |= CTK_FOCUS_WIDGET;
00248 }
00249
00250 draw_widget(w, posx, posy, focus);
00251 }
00252
00253 void
00254 ctk_draw_clear_window(struct ctk_window *window,
00255 unsigned char focus,
00256 unsigned char clipy1,
00257 unsigned char clipy2) {
00258
00259 unsigned char i;
00260 unsigned char x1, x2, y1, y2;
00261 x1 = window->x + 1;
00262 x2 = x1 + window->w;
00263 y1 = window->y + 2;
00264 y2 = y1 + window->h;
00265
00266 for(i = y1; i < y2; ++i) {
00267 gotoxy(x1, i);
00268 clearTo(x2);
00269 }
00270 }
00271
00272 void draw_window_sub(struct ctk_window *window, unsigned char focus) {
00273
00274 unsigned char x, y;
00275 unsigned char x1, y1, x2;
00276 struct ctk_widget *w;
00277 unsigned char wfocus;
00278
00279 x = window->x;
00280 y = window->y + 1;
00281
00282 x1 = x + 1;
00283 y1 = y + 1;
00284 x2 = x1 + window->w;
00285
00286
00287 gotoxy(x, y1);
00288 cvline(window->h);
00289 cputc(CH_LLCORNER);
00290 chline(window->w);
00291 cputc(CH_LRCORNER);
00292
00293
00294 gotoxy(x, y);
00295 cputc(CH_ULCORNER);
00296 chline(window->w);
00297 cputc(CH_URCORNER);
00298
00299 gotoxy(x2, y1);
00300 cvline(window->h);
00301
00302
00303 for(w = window->inactive; w != NULL; w = w->next) {
00304 draw_widget(w, x1, y1, focus);
00305 }
00306
00307
00308 for(w = window->active; w != NULL; w = w->next) {
00309 wfocus = focus;
00310 if(w == window->focused) {
00311 wfocus |= CTK_FOCUS_WIDGET;
00312 }
00313 draw_widget(w, x1, y1, wfocus);
00314 }
00315 }
00316
00317 void
00318 ctk_draw_window(struct ctk_window *window, unsigned char focus,
00319 unsigned char clipy1, unsigned char clipy2, unsigned char draw_borders) {
00320 clip(clipy1, clipy2);
00321
00322 focus = focus & CTK_FOCUS_WINDOW;
00323 draw_window_sub(window, focus);
00324 }
00325
00326 void ctk_draw_dialog(struct ctk_window *dialog) {
00327 clip(0, SCREEN_HEIGHT);
00328
00329 ctk_draw_clear_window(dialog, 0, 0, SCREEN_HEIGHT);
00330 draw_window_sub(dialog, CTK_FOCUS_DIALOG);
00331 }
00332
00333 #if CTK_CONF_MENUS
00334 void draw_menu(struct ctk_menu *m, struct ctk_menu *open) {
00335 #if CC_CONF_UNSIGNED_CHAR_BUGS
00336 unsigned char x2;
00337 unsigned int x, y;
00338 #else
00339 unsigned char x2;
00340 unsigned char x, y;
00341 #endif
00342 x = cursx;
00343 cputs(m->title);
00344 cputc(CH_SPACE);
00345
00346 if (m == open) {
00347 x2 = cursx;
00348 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) {
00349 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH;
00350 }
00351
00352 for(y = 0; y < m->nitems; y++) {
00353 if(y == m->active) {
00354 revers(0);
00355 }
00356 gotoxy(x, y + 1);
00357 if(m->items[y].title[0] == '-') {
00358 chline(CTK_CONF_MENUWIDTH);
00359 } else {
00360 cputs(m->items[y].title);
00361 }
00362 clearTo(x + CTK_CONF_MENUWIDTH);
00363 revers(1);
00364 }
00365 gotoxy(x2, 0);
00366 }
00367 }
00368
00369 void ctk_draw_menus(struct ctk_menus *menus) {
00370 struct ctk_menu *m;
00371
00372 clip(0, SCREEN_HEIGHT);
00373
00374 gotoxy(0, 0);
00375 revers(1);
00376 for(m = menus->menus->next; m != NULL; m = m->next) {
00377 draw_menu(m, menus->open);
00378 }
00379
00380 clearTo(SCREEN_WIDTH - strlen(menus->desktopmenu->title) - 1);
00381
00382
00383 draw_menu(menus->desktopmenu, menus->open);
00384
00385 revers(0);
00386 }
00387 #endif
00388
00389
00390 unsigned char ctk_draw_width(void) {
00391 return SCREEN_WIDTH;
00392 }
00393 unsigned char ctk_draw_height(void) {
00394 return SCREEN_HEIGHT;
00395 }
00396