57 #include "ctk/ctk-mouse.h"
59 static unsigned char height, width;
61 static unsigned char mode;
75 static unsigned char maxnitems;
79 #define NULL (void *)0
84 #define REDRAW_FOCUS 2
85 #define REDRAW_WIDGETS 4
86 #define REDRAW_MENUS 8
87 #define REDRAW_MENUPART 16
89 #define MAX_REDRAWWIDGETS 4
90 static unsigned char redraw;
91 static struct ctk_widget *redraw_widgets[MAX_REDRAWWIDGETS];
92 static unsigned char redraw_widgetptr;
95 static unsigned char iconx, icony;
96 #define ICONX_START (width - 6)
97 #define ICONY_START (height - 6 - CTK_CONF_MENUS)
98 #define ICONX_DELTA -16
99 #define ICONY_DELTA -5
100 #define ICONY_MAX height
103 #ifndef ctk_arch_keyavail
107 #ifndef ctk_arch_getkey
111 #ifndef ctk_arch_isprint
115 PROCESS(ctk_process,
"CTK Contiki GUI");
158 #if CTK_CONF_MOUSE_SUPPORT
162 process_event_t ctk_signal_pointer_move,
165 ctk_signal_pointer_button;
168 #if CTK_CONF_SCREENSAVER
171 process_event_t ctk_signal_screensaver_stop,
174 ctk_signal_screensaver_start;
179 #if CTK_CONF_MOUSE_SUPPORT
180 unsigned short mouse_x, mouse_y, mouse_button;
183 #if CTK_CONF_SCREENSAVER
184 static unsigned short screensaver_timer = 0;
185 unsigned short ctk_screensaver_timeout = (5*60);
204 make_desktopmenu(
void)
208 desktopmenu.nitems = 0;
210 if(windows ==
NULL) {
213 for(w = windows; w !=
NULL; w = w->
next) {
229 for(icon = desktop_window.active; icon !=
NULL; icon = icon->
next) {
234 icony += ICONY_DELTA;
235 if(icony >= ICONY_MAX) {
237 iconx += ICONX_DELTA;
248 height = ctk_draw_height();
249 width = ctk_draw_width();
308 icon->widget.icon.owner = p;
325 redraw |= REDRAW_FOCUS;
334 ctk_dialog_close(
void)
337 redraw |= REDRAW_ALL;
354 for(w2 = windows; w2 != w && w2 !=
NULL; w2 = w2->
next);
359 if(windows !=
NULL) {
368 if(w->next !=
NULL) {
369 w->next->prev = w->prev;
371 if(w->prev !=
NULL) {
372 w->prev->next = w->next;
389 redraw |= REDRAW_ALL;
403 #if CTK_CONF_WINDOWCLOSE
413 if(windows !=
NULL) {
421 for(w2 = windows; w2 !=
NULL && w2->
next !=
w; w2 = w2->
next);
440 redraw |= REDRAW_ALL;
452 unsigned char placement;
454 if(ctk_draw_windowtitle_height >= 2) {
455 placement = -1 - ctk_draw_windowtitle_height/2;
459 #if CTK_CONF_WINDOWMOVE
460 CTK_BUTTON_NEW(&window->titlebutton, 0, placement,
461 window->titlelen, window->title);
463 CTK_LABEL_NEW(&window->titlebutton, 0, placement,
464 window->titlelen, 1, window->title);
468 #if CTK_CONF_WINDOWCLOSE
469 CTK_BUTTON_NEW(&window->closebutton, window->w - 3, placement,
472 CTK_LABEL_NEW(&window->closebutton, window->w - 4, placement,
491 make_windowbuttons(w);
510 if(lastmenu ==
NULL) {
522 redraw |= REDRAW_MENUPART;
539 if(m->
next == menu) {
541 if(menu == lastmenu) {
544 redraw |= REDRAW_MENUPART;
560 do_redraw_all(
unsigned char clipy1,
unsigned char clipy2)
568 if(mode != CTK_MODE_NORMAL && mode != CTK_MODE_WINDOWMOVE) {
576 for(widget = desktop_window.active;
577 widget !=
NULL; widget = widget->
next) {
582 if(windows !=
NULL) {
587 for(; w != windows; w = w->
prev) {
593 focus = mode == CTK_MODE_WINDOWMOVE?
628 ctk_desktop_redraw(
struct ctk_desktop *d)
631 if(mode == CTK_MODE_NORMAL || mode == CTK_MODE_WINDOWMOVE) {
632 do_redraw_all(CTK_CONF_MENUS, height);
635 height = ctk_draw_height();
636 width = ctk_draw_width();
638 redraw |= REDRAW_ALL;
657 if(mode != CTK_MODE_NORMAL) {
664 }
else if(dialog ==
NULL &&
666 menus.open ==
NULL &&
686 unsigned char w,
unsigned char h,
char *
title)
692 window->x = (width - w - 2) / 2;
694 if(h >= height - 2 - ctk_draw_windowtitle_height) {
697 window->y = (height - h - 2 - ctk_draw_windowtitle_height) / 2;
703 window->title =
title;
705 window->titlelen = (
unsigned char)strlen(title);
707 window->titlelen = 0;
709 window->next = window->prev =
NULL;
711 window->active = window->inactive = window->focused =
NULL;
734 unsigned char w,
unsigned char h,
char *title)
736 window_new(window, w, h, title);
739 make_windowbuttons(window);
758 unsigned char w,
unsigned char h)
760 window_new(dialog, w, h,
NULL);
781 menu->titlelen = (
unsigned char)strlen(title);
804 if(menu->nitems == CTK_MAXMENUITEMS) {
807 menu->items[menu->nitems].title = name;
808 menu->items[menu->nitems].titlelen = (
unsigned char)strlen(name);
809 return menu->nitems++;
825 static unsigned char i;
827 if(redraw_widgetptr == MAX_REDRAWWIDGETS) {
828 redraw |= REDRAW_FOCUS;
830 redraw |= REDRAW_WIDGETS;
833 for(i = 0; i < redraw_widgetptr; ++i) {
834 if(redraw_widgets[i] == w) {
838 redraw_widgets[redraw_widgetptr++] =
w;
858 if(mode != CTK_MODE_NORMAL || widget ==
NULL) {
871 if(menus.open ==
NULL)
876 if(window == dialog) {
878 }
else if(dialog ==
NULL &&
879 (window == windows ||
880 window == &desktop_window))
905 if(mode != CTK_MODE_NORMAL || widget ==
NULL) {
911 add_redrawwidget(widget);
931 widget->next = window->inactive;
932 window->inactive = widget;
933 widget->window = window;
935 widget->next = window->active;
936 window->active = widget;
937 widget->window = window;
953 return ctk_draw_width();
968 return ctk_draw_height();
995 add_redrawwidget(window->
focused);
1006 switch_focus_widget(
unsigned char direction)
1008 #if CTK_CONF_WINDOWS
1014 #if CTK_CONF_WINDOWS
1015 if(dialog !=
NULL) {
1023 if(window ==
NULL) {
1024 window = &desktop_window;
1027 if(window ==
NULL) {
1039 add_redrawwidget(focus);
1041 if((direction & 1) == 0) {
1043 focus = focus->
next;
1046 for(widget = window->
active;
1047 widget !=
NULL; widget = widget->
next) {
1048 if(widget->
next == focus) {
1055 for(focus = window->
active;
1064 select_widget(focus);
1069 switch_open_menu(
unsigned char rightleft)
1073 if(rightleft == 0) {
1075 for(menu = menus.menus; menu !=
NULL; menu = menu->
next) {
1076 if(menu->
next == menus.open) {
1080 lastmenu = menus.open;
1082 if(menus.open ==
NULL) {
1083 for(menu = menus.menus;
1089 lastmenu = menus.open;
1090 menus.open = menus.open->
next;
1091 if(menus.open ==
NULL) {
1092 menus.open = menus.menus;
1100 switch_menu_item(
unsigned char updown)
1134 #if CTK_CONF_WINDOWCLOSE
1135 if(w == (
struct ctk_widget *)&windows->closebutton) {
1141 #if CTK_CONF_WINDOWMOVE
1142 if(w == (
struct ctk_widget *)&windows->titlebutton) {
1143 mode = CTK_MODE_WINDOWMOVE;
1152 if(w->widget.icon.owner != PROCESS_NONE) {
1161 if(w->widget.textentry.state == CTK_TEXTENTRY_NORMAL) {
1162 w->widget.textentry.state = CTK_TEXTENTRY_EDIT;
1163 textentry_input(0, (
struct ctk_textentry *)w);
1165 w->widget.textentry.state = CTK_TEXTENTRY_NORMAL;
1168 add_redrawwidget(w);
1169 return REDRAW_WIDGETS;
1181 ctk_textentry_input_null(
ctk_arch_key_t c,
struct ctk_textentry *t)
1190 register char *cptr, *cptr2;
1191 static unsigned char len, txpos, typos, tlen;
1193 if(t->input !=
NULL && t->input(c, t)) {
1201 cptr = &t->text[txpos + typos * (tlen + 1)];
1211 if(txpos < tlen - 1 && *cptr != 0) {
1222 txpos = (
unsigned char)strlen(t->text);
1230 switch_focus_widget(DOWN);
1233 case CTK_CONF_WIDGETDOWN_KEY:
1234 t->state = CTK_TEXTENTRY_NORMAL;
1235 switch_focus_widget(DOWN);
1237 case CTK_CONF_WIDGETUP_KEY:
1238 t->state = CTK_TEXTENTRY_NORMAL;
1239 switch_focus_widget(UP);
1245 if(len == 1 && *cptr != 0) {
1250 strcpy(cptr - 1, cptr);
1254 if(ctk_arch_isprint(c)) {
1256 cptr2 = cptr + len - 1;
1257 while(cptr2 > cptr) {
1258 *cptr2 = *(cptr2 - 1);
1274 static unsigned char
1279 lastmenu = menus.open;
1280 if(menus.open == &desktopmenu) {
1281 for(w = windows; w !=
NULL; w = w->
next) {
1282 if(w->
title == desktopmenu.items[desktopmenu.active].title) {
1292 return REDRAW_MENUPART;
1295 static unsigned char
1298 if(menus.open->nitems > maxnitems) {
1299 maxnitems = menus.open->nitems;
1304 switch_open_menu(1);
1305 return REDRAW_MENUPART;
1308 switch_menu_item(1);
1309 return REDRAW_MENUS;
1312 switch_open_menu(0);
1313 return REDRAW_MENUPART;
1316 switch_menu_item(0);
1317 return REDRAW_MENUS;
1320 return activate_menu();
1322 case CTK_CONF_MENU_KEY:
1323 lastmenu = menus.open;
1325 return REDRAW_MENUPART;
1332 #if CTK_CONF_SCREENSAVER
1336 if(mode == CTK_MODE_NORMAL) {
1337 ++screensaver_timer;
1338 if(screensaver_timer >= ctk_screensaver_timeout) {
1340 #ifdef CTK_SCREENSAVER_INIT
1341 CTK_SCREENSAVER_INIT();
1344 screensaver_timer = 0;
1354 redraw |= REDRAW_WIDGETS;
1355 add_redrawwidget(w);
1357 ((
struct ctk_textentry *)w)->state =
1358 CTK_TEXTENTRY_NORMAL;
1360 w->window->focused =
NULL;
1367 static unsigned char i;
1368 #if CTK_CONF_WINDOWS
1373 #if CTK_CONF_MOUSE_SUPPORT
1374 static unsigned char mxc, myc, mouse_button_changed, mouse_moved,
1377 static unsigned char menux;
1387 menus.menus = menus.desktopmenu = &desktopmenu;
1390 #if CTK_CONF_MOUSE_SUPPORT
1397 #if CTK_CONF_WINDOWS
1398 desktop_window.owner = &ctk_process;
1416 #if CTK_CONF_MOUSE_SUPPORT
1421 #if CTK_CONF_SCREENSAVER
1426 mode = CTK_MODE_NORMAL;
1429 iconx = ICONX_START;
1430 icony = ICONY_START;
1433 #if CTK_CONF_SCREENSAVER
1441 #if CTK_CONF_SCREENSAVER
1449 if(menus.open !=
NULL) {
1450 maxnitems = menus.open->nitems;
1456 #if CTK_CONF_MOUSE_SUPPORT
1457 mouse_button_changed = mouse_moved = mouse_clicked = 0;
1460 if(ctk_mouse_button() != mouse_button) {
1461 mouse_button = ctk_mouse_button();
1462 mouse_button_changed = 1;
1463 if(mouse_button == 0) {
1469 if(ctk_mouse_x() != mouse_x ||
1470 ctk_mouse_y() != mouse_y) {
1471 mouse_x = ctk_mouse_x();
1472 mouse_y = ctk_mouse_y();
1476 mxc = ctk_mouse_xtoc(mouse_x);
1477 myc = ctk_mouse_ytoc(mouse_y);
1480 #if CTK_CONF_SCREENSAVER
1481 if(mode == CTK_MODE_SCREENSAVER) {
1483 #
if CTK_CONF_MOUSE_SUPPORT
1484 || mouse_moved || mouse_button_changed
1488 mode = CTK_MODE_NORMAL;
1492 if(mode == CTK_MODE_NORMAL) {
1493 #if CTK_CONF_MOUSE_SUPPORT
1497 if(mouse_moved || mouse_button_changed) {
1499 #if CTK_CONF_SCREENSAVER
1500 screensaver_timer = 0;
1516 for(menu = menus.menus->
next;
1519 if(mxc >= menux && mxc <= menux + titlelen) {
1526 if(mxc >= width - 7 &&
1528 menu = &desktopmenu;
1532 redraw |= REDRAW_MENUPART;
1537 if(menus.open !=
NULL) {
1538 static unsigned char nitems;
1544 if(menus.open == &desktopmenu) {
1545 menux = width - CTK_CONF_MENUWIDTH;
1548 for(menu = menus.menus->
next; menu != menus.open;
1549 menu = menu->
next) {
1554 nitems = menus.open->nitems;
1557 if(mxc >= menux && mxc <= menux + CTK_CONF_MENUWIDTH) {
1559 menus.open->active = myc;
1561 menus.open->active = nitems - 1;
1566 if(mxc >= menux && mxc <= menux + CTK_CONF_MENUWIDTH &&
1568 redraw |= activate_menu();
1570 lastmenu = menus.open;
1572 redraw |= REDRAW_MENUPART;
1575 redraw |= REDRAW_MENUS;
1580 #if CTK_CONF_WINDOWS
1583 if(dialog !=
NULL) {
1586 for(window = windows; window !=
NULL;
1587 window = window->
next) {
1590 if(mxc >= window->x &&
1591 mxc <= window->x + window->
w +
1592 2 * ctk_draw_windowborder_width &&
1594 myc <= window->y + window->
h +
1595 ctk_draw_windowtitle_height +
1596 ctk_draw_windowborder_height) {
1605 if(window ==
NULL) {
1606 window = &desktop_window;
1613 if(windows !=
NULL &&
1614 window != windows &&
1616 unfocus_widget(windows->
focused);
1620 if(window !=
NULL) {
1621 #if CTK_CONF_WINDOWS
1624 if(dialog ==
NULL &&
1625 window != &desktop_window &&
1626 window != windows &&
1630 redraw |= REDRAW_ALL;
1636 mxc = mxc - window->x - ctk_draw_windowborder_width;
1637 myc = myc - window->y - ctk_draw_windowtitle_height;
1644 widget = widget->
next) {
1646 if(mxc >= widget->
x &&
1647 mxc <= widget->x + widget->
w + 1 &&
1649 myc <= widget->y + widget->
h - 1) {
1658 #
if CTK_CONF_WINDOWS
1659 && (window != &desktop_window || windows ==
NULL)
1670 unfocus_widget(window->
focused);
1672 redraw |= REDRAW_WIDGETS;
1673 if(widget !=
NULL) {
1674 select_widget(widget);
1678 if(mouse_button_changed) {
1680 (process_data_t)(
size_t)mouse_button);
1681 if(mouse_clicked && widget !=
NULL) {
1682 select_widget(widget);
1683 redraw |= activate(widget);
1686 #if CTK_CONF_WINDOWS
1701 #if CTK_CONF_SCREENSAVER
1702 screensaver_timer = 0;
1707 #if CTK_CONF_WINDOWS
1708 if(dialog !=
NULL) {
1710 }
else if(windows !=
NULL) {
1713 window = &desktop_window;
1716 if(window ==
NULL) {
1731 if(widget !=
NULL &&
1733 widget->
widget.textentry.state == CTK_TEXTENTRY_EDIT) {
1734 textentry_input(c, (
struct ctk_textentry *)widget);
1735 add_redrawwidget(widget);
1737 }
else if(menus.open !=
NULL) {
1738 redraw |= menus_input(c);
1742 case CTK_CONF_WIDGETDOWN_KEY:
1743 switch_focus_widget(DOWN);
1745 case CTK_CONF_WIDGETUP_KEY:
1746 switch_focus_widget(UP);
1749 case CTK_CONF_MENU_KEY:
1750 if(dialog ==
NULL) {
1751 if(lastmenu ==
NULL) {
1752 menus.open = menus.menus;
1754 menus.open = lastmenu;
1757 redraw |= REDRAW_MENUS;
1761 #if CTK_CONF_WINDOWS
1762 case CTK_CONF_WINDOWSWITCH_KEY:
1763 if(windows !=
NULL) {
1764 for(window = windows; window->
next !=
NULL;
1765 window = window->
next);
1774 redraw |= activate(widget);
1776 if(widget !=
NULL &&
1778 if(widget->
widget.textentry.state == CTK_TEXTENTRY_NORMAL) {
1779 widget->
widget.textentry.state = CTK_TEXTENTRY_EDIT;
1780 textentry_input(0, (
struct ctk_textentry *)widget);
1782 textentry_input(c, (
struct ctk_textentry *)widget);
1783 add_redrawwidget(widget);
1785 unfocus_widget(window->
focused);
1787 (process_data_t)(
size_t)c);
1795 if(redraw & REDRAW_WIDGETS) {
1796 widgetptr = redraw_widgets;
1797 for(i = 0; i < MAX_REDRAWWIDGETS; ++i) {
1798 widget_redraw(*widgetptr);
1802 redraw &= ~REDRAW_WIDGETS;
1803 redraw_widgetptr = 0;
1807 #if CTK_CONF_WINDOWMOVE
1808 }
else if(mode == CTK_MODE_WINDOWMOVE) {
1814 #if CTK_CONF_MOUSE_SUPPORT
1819 if(window->
w + mxc + 2 >= width) {
1820 window->x = width - 2 - window->
w;
1825 if(window->
h + myc + ctk_draw_windowtitle_height +
1826 ctk_draw_windowborder_height >= height) {
1827 window->y = height - window->
h -
1828 ctk_draw_windowtitle_height - ctk_draw_windowborder_height;
1838 redraw = REDRAW_ALL;
1843 if(mouse_button_changed &&
1844 mouse_button == 0) {
1845 mode = CTK_MODE_NORMAL;
1846 redraw = REDRAW_ALL;
1852 #if CTK_CONF_SCREENSAVER
1853 screensaver_timer = 0;
1861 if(window->x + window->
w + 1 >= width) {
1864 redraw = REDRAW_ALL;
1870 redraw = REDRAW_ALL;
1874 if(window->y + window->
h + 1 + CTK_CONF_MENUS >= height) {
1877 redraw = REDRAW_ALL;
1883 redraw = REDRAW_ALL;
1886 mode = CTK_MODE_NORMAL;
1887 redraw = REDRAW_ALL;
1894 if(redraw & REDRAW_ALL) {
1895 do_redraw_all(CTK_CONF_MENUS, height);
1897 }
else if(redraw & REDRAW_MENUPART) {
1898 do_redraw_all(CTK_CONF_MENUS, maxnitems + 1);
1899 }
else if(redraw & REDRAW_MENUS) {
1902 }
else if(redraw & REDRAW_FOCUS) {
1903 #if CTK_CONF_WINDOWS
1904 if(dialog !=
NULL) {
1906 }
else if(windows !=
NULL) {
1912 if(window !=
NULL) {
1916 }
else if(redraw & REDRAW_WIDGETS) {
1917 widgetptr = redraw_widgets;
1918 for(i = 0; i < MAX_REDRAWWIDGETS; ++i) {
1919 widget_redraw(*widgetptr);
1925 redraw_widgetptr = 0;