00001
00039 #include <led.h>
00040 #include <board.h>
00041 #include <string.h>
00042
00043 #include <gfx/gfx.h>
00044 #include <gfx/win.h>
00045 #include <gfx/wtk.h>
00046 #include <gfx/sysfont.h>
00047 #include <membag.h>
00048 #include <debug.h>
00049 #include <mainloop.h>
00050
00051 #include "app_desktop.h"
00052 #include "app_widget.h"
00053
00066 enum command_id {
00068 DUMMY_ID,
00070 SLIDER_ID,
00072 CHECK_BOX_ID,
00074 RADIO_BUTTON_1_ID,
00076 RADIO_BUTTON_2_ID,
00078 BUTTON_QUIT_ID,
00079 };
00080
00087
00088 #define COLOR_SCHEME_0_FG GFX_COLOR(255,255,0)
00089
00090 #define COLOR_SCHEME_0_BG GFX_COLOR(0,50,0)
00091
00092 #define COLOR_SCHEME_1_FG GFX_COLOR(0,255,0)
00093
00094 #define COLOR_SCHEME_1_BG GFX_COLOR(0,100,100)
00095
00096 #define APP_BACKGROUND_COLOR GFX_COLOR(0,0,0)
00097
00098 #define SUBFRAME_BACKGROUND_COLOR GFX_COLOR(90,90,90)
00099
00101
00108
00109 #define LABEL_POS_X 10
00110
00111 #define LABEL_POS_Y 10
00112
00114 #define SUBFRAME_HORIZONTAL_SPACING 45
00115
00116 #define SUBFRAME_TOP_SPACING 10
00117
00118 #define SUBFRAME_BOTTOM_SPACING 30
00119
00121 #define WIDGET_POS_X 10
00122
00124 #define SLIDER_POS_Y 10
00125
00126 #define SLIDER_SIZE_X 80
00127
00128 #define SLIDER_SIZE_Y 40
00129
00131 #define SLIDER_PB_SPACING_X 10
00132
00133 #define PB_SIZE_X SLIDER_SIZE_X
00134
00135 #define PB_SIZE_Y SLIDER_SIZE_Y
00136
00138 #define CHECK_BOX_SPACING_Y 20
00139
00141 #define RADIO_BUTTON_SPACING_Y 5
00142
00144
00146 const static char demo_string[] = "Demonstrating widgets";
00148 const static char checkbox_string[] = "Invert colors";
00150 const static char rb1_string[] = "Color scheme 1";
00152 const static char rb2_string[] = "Color scheme 2";
00153
00155 struct widget_context {
00157 struct wtk_basic_frame *frame;
00159 struct wtk_slider *slider;
00161 struct wtk_progress_bar *pb;
00163 struct gfx_bitmap background;
00165 struct gfx_bitmap subframe_background;
00167 struct font old_sysfont;
00169 uint8_t color_scheme;
00171 bool color_invert;
00172
00173 };
00174
00176 static struct widget_context *widget_ctx;
00177
00185 static void app_widget_update_colors(struct widget_context *widget)
00186 {
00187 gfx_color_t temp;
00188 gfx_color_t fg;
00189 gfx_color_t bg;
00190
00191 switch (widget->color_scheme) {
00192 case 1:
00193
00194 fg = COLOR_SCHEME_1_FG;
00195 bg = COLOR_SCHEME_1_BG;
00196 break;
00197
00198 default:
00199
00200 fg = COLOR_SCHEME_0_FG;
00201 bg = COLOR_SCHEME_0_BG;
00202 break;
00203 }
00204
00205 if (widget->color_invert) {
00206 temp = bg;
00207 bg = fg;
00208 fg = temp;
00209 }
00210
00211 wtk_progress_bar_set_colors(widget->pb, fg, bg);
00212 win_redraw(wtk_progress_bar_as_child(widget->pb));
00213 }
00214
00227 static bool widget_frame_command_handler(struct wtk_basic_frame *frame,
00228 win_command_t command_data)
00229 {
00230 struct widget_context *widget;
00231 char command;
00232
00233 widget = (struct widget_context *)wtk_basic_frame_get_custom_data(frame);
00234 command = (char)(uintptr_t)command_data;
00235
00236 switch (command) {
00237 case BUTTON_QUIT_ID:
00238
00239 memcpy(&sysfont, &widget_ctx->old_sysfont, sizeof(struct font));
00240
00241 membag_free(widget);
00242
00243 app_desktop_restart();
00244
00245 return true;
00246
00247 case SLIDER_ID:
00248
00249 wtk_progress_bar_set_value(widget->pb,
00250 wtk_slider_get_value(widget->slider));
00251 break;
00252
00253 case CHECK_BOX_ID:
00254
00255 widget->color_invert = !widget->color_invert;
00256 app_widget_update_colors(widget);
00257 break;
00258
00259 case RADIO_BUTTON_1_ID:
00260
00261 widget->color_scheme = 0;
00262 app_widget_update_colors(widget);
00263 break;
00264
00265 case RADIO_BUTTON_2_ID:
00266
00267 widget->color_scheme = 1;
00268 app_widget_update_colors(widget);
00269 break;
00270 }
00271 return false;
00272 }
00273
00283 void app_widget_launch(struct workqueue_task *task) {
00284
00285 struct win_window *win_root;
00286 struct win_window *parent;
00287 struct win_window *subparent;
00288 struct win_area area;
00289 struct wtk_basic_frame *subframe;
00290 struct wtk_label *lbl;
00291 struct wtk_button *btn;
00292 struct wtk_check_box *cb;
00293 struct wtk_radio_group *rg;
00294 struct wtk_radio_button *rb;
00295
00296 widget_ctx = membag_alloc(sizeof(struct widget_context));
00297
00298 if (!widget_ctx) {
00299 goto error_ctx;
00300 }
00301 widget_ctx->color_scheme = 0;
00302 widget_ctx->color_invert = 0;
00303
00304
00305 memcpy(&widget_ctx->old_sysfont, &sysfont, sizeof(struct font));
00306 sysfont.scale = 2;
00307
00308 win_root = win_get_root();
00309
00310
00311 widget_ctx->background.type = BITMAP_SOLID;
00312 widget_ctx->background.data.color = APP_BACKGROUND_COLOR;
00313
00314 area.pos.x = 0;
00315 area.pos.y = 0;
00316 area.size.x = gfx_get_width();
00317 area.size.y = gfx_get_height();
00318
00319 widget_ctx->frame = wtk_basic_frame_create(win_root, &area,
00320 &widget_ctx->background, NULL,
00321 widget_frame_command_handler, widget_ctx);
00322 if (!widget_ctx->frame) {
00323 goto error_frame;
00324 }
00325
00326 parent = wtk_basic_frame_as_child(widget_ctx->frame);
00327 win_show(parent);
00328
00329
00330 area.pos.x = LABEL_POS_X;
00331 area.pos.y = LABEL_POS_Y;
00332
00333 wtk_label_size_hint(&area.size, demo_string);
00334
00335 lbl = wtk_label_create(parent, &area, demo_string, false);
00336 if (!lbl) {
00337 goto error_widget;
00338 }
00339 win_show(wtk_label_as_child(lbl));
00340
00341
00342 widget_ctx->subframe_background.type = BITMAP_SOLID;
00343 widget_ctx->subframe_background.data.color = SUBFRAME_BACKGROUND_COLOR;
00344
00345 area.pos.x = SUBFRAME_HORIZONTAL_SPACING;
00346 area.pos.y += area.size.y + SUBFRAME_TOP_SPACING;
00347 area.size.x = gfx_get_width() - (2 * SUBFRAME_HORIZONTAL_SPACING);
00348 area.size.y = gfx_get_height() - area.pos.y - SUBFRAME_BOTTOM_SPACING;
00349
00350 subframe = wtk_basic_frame_create(parent, &area,
00351 &widget_ctx->subframe_background, NULL, NULL, NULL);
00352 if (!subframe) {
00353 goto error_widget;
00354 }
00355 subparent = wtk_basic_frame_as_child(subframe);
00356 win_show(subparent);
00357
00358
00359 area.pos.x = WIDGET_POS_X;
00360 area.pos.y = SLIDER_POS_Y;
00361 area.size.x = SLIDER_SIZE_X;
00362 area.size.y = SLIDER_SIZE_Y;
00363
00364 widget_ctx->slider = wtk_slider_create(subparent, &area, 100,
00365 50, WTK_SLIDER_HORIZONTAL|WTK_SLIDER_CMD_RELEASE,
00366 (win_command_t)SLIDER_ID);
00367 if (!widget_ctx->slider) {
00368 goto error_widget;
00369 }
00370 win_show(wtk_slider_as_child(widget_ctx->slider));
00371
00372
00373 area.pos.x += area.size.x + SLIDER_PB_SPACING_X;
00374 area.size.x = PB_SIZE_X;
00375 area.size.y = PB_SIZE_Y;
00376
00377 widget_ctx->pb = wtk_progress_bar_create(subparent, &area, 100,
00378 50, GFX_COLOR(0, 0, 0), GFX_COLOR(0, 0, 0),
00379 WTK_PROGRESS_BAR_HORIZONTAL);
00380
00381 if (!widget_ctx->pb) {
00382 goto error_widget;
00383 }
00384 win_show(wtk_progress_bar_as_child(widget_ctx->pb));
00385 app_widget_update_colors(widget_ctx);
00386
00387
00388 area.pos.x = WIDGET_POS_X;
00389 area.pos.y += area.size.y + CHECK_BOX_SPACING_Y;
00390
00391 wtk_check_box_size_hint(&area.size, checkbox_string);
00392
00393 cb = wtk_check_box_create(subparent, &area, checkbox_string,
00394 false, (win_command_t)CHECK_BOX_ID);
00395 if (!cb) {
00396 goto error_widget;
00397 }
00398 win_show(wtk_check_box_as_child(cb));
00399
00400
00401 rg = wtk_radio_group_create();
00402 if (!rg) {
00403 goto error_widget;
00404 }
00405
00406 area.pos.x = WIDGET_POS_X;
00407 area.pos.y += area.size.y + RADIO_BUTTON_SPACING_Y;
00408 wtk_radio_button_size_hint(&area.size, rb1_string);
00409
00410 rb = wtk_radio_button_create(subparent, &area, rb1_string,
00411 true, rg, (win_command_t)RADIO_BUTTON_1_ID);
00412 if (!rb) {
00413 goto error_widget;
00414 }
00415 win_show(wtk_radio_button_as_child(rb));
00416
00417 area.pos.y += area.size.y + RADIO_BUTTON_SPACING_Y;
00418
00419 rb = wtk_radio_button_create(subparent, &area, rb2_string,
00420 false, rg, (win_command_t)RADIO_BUTTON_2_ID);
00421 if (!rb) {
00422 goto error_widget;
00423 }
00424 win_show(wtk_radio_button_as_child(rb));
00425
00426 area.size.x = APP_EXIT_BUTTON_SIZE_X;
00427 area.size.y = APP_EXIT_BUTTON_SIZE_Y;
00428 area.pos.x = APP_EXIT_BUTTON_POS_X;
00429 area.pos.y = APP_EXIT_BUTTON_POS_Y;
00430
00431
00432 btn = wtk_button_create(parent, &area, APP_EXIT_BUTTON_TEXT,
00433 (win_command_t)BUTTON_QUIT_ID);
00434 if (!btn) {
00435 goto error_widget;
00436 }
00437 win_show(wtk_button_as_child(btn));
00438
00439 return;
00440
00441 error_widget:
00442 win_destroy(wtk_basic_frame_as_child(widget_ctx->frame));
00443 error_frame:
00444 memcpy(&sysfont, &widget_ctx->old_sysfont, sizeof(struct font));
00445 membag_free(widget_ctx);
00446 error_ctx:
00447 app_desktop_restart();
00448 }
00449