00001
00038 #include <led.h>
00039 #include <board.h>
00040 #include <membag.h>
00041 #include <string.h>
00042 #include <mainloop.h>
00043
00044 #include <fs/tsfs.h>
00045
00046 #include <gfx/gfx.h>
00047 #include <gfx/win.h>
00048 #include <gfx/wtk.h>
00049 #include <gfx/sysfont.h>
00050
00051 #include "app_desktop.h"
00052 #include "app_calibrate.h"
00053 #include "app_calc.h"
00054 #include "app_clock.h"
00055 #ifdef CONFIG_HUGEMEM
00056 # include "app_fonts.h"
00057 # include "app_slideshow.h"
00058 # include "app_tank.h"
00059 # include "app_files.h"
00060 # include "app_memgame.h"
00061 #endif
00062 #include "app_widget.h"
00063
00064 #include "file_loader.h"
00065
00078
00079 #define DESKTOP_NUM_APPS_PER_COLUMN 4
00080
00081 #define DESKTOP_NUM_APPS_PER_ROW 3
00082
00083 #define DESKTOP_APP_COUNT (DESKTOP_NUM_APPS_PER_COLUMN * \
00084 DESKTOP_NUM_APPS_PER_ROW)
00085
00087
00094
00095 #define DESKTOP_BACKGROUND_COLOR GFX_COLOR(0, 0, 0)
00096
00097 #define DESKTOP_ICON_TEXT_COLOR GFX_COLOR(255, 255, 255)
00098
00099 #define DESKTOP_POPUP_BORDER_COLOR GFX_COLOR(255, 42, 42)
00100
00102
00109
00110 #define DESKTOP_ICON_NAME_SIZE 9
00111
00112 #define DESKTOP_ICON_TEXT_SIZE 11
00113
00114 #define DESKTOP_ICON_SPACING_X 80
00115
00116 #define DESKTOP_ICON_SPACING_Y 80
00117
00118 #define DESKTOP_ICON_POS_X 11
00119
00120 #define DESKTOP_ICON_POS_Y 7
00121
00122 #define DESKTOP_ICON_SIZE_X 57
00123
00124 #define DESKTOP_ICON_SIZE_Y 57
00125
00126 #define DESKTOP_ICON_TEXT_X (DESKTOP_ICON_SPACING_X / 2)
00127
00128 #define DESKTOP_ICON_TEXT_Y ((DESKTOP_ICON_POS_Y + \
00129 DESKTOP_ICON_SIZE_Y + DESKTOP_ICON_SPACING_Y) / 2)
00130
00132
00139
00140 #define DESKTOP_POPUP_PADDING 20
00141
00142 #define DESKTOP_POPUP_HEIGHT (gfx_font_get_height(&sysfont) * 5)
00143
00144 #define DESKTOP_POPUP_WIDTH (gfx_get_width() - 2 * \
00145 DESKTOP_POPUP_PADDING)
00146
00147 #define DESKTOP_POPUP_POS_X DESKTOP_POPUP_PADDING
00148
00149 #define DESKTOP_POPUP_POS_Y ((gfx_get_height() / 2) - \
00150 (DESKTOP_POPUP_HEIGHT / 2))
00151
00153
00155 #define DESKTOP_REGISTER_APP(icon,text,start_task) \
00156 { .icon_name = icon, .icon_text=text,.task=start_task }
00157
00159 struct app_desktop {
00161 struct workqueue_task desktop_worker_task;
00163 struct workqueue_task application_launcher_task;
00165 bool desktop_enabled;
00166 };
00167
00169 static struct app_desktop the_app_desktop;
00170
00171 #ifdef CONFIG_FS_TSFS
00172
00173 extern struct tsfs myfs;
00174 #endif
00175
00177 struct app_config {
00179 char icon_name[DESKTOP_ICON_NAME_SIZE];
00181 char icon_text[DESKTOP_ICON_TEXT_SIZE];
00183 workqueue_func_t task;
00184 };
00185
00194 struct app_config apps[DESKTOP_APP_COUNT] = {
00195 DESKTOP_REGISTER_APP("i_calc", "Calc", app_calc_launch),
00196 DESKTOP_REGISTER_APP("i_sett", "Widget", app_widget_launch),
00197 DESKTOP_REGISTER_APP("i_clock", "Clock", app_clock_launch),
00198 #ifdef CONFIG_FS_TSFS
00199 DESKTOP_REGISTER_APP("i_fonts", "Fonts", app_fonts_launch),
00200
00201 DESKTOP_REGISTER_APP("i_pics", "Pictures", app_slideshow_pics_launch),
00202 DESKTOP_REGISTER_APP("i_tank", "Water tank", app_tank_launch),
00203 DESKTOP_REGISTER_APP("i_files", "Files", app_files_launch),
00204 DESKTOP_REGISTER_APP("i_games", "Memory", app_memgame_launch),
00205
00206 DESKTOP_REGISTER_APP("i_avr", "8-bit", app_slideshow_avr_launch),
00207 DESKTOP_REGISTER_APP("i_uc3", "32-bit", app_slideshow_uc3_launch),
00208 DESKTOP_REGISTER_APP("i_xmega", "XMEGA", app_slideshow_xmega_launch),
00209 DESKTOP_REGISTER_APP("i_avr", "This kit", app_slideshow_dx_launch),
00210 #else
00211 DESKTOP_REGISTER_APP("", "", NULL),
00212 DESKTOP_REGISTER_APP("", "", NULL),
00213 DESKTOP_REGISTER_APP("", "", NULL),
00214 DESKTOP_REGISTER_APP("", "", NULL),
00215
00216 DESKTOP_REGISTER_APP("", "", NULL),
00217 DESKTOP_REGISTER_APP("", "", NULL),
00218 DESKTOP_REGISTER_APP("", "", NULL),
00219 DESKTOP_REGISTER_APP("", "", NULL),
00220 #endif
00221 };
00222
00228 static void app_desktop_enable(void)
00229 {
00230 the_app_desktop.desktop_enabled = true;
00231 }
00232
00239 static void app_desktop_disable(void)
00240 {
00241 the_app_desktop.desktop_enabled = false;
00242 }
00243
00249 static bool app_desktop_is_enabled(void)
00250 {
00251 return the_app_desktop.desktop_enabled;
00252 }
00253
00264 void app_desktop_restart(void)
00265 {
00266 workqueue_add_task(&main_workqueue, &the_app_desktop.desktop_worker_task);
00267 }
00268
00269
00280 static void get_icon_pos(uint8_t iconnum, gfx_coord_t *x, gfx_coord_t *y)
00281 {
00282 *x = iconnum % DESKTOP_NUM_APPS_PER_COLUMN * DESKTOP_ICON_SPACING_X;
00283 *y = iconnum / DESKTOP_NUM_APPS_PER_COLUMN * DESKTOP_ICON_SPACING_Y;
00284 }
00285
00296 static void draw_icon_text(const char text[], gfx_coord_t center_x,
00297 gfx_coord_t center_y)
00298 {
00299 gfx_coord_t x;
00300 gfx_coord_t y;
00301
00302 gfx_get_string_bounding_box(text, &sysfont, &x, &y);
00303 gfx_draw_string((char *)text, center_x - x / 2, center_y - y / 2,
00304 &sysfont, DESKTOP_ICON_TEXT_COLOR,
00305 GFX_COLOR_TRANSPARENT);
00306 }
00307
00308 #ifdef CONFIG_FS_TSFS
00309
00315 static void app_desktop_popup_empty_tsfs(void)
00316 {
00317 gfx_draw_filled_rect(DESKTOP_POPUP_POS_X, DESKTOP_POPUP_POS_Y,
00318 DESKTOP_POPUP_WIDTH, DESKTOP_POPUP_HEIGHT,
00319 DESKTOP_BACKGROUND_COLOR);
00320 gfx_draw_rect(DESKTOP_POPUP_POS_X, DESKTOP_POPUP_POS_Y,
00321 DESKTOP_POPUP_WIDTH, DESKTOP_POPUP_HEIGHT,
00322 DESKTOP_POPUP_BORDER_COLOR);
00323 gfx_draw_string("Warning: file system empty, please program\n\n"
00324 "the DataFlash to contain a proper TSFS image.",
00325 DESKTOP_POPUP_POS_X + gfx_font_get_height(&sysfont),
00326 DESKTOP_POPUP_POS_Y + gfx_font_get_width(&sysfont),
00327 &sysfont, DESKTOP_ICON_TEXT_COLOR,
00328 GFX_COLOR_TRANSPARENT);
00329 }
00330 #endif
00331
00345 static bool app_desktop_handler(struct win_window *win,
00346 enum win_event_type type, void const *data)
00347 {
00348 static gfx_coord_t last_x;
00349 static gfx_coord_t last_y;
00350 static gfx_coord_t x = 0;
00351 static gfx_coord_t y = 0;
00352
00353
00354 if (!app_desktop_is_enabled()) {
00355 return true;
00356 }
00357
00358 if (type == WIN_EVENT_POINTER) {
00359
00360
00361 struct win_pointer_event const *event =
00362 (struct win_pointer_event const *)data;
00363 uint8_t i;
00364
00365 switch (event->type) {
00366 case WIN_POINTER_PRESS:
00367
00368 x = event->pos.x / DESKTOP_ICON_SPACING_X;
00369 y = event->pos.y / DESKTOP_ICON_SPACING_Y;
00370
00371 last_x = x * DESKTOP_ICON_SPACING_X;
00372 last_y = y * DESKTOP_ICON_SPACING_Y;
00373 gfx_draw_rect(last_x, last_y,
00374 DESKTOP_ICON_SPACING_X,
00375 DESKTOP_ICON_SPACING_Y,
00376 DESKTOP_ICON_TEXT_COLOR);
00377 break;
00378
00379 case WIN_POINTER_RELEASE:
00380
00381
00382
00383 gfx_draw_rect(last_x, last_y,
00384 DESKTOP_ICON_SPACING_X,
00385 DESKTOP_ICON_SPACING_Y,
00386 DESKTOP_BACKGROUND_COLOR);
00387
00388 i = x + y * DESKTOP_NUM_APPS_PER_COLUMN;
00389
00390 if ((i < DESKTOP_APP_COUNT) && (apps[i].task)) {
00391 app_desktop_disable();
00392
00393 workqueue_task_set_work_func
00394 (&the_app_desktop.application_launcher_task,
00395 apps[i].task);
00396
00397 workqueue_add_task(&main_workqueue,
00398 &the_app_desktop.application_launcher_task);
00399 } else {
00400 dbg_error("Not implemented\n");
00401 }
00402
00403 break;
00404
00405 default:
00406 break;
00407 }
00408 }
00409
00410 return true;
00411 }
00412
00413
00414 #ifdef CONFIG_FS_TSFS
00415
00430 static void load_desktop(struct workqueue_task *task)
00431 {
00432 static uint8_t i = 0;
00433 gfx_coord_t x;
00434 gfx_coord_t y;
00435 enum status_code result;
00436
00437 if (file_loader_busy()) {
00438
00439 workqueue_add_task(&main_workqueue, task);
00440 return;
00441 }
00442
00443
00444 if (i > DESKTOP_APP_COUNT) {
00445
00446
00447
00448
00449 if (!tsfs_nr_files(&myfs)) {
00450 app_desktop_popup_empty_tsfs();
00451 }
00452
00453
00454 i = 0;
00455
00456 app_desktop_enable();
00457 return;
00458 }
00459
00460
00461 if (i == 0) {
00462
00463 app_desktop_disable();
00464
00465
00466 gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());
00467 gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
00468 DESKTOP_BACKGROUND_COLOR);
00469 win_redraw(win_get_root());
00470 }
00471
00472
00473 get_icon_pos(i, &x, &y);
00474 draw_icon_text(apps[i].icon_text, x + DESKTOP_ICON_TEXT_X,
00475 y + DESKTOP_ICON_TEXT_Y);
00476
00477 x += DESKTOP_ICON_POS_X;
00478 y += DESKTOP_ICON_POS_Y;
00479
00480
00481 if (strlen(apps[i].icon_name) > 0) {
00482
00483 result = load_file_to_screen(apps[i].icon_name, x, y,
00484 DESKTOP_ICON_SIZE_X, DESKTOP_ICON_SIZE_Y, task);
00485
00486 if (result != STATUS_OK) {
00487
00488 gfx_draw_rect(x, y, DESKTOP_ICON_SIZE_X,
00489 DESKTOP_ICON_SIZE_Y,
00490 DESKTOP_ICON_TEXT_COLOR);
00491 gfx_draw_line(x, y, x + DESKTOP_ICON_SIZE_X - 1,
00492 y + DESKTOP_ICON_SIZE_Y - 1,
00493 DESKTOP_ICON_TEXT_COLOR);
00494 gfx_draw_line(x, y + DESKTOP_ICON_SIZE_Y - 1,
00495 x + DESKTOP_ICON_SIZE_X - 1, y,
00496 DESKTOP_ICON_TEXT_COLOR);
00497
00498 workqueue_add_task(&main_workqueue, task);
00499 }
00500 } else {
00501
00502 workqueue_add_task(&main_workqueue, task);
00503 }
00504
00505 i++;
00506 }
00507 #else
00508
00519 static void load_desktop(struct workqueue_task *task)
00520 {
00521 uint8_t i;
00522 uint8_t shade;
00523 gfx_coord_t x;
00524 gfx_coord_t y;
00525
00526
00527 app_desktop_disable();
00528
00529 gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());
00530 gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
00531 DESKTOP_BACKGROUND_COLOR);
00532 win_redraw(win_get_root());
00533
00534
00535 shade = 128;
00536 for (i = 0; i < ARRAY_LEN(apps); i++) {
00537 get_icon_pos(i, &x, &y);
00538 draw_icon_text(apps[i].icon_text, x + DESKTOP_ICON_TEXT_X,
00539 y + DESKTOP_ICON_TEXT_Y);
00540
00541 x += DESKTOP_ICON_POS_X;
00542 y += DESKTOP_ICON_POS_Y;
00543
00544 if (strlen(apps[i].icon_name) > 0) {
00545
00546 gfx_draw_filled_rect(x, y, DESKTOP_ICON_SIZE_X,
00547 DESKTOP_ICON_SIZE_Y,
00548 gfx_color(76, 76, shade));
00549
00550 shade += 6;
00551 }
00552 }
00553
00554 app_desktop_enable();
00555 }
00556 #endif
00557
00574 void app_desktop_setup(void)
00575 {
00576 struct win_window *win_root;
00577 struct win_attributes attr;
00578
00579 win_root = win_get_root();
00580
00581 attr = *win_get_attributes(win_root);
00582 attr.background = NULL;
00583 attr.event_handler = app_desktop_handler;
00584 win_set_attributes(win_root, &attr,
00585 WIN_ATTR_BACKGROUND | WIN_ATTR_EVENTHANDLER);
00586
00587 win_show(win_root);
00588
00589 #ifdef CONFIG_FS_TSFS
00590 file_loader_init();
00591 #endif
00592 workqueue_task_init(&the_app_desktop.desktop_worker_task, load_desktop);
00593 workqueue_task_init(&the_app_desktop.application_launcher_task, NULL);
00594
00595 #if CONFIG_GFX_WIN_USE_TOUCH
00596 app_touch_calibrate_setup(&the_app_desktop.desktop_worker_task);
00597 #else
00598 workqueue_add_task(&main_workqueue,
00599 &the_app_desktop.desktop_worker_task);
00600 #endif
00601 }
00602