/** * \brief Configure the root GUI window * * Configures the root window background to be a tiled version of the * Atmel company logo, and sets it as being visible. */ static void setup_gui_root_window(void) { struct win_attributes root_attr; struct win_window *win_root; win_root = win_get_root(); root_attr = *win_get_attributes(win_root); root_attr.background = &atmel_logo_small; win_set_attributes(win_root, &root_attr, WIN_ATTR_BACKGROUND); win_show(win_root); }
/** * \brief Set up and show the root window */ static void setup_root_window(void) { struct win_window *win_root; struct win_attributes attr; win_root = win_get_root(); attr = *win_get_attributes(win_root); attr.background = NULL; win_set_attributes(win_root, &attr, WIN_ATTR_BACKGROUND); win_show(win_root); }
/* Put all the windows */ void init_wins(WINDOW **wins, int n) { int x, y, i; char label[80]; y = 2; x = 10; for(i = 0; i < n; ++i) { wins[i] = newwin(NLINES, NCOLS, y, x); sprintf(label, "Window Number %d", i + 1); win_show(wins[i], label, i + 1); y += 3; x += 7; } }
static gboolean time_handler(GtkWidget *widget) { static int msg_life = 0; pthread_mutex_lock(&mutex); if (new_msg) { new_msg = FALSE; msg_life = MSG_LIFE / time_interval; pthread_mutex_unlock(&mutex); show_message(msg_from, msg_content); } else { pthread_mutex_unlock(&mutex); if (--msg_life == 0) win_show("", ""); } return TRUE; }
void win_init() { //创建窗口 window = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_set_decorated (GTK_WINDOW(window), FALSE); // 设置无边框 gtk_window_set_keep_above (GTK_WINDOW(window), TRUE); gtk_widget_set_app_paintable (window, TRUE); gtk_widget_realize (window); GdkScreen *screen = gtk_widget_get_screen(window); screen_width = gdk_screen_get_width(screen); screen_height = gdk_screen_get_height(screen); window_width = screen_width; window_height = font_size * 1.5; debug("screen_size=(%d, %d), window_size=(%d,%d)\n", screen_width, screen_height, window_width, window_height); //创建位图与蒙板 pixmap = gdk_pixmap_new (window->window, window_width, window_height, -1); pixmap_mask = gdk_pixmap_new (window->window, window_width, window_height, 1); //初始化绘图环境 sf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, window_width, window_height); cr = cairo_create (sf); pthread_mutex_init (&mutex,NULL); g_timeout_add(time_interval, (GSourceFunc) time_handler, (gpointer) window); //显示窗口 win_show("", "OSDChat"); gtk_widget_show_all (window); gdk_window_move_resize(window->window, 0, screen_height - window_height, window_width, window_height); //启动线程 pthread_create(&thread, NULL, main_thread, NULL); }
int main() { WINDOW *my_wins[3]; PANEL *my_panels[3]; PANEL_DATA *top; PANEL *stack_top; WINDOW *temp_win, *old_win; int ch; int newx, newy, neww, newh; int size = FALSE, move = FALSE; /* Initialize curses */ initscr(); start_color(); cbreak(); noecho(); keypad(stdscr, TRUE); /* Initialize all the colors */ init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_GREEN, COLOR_BLACK); init_pair(3, COLOR_BLUE, COLOR_BLACK); init_pair(4, COLOR_CYAN, COLOR_BLACK); init_wins(my_wins, 3); /* Attach a panel to each window */ /* Order is bottom up */ my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */ my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */ my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */ set_user_ptrs(my_panels, 3); /* Update the stacking order. 2nd panel will be on top */ update_panels(); /* Show it on the screen */ attron(COLOR_PAIR(4)); mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing"); mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)"); attroff(COLOR_PAIR(4)); doupdate(); stack_top = my_panels[2]; top = (PANEL_DATA *)panel_userptr(stack_top); newx = top->x; newy = top->y; neww = top->w; newh = top->h; while((ch = getch()) != KEY_F(1)) { switch(ch) { case 9: /* Tab */ top = (PANEL_DATA *)panel_userptr(stack_top); top_panel(top->next); stack_top = top->next; top = (PANEL_DATA *)panel_userptr(stack_top); newx = top->x; newy = top->y; neww = top->w; newh = top->h; break; case 'r': /* Re-Size*/ size = TRUE; attron(COLOR_PAIR(4)); mvprintw(LINES - 4, 0, "Entered Resizing :Use Arrow Keys to resize and press <ENTER> to end resizing"); refresh(); attroff(COLOR_PAIR(4)); break; case 'm': /* Move */ attron(COLOR_PAIR(4)); mvprintw(LINES - 4, 0, "Entered Moving: Use Arrow Keys to Move and press <ENTER> to end moving"); refresh(); attroff(COLOR_PAIR(4)); move = TRUE; break; case KEY_LEFT: if(size == TRUE) { --newx; ++neww; } if(move == TRUE) --newx; break; case KEY_RIGHT: if(size == TRUE) { ++newx; --neww; } if(move == TRUE) ++newx; break; case KEY_UP: if(size == TRUE) { --newy; ++newh; } if(move == TRUE) --newy; break; case KEY_DOWN: if(size == TRUE) { ++newy; --newh; } if(move == TRUE) ++newy; break; case 10: /* Enter */ move(LINES - 4, 0); clrtoeol(); refresh(); if(size == TRUE) { old_win = panel_window(stack_top); temp_win = newwin(newh, neww, newy, newx); replace_panel(stack_top, temp_win); win_show(temp_win, top->label, top->label_color); delwin(old_win); size = FALSE; } if(move == TRUE) { move_panel(stack_top, newy, newx); move = FALSE; } break; } attron(COLOR_PAIR(4)); mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing"); mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)"); attroff(COLOR_PAIR(4)); refresh(); update_panels(); doupdate(); } endwin(); return 0; }
/** * \brief Launch the water tank application. * * This function allocates memory, creates the application frame and widgets, * initializes the timer and initiates loading of the required bitmaps. * * One basic frame is created, along with four widgets: one slider, two progress * bars and a command button. These are not shown until the background image has * been loaded. * * If the alarm light bitmaps have already been loaded, i.e., the application * has already been run, the application will skip directly to loading of the * background image. * * If memory for the application context cannot be allocated or the frame or * widgets cannot be created, the application will exit immediately. * * \param task Workqueue task to use for the application's worker functions. */ void app_tank_launch(struct workqueue_task *task) { struct win_attributes attr; struct win_window *win; struct gfx_bitmap bitmap; struct wtk_basic_frame *frame; struct wtk_slider *slider; struct wtk_button *button; struct wtk_progress_bar *pbar; struct timer *timer; timer_res_t timer_res; uint32_t timer_clk; assert(task); // Clear the screen right away. #ifdef CONFIG_GFX_USE_CLIPPING gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height()); #endif /* CONFIG_GFX_USE_CLIPPING */ gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(), COLOR_WIN_BACKGROUND); // Allocate the application context first. tank_ctx = membag_alloc(sizeof(struct tank_context)); if (!tank_ctx) goto exit_no_context; // Use larger sysfont for this app. memcpy(&tank_ctx->old_sysfont, &sysfont, sizeof(struct font)); sysfont.scale = 2; // Create a basic frame to contain the widgets. attr.area.pos.x = 0; attr.area.pos.y = 0; attr.area.size.x = gfx_get_width(); attr.area.size.y = gfx_get_height(); frame = wtk_basic_frame_create(win_get_root(), &attr.area, NULL, NULL, tank_frame_handler, NULL); if (!frame) { goto exit_no_frame; } tank_ctx->frame = frame; // Get the frame's window to use as parent for widgets. win = wtk_basic_frame_as_child(frame); // Initialize the application timer. timer = &tank_ctx->timer; timer_init(CONFIG_TIMER_ID, timer, tank_timer_callback); timer_res = timer_set_resolution(CONFIG_TIMER_ID, timer, TICK_RATE); timer_write_resolution(CONFIG_TIMER_ID, timer, timer_res); // Get the timer alarm delay to use for the configured tick rate. timer_clk = timer_get_resolution(CONFIG_TIMER_ID, timer, timer_res); tank_ctx->timer_delay = timer_clk / TICK_RATE; // Initialize random variable and tick count. tank_ctx->rand = 1; tank_ctx->rand_ticks = TICKS_PER_RANDOM_UPDATE; // Create the supply slider. attr.area.pos.x = WIDGET_SUPPLY_POSITION_X; attr.area.pos.y = WIDGET_SUPPLY_POSITION_Y; attr.area.size.x = WIDGET_SUPPLY_SIZE_X; attr.area.size.y = WIDGET_SUPPLY_SIZE_Y; slider = wtk_slider_create(win, &attr.area, VALUE_SUPPLY_MAXIMUM, VALUE_SUPPLY_INITIAL, WTK_SLIDER_VERTICAL | WTK_SLIDER_INVERT, CMD_NONE); if (!slider) { goto exit_no_widget; } tank_ctx->supply = slider; win_show(wtk_slider_as_child(slider)); // Create the tank level progress bar. attr.area.pos.x = WIDGET_LEVEL_POSITION_X; attr.area.pos.y = WIDGET_LEVEL_POSITION_Y; attr.area.size.x = WIDGET_LEVEL_SIZE_X; attr.area.size.y = WIDGET_LEVEL_SIZE_Y; pbar = wtk_progress_bar_create(win, &attr.area, VALUE_LEVEL_MAXIMUM, VALUE_LEVEL_INITIAL, COLOR_LEVEL_FILL, COLOR_LEVEL_BACKGROUND, WTK_PROGRESS_BAR_VERTICAL | WTK_PROGRESS_BAR_INVERT); if (!pbar) { goto exit_no_widget; } tank_ctx->level = pbar; win_show(wtk_progress_bar_as_child(pbar)); // Create the demand progress bar. attr.area.pos.x = WIDGET_DEMAND_POSITION_X; attr.area.pos.y = WIDGET_DEMAND_POSITION_Y; attr.area.size.x = WIDGET_DEMAND_SIZE_X; attr.area.size.y = WIDGET_DEMAND_SIZE_Y; pbar = wtk_progress_bar_create(win, &attr.area, VALUE_DEMAND_MAXIMUM, VALUE_DEMAND_INITIAL, COLOR_DEMAND_NORMAL, COLOR_DEMAND_BACKGROUND, WTK_PROGRESS_BAR_VERTICAL | WTK_PROGRESS_BAR_INVERT); if (!pbar) { goto exit_no_widget; } tank_ctx->demand = pbar; win_show(wtk_progress_bar_as_child(pbar)); // Create the exit button with the standard settings. attr.area.pos.x = APP_EXIT_BUTTON_POS_X; attr.area.pos.y = APP_EXIT_BUTTON_POS_Y; attr.area.size.x = APP_EXIT_BUTTON_SIZE_X; attr.area.size.y = APP_EXIT_BUTTON_SIZE_Y; button = wtk_button_create(win, &attr.area, APP_EXIT_BUTTON_TEXT, (win_command_t)CMD_EXIT); if (!button) { goto exit_no_widget; } win_show(wtk_button_as_child(button)); // Set the tank alarm to trigger initial drawing of alarm light. tank_ctx->level_alarm = true; tank_ctx->flow_alarm = false; tank_ctx->task = task; /* Initialize bitmap data and set initial application loader state: * If the alarm light bitmaps have already been loaded, skip right to * loading of the application background bitmap. */ bitmap.width = BITMAP_LIGHT_SIZE_X; bitmap.height = BITMAP_LIGHT_SIZE_Y; bitmap.type = BITMAP_HUGEMEM; tank_ctx->bitmaps[BITMAP_RED_LIGHT] = bitmap; tank_ctx->bitmaps[BITMAP_GREEN_LIGHT] = bitmap; if (tank_bitmap_data[BITMAP_GREEN_LIGHT]) { tank_ctx->loader_state = LOAD_BACKGROUND; tank_ctx->bitmaps[BITMAP_RED_LIGHT].data.hugemem = tank_bitmap_data[BITMAP_RED_LIGHT]; tank_ctx->bitmaps[BITMAP_GREEN_LIGHT].data.hugemem = tank_bitmap_data[BITMAP_GREEN_LIGHT]; } else { tank_ctx->loader_state = LOAD_RED_LIGHT; } workqueue_task_set_work_func(task, tank_loader); workqueue_add_task(&main_workqueue, task); return; // Handle allocation errors. exit_no_widget: win_destroy(wtk_basic_frame_as_child(tank_ctx->frame)); exit_no_frame: memcpy(&sysfont, &tank_ctx->old_sysfont, sizeof(struct font)); membag_free(tank_ctx); exit_no_context: app_desktop_restart(); return; }
/** * \brief Application loader. * * This worker function loads the alarm light bitmaps, then loads the background * image before showing all the widgets and starting the process simulation. * * If memory for bitmaps cannot be allocated, or the background image cannot be * loaded, the application will exit immediately. * * \param task Workqueue task for this worker function. */ static void tank_loader(struct workqueue_task *task) { enum status_code result; hugemem_ptr_t bitmap_data; /* Handle the individual bitmap load states. * * All states, except LOAD_FINISHED, will cause the current workqueue * task to be re-enqueued after loading of the corresponding bitmap has * completed. This task worker will thus go through the states in * sequence. */ switch (tank_ctx->loader_state) { case LOAD_RED_LIGHT: // Enqueue loading of the red alarm light bitmap. bitmap_data = load_file_to_hugemem(BITMAP_RED_LIGHT_FILENAME, task); /* If memory could be allocated for the bitmap, update the * pointer in the bitmap metadata and set next load state. * Otherwise, exit the application load error. */ if (bitmap_data != HUGEMEM_NULL) { tank_bitmap_data[BITMAP_RED_LIGHT] = bitmap_data; tank_ctx->bitmaps[BITMAP_RED_LIGHT].data.hugemem = bitmap_data; tank_ctx->loader_state = LOAD_GREEN_LIGHT; } else { goto exit_load_error; } break; case LOAD_GREEN_LIGHT: bitmap_data = load_file_to_hugemem(BITMAP_GREEN_LIGHT_FILENAME, task); if (bitmap_data != HUGEMEM_NULL) { tank_bitmap_data[BITMAP_GREEN_LIGHT] = bitmap_data; tank_ctx->bitmaps[BITMAP_GREEN_LIGHT].data.hugemem = bitmap_data; tank_ctx->loader_state = LOAD_BACKGROUND; } else { goto exit_load_error; } break; case LOAD_BACKGROUND: // Now load the background image. result = load_file_to_screen(BITMAP_BACKGROUND_FILENAME, BITMAP_BACKGROUND_POSITION_X, BITMAP_BACKGROUND_POSITION_Y, BITMAP_BACKGROUND_SIZE_X, BITMAP_BACKGROUND_SIZE_Y, task); if (result == STATUS_OK) { tank_ctx->loader_state = LOAD_FINISHED; } else { goto exit_load_error; } break; case LOAD_FINISHED: // Now show the application's frame. This will draw all widgets. win_show(wtk_basic_frame_as_child(tank_ctx->frame)); // Set the worker function that updates the application. workqueue_task_set_work_func(task, tank_worker); // Set the timer alarm to trigger application updates. timer_start(CONFIG_TIMER_ID, &tank_ctx->timer); timer_set_alarm(CONFIG_TIMER_ID, &tank_ctx->timer, tank_ctx->timer_delay); break; default: // Should not end up here. unhandled_case(tank_ctx->loader_state); break; } return; // If a load error occurred, go back to the desktop. exit_load_error: win_destroy(wtk_basic_frame_as_child(tank_ctx->frame)); memcpy(&sysfont, &tank_ctx->old_sysfont, sizeof(struct font)); membag_free(tank_ctx); tank_ctx = NULL; app_desktop_restart(); }
/** * \brief Setup widget demo * * Allocates memory for the application context, and creates all widgets that * make up its interface. If memory allocation or widget creation fails, the * application exits immediately. * * \return Boolean true if the application was launched successfully, false if * a memory allocation occurred. */ bool app_widget_launch(void) { struct win_window *parent; struct win_area area; struct wtk_button *button; /* Create a new context for the GUI */ widget_ctx = membag_alloc(sizeof(struct widget_context)); if (!widget_ctx) { return false; } /* Initialize context data. */ widget_ctx->frame_bg.type = GFX_BITMAP_SOLID; widget_ctx->frame_bg.data.color = GFX_COLOR(220, 220, 220); /* Set the area for the GUI window */ area = win_get_attributes(win_get_root())->area; win_inflate_area(&area, -20); /* Create and show the main GUI frame */ widget_ctx->frame = wtk_basic_frame_create( win_get_root(), &area, &widget_ctx->frame_bg, NULL, widget_frame_command_handler, widget_ctx); if (!widget_ctx->frame) { goto error_frame; } parent = wtk_basic_frame_as_child(widget_ctx->frame); win_show(parent); /* Set the background information for the plot widget */ widget_ctx->plot_bg.type = GFX_BITMAP_SOLID; widget_ctx->plot_bg.data.color = GFX_COLOR_WHITE; /* Adjust area for the plot widget */ area.size.y -= 80; area.size.x -= 40; /* Create and show the plot widget with vertical axis marks */ widget_ctx->plot = wtk_plot_create(parent, &area, 100, 10, GFX_COLOR_RED, &widget_ctx->plot_bg, WTK_PLOT_LEFT_TO_RIGHT); if (!widget_ctx->plot) { goto error_widget; } wtk_plot_set_grid(widget_ctx->plot, WTK_PLOT_TICKS_VERTICAL, 10, 0, 10, 0, GFX_COLOR_BLUE, GFX_COLOR_GREEN); win_show(wtk_plot_as_child(widget_ctx->plot)); /* Adjust area for the slider widget */ area.pos.y += area.size.y + 10; area.size.y = 40; area.size.x -= 60; /* Create and show the slider widget */ widget_ctx->slider = wtk_slider_create(parent, &area, 100, 0, WTK_SLIDER_HORIZONTAL, (win_command_t)SLIDER_ID); if (!widget_ctx->slider) { goto error_widget; } win_show(wtk_slider_as_child(widget_ctx->slider)); /* Adjust area for the button widget */ area.pos.x += area.size.x + 10; area.size.x = 50; /* Create and show the button widget */ button = wtk_button_create(parent, &area, "Add", (win_command_t)BUTTON_ID); if (!button) { goto error_widget; } win_show(wtk_button_as_child(button)); return true; /* Error handling to clean up allocations after an error */ error_widget: win_destroy(wtk_basic_frame_as_child(widget_ctx->frame)); error_frame: membag_free(widget_ctx); return false; }
/** * This function creates a new frame widget. It allocates required memory and * intializes necessary windows to create the widget. If there is not enough * memory, the function returns NULL. * * To destroy the widget and all its contents, and free its memory, call * win_destroy() on the frame's child reference, given by wtk_frame_as_child(), * like this: "win_destroy(wtk_frame_as_child(my_frame_ptr));". * The frame's internal area will equal the area parameter, but the total * extents will be slightly larger, to accommodate for titlebar, borders etc. * * \param parent Parent window. * \param area Area of the internal contents. * \param caption Pointer to caption string. Will be copied into widget. * \param allow_resize True if resize handle should be included on the frame. * \param frame_handler Optional command event handler, for applications. * \param custom_data Optional custom data link, for applications. * * \return Pointer to frame, or NULL if failed. */ struct wtk_frame *wtk_frame_create(struct win_window *parent, struct win_area const *area, char const *caption, bool allow_resize, wtk_frame_handler_t frame_handler, void *custom_data) { struct win_attributes attr; struct wtk_frame *frame; Assert(area); Assert(caption); Assert(parent); /* Allocate memory for frame control data. */ frame = membag_alloc(sizeof(struct wtk_frame)); if (!frame) { goto outofmem_frame; } frame->state = WTK_FRAME_NORMAL; frame->frame_handler = frame_handler; frame->custom_data = custom_data; /* Allocate memory for caption string, and copy text. */ frame->caption = membag_alloc((strlen(caption) + 1) * sizeof(char)); if (!frame->caption) { goto outofmem_caption; } wtk_copy_string(frame->caption, caption); /* Start with valid area info, but only contents frame will keep the * original area. The other frames will be resized properly at the end. * All windows have the same event handler, and the same link back to * the widget object. */ attr.area = *area; attr.event_handler = wtk_frame_handler; attr.custom = frame; /* Prepare container frame, which will contain title bar, border, size, * handle etc. */ attr.background = NULL; attr.behavior = WIN_BEHAVIOR_RAISE_ON_PRESS; /* Create the container window, the proper size will be set later. */ frame->container = win_create(parent, &attr); if (!frame->container) { goto outofmem_container; } /* Prepare the contents frame, which will contain whatever controls * owned by the frame. Size will be equal to the given area parameter. */ attr.area.pos.x = WTK_FRAME_LEFTBORDER; attr.area.pos.y = WTK_FRAME_TOPBORDER + WTK_FRAME_TITLEBAR_HEIGHT; attr.background = &wtk_frame_background; attr.behavior = 0; frame->contents = win_create(frame->container, &attr); if (!frame->contents) { goto outofmem_contents; } /* Only create resize handle window if resize is allowed. */ if (allow_resize) { /* Prepare resize handle. Proper position will be set later. * Size is set here, though. */ attr.area.size.x = WTK_FRAME_RESIZE_WIDTH; attr.area.size.y = WTK_FRAME_RESIZE_HEIGHT; attr.background = NULL; attr.behavior = 0; frame->resize = win_create(frame->container, &attr); if (!frame->resize) { goto outofmem_resize; } win_show(frame->resize); } else { frame->resize = NULL; } /* Now, resize and rearrange according to size of contents frame, which * is equal to the given area parameter. */ wtk_resize_frame(frame, area); /* Make sure internals are visible when frame is mapped. */ win_show(frame->contents); return frame; outofmem_resize: win_destroy(frame->contents); outofmem_contents: win_destroy(frame->container); outofmem_container: membag_free(frame->caption); outofmem_caption: membag_free(frame); outofmem_frame: return NULL; }
/** * \brief Setup widget demo * * Allocates memory for the application context, and creates all widgets that * make up its interface. If memory allocation or widget creation fails, the * application exits immediately. * * \return Boolean true if the application was launched successfully, false if * a memory allocation occurred. */ bool app_widget_launch(void) { struct win_window *parent; struct win_area area; struct wtk_check_box *cb; struct wtk_radio_group *rg; struct wtk_radio_button *rb; struct wtk_button *btn; /* Create a new context for the GUI */ widget_ctx = membag_alloc(sizeof(struct widget_context)); if (!widget_ctx) { return false; } /* Initialize context data. */ widget_ctx->color_scheme = 0; widget_ctx->color_invert = 0; /* Set the background information for the GUI window */ widget_ctx->frame_bg.type = GFX_BITMAP_SOLID; widget_ctx->frame_bg.data.color = APP_BACKGROUND_COLOR; /* Set the area for the GUI window */ area = win_get_attributes(win_get_root())->area; win_inflate_area(&area, -20); /* Create and show the main GUI frame */ widget_ctx->frame = wtk_basic_frame_create( win_get_root(), &area, &widget_ctx->frame_bg, NULL, widget_frame_command_handler, widget_ctx); if (!widget_ctx->frame) { goto error_frame; } parent = wtk_basic_frame_as_child(widget_ctx->frame); win_show(parent); /* Update area for the slider widget */ area.pos.x = WIDGET_POS_X; area.pos.y = WIDGET_POS_Y + SLIDER_POS_Y; area.size.x = SLIDER_SIZE_X; area.size.y = SLIDER_SIZE_Y; /* Create slider inside frame */ widget_ctx->slider = wtk_slider_create(parent, &area, 100, 50, WTK_SLIDER_HORIZONTAL | WTK_SLIDER_CMD_MOVE | WTK_SLIDER_CMD_RELEASE, (win_command_t)SLIDER_ID); if (!widget_ctx->slider) { goto error_widget; } win_show(wtk_slider_as_child(widget_ctx->slider)); /* Update area for the progress bar widget */ area.pos.x += area.size.x + SLIDER_PB_SPACING_X; area.size.x = PB_SIZE_X; area.size.y = PB_SIZE_Y; /* Create progress bar to the right of the slider */ widget_ctx->pb = wtk_progress_bar_create(parent, &area, 100, 50, GFX_COLOR_BLACK, GFX_COLOR_BLACK, WTK_PROGRESS_BAR_HORIZONTAL); if (!widget_ctx->pb) { goto error_widget; } win_show(wtk_progress_bar_as_child(widget_ctx->pb)); app_widget_update_colors(widget_ctx); /* Update area for the checkbox widget */ area.pos.x = WIDGET_POS_X; area.pos.y += area.size.y + CHECK_BOX_SPACING_Y; wtk_check_box_size_hint(&area.size, checkbox_string); /* Create check box below slider and progress bar */ cb = wtk_check_box_create(parent, &area, checkbox_string, false, (win_command_t)CHECK_BOX_ID); if (!cb) { goto error_widget; } win_show(wtk_check_box_as_child(cb)); /* Create a logical group for the radio buttons */ rg = wtk_radio_group_create(); if (!rg) { goto error_widget; } /* Update area for the first radio button widget */ area.pos.y += area.size.y + RADIO_BUTTON_SPACING_Y; wtk_radio_button_size_hint(&area.size, rb1_string); /* Create first radio button widget */ rb = wtk_radio_button_create(parent, &area, rb1_string, true, rg, (win_command_t)RADIO_BUTTON_1_ID); if (!rb) { goto error_widget; } win_show(wtk_radio_button_as_child(rb)); /* Update area for the second radio button widget */ area.pos.y += area.size.y + RADIO_BUTTON_SPACING_Y; wtk_radio_button_size_hint(&area.size, rb2_string); /* Create second radio button widget */ rb = wtk_radio_button_create(parent, &area, rb2_string, false, rg, (win_command_t)RADIO_BUTTON_2_ID); if (!rb) { goto error_widget; } win_show(wtk_radio_button_as_child(rb)); /* Update area for the button widget */ area.pos.y += area.size.y + BUTTON_SPACING_Y; area.size.x = SLIDER_SIZE_X + SLIDER_PB_SPACING_X + PB_SIZE_X; area.size.y = BUTTON_SIZE_Y; /* Create button widget */ btn = wtk_button_create(parent, &area, btn_string, (win_command_t)BUTTON_ID); wtk_button_size_hint(&area.size, btn_string); if (!btn) { goto error_widget; } win_show(wtk_button_as_child(btn)); return true; /* Error handling to clean up allocations after an error */ error_widget: win_destroy(wtk_basic_frame_as_child(widget_ctx->frame)); error_frame: membag_free(widget_ctx); return false; }
/** * \brief Setup widget demo * * This function launches the widget demo. */ void app_widget_launch() { struct win_window *win_root; struct win_window *parent; struct win_area area; struct wtk_label *lbl; struct wtk_button *btn; /* Get pointer to root window */ win_root = win_get_root(); /* Application frame */ /* Create a background bitmap using a solid color. */ frame_background.type = GFX_BITMAP_SOLID; frame_background.data.color = APP_BACKGROUND_COLOR; /* Set the area to fill the entire screen */ area.pos.x = 0; area.pos.y = 0; area.size.x = gfx_get_width(); area.size.y = gfx_get_height(); /* * Create a basic frame with a specified background and command event * handler. Check the return value if an error occurred while creating * the widget. */ main_frame = wtk_basic_frame_create(win_root, &area, &frame_background, NULL, widget_frame_command_handler, NULL); if (!main_frame) { goto error_frame; } /* Get a pointer to the widget's window for adding sub-widgets. */ parent = wtk_basic_frame_as_child(main_frame); /* * Draw the frame by showing the frame widget's window. Any * child-widgets and windows will not be shown before the parent * widget/window is shown. */ win_show(parent); /* Application label */ area.pos.x = LABEL_POS_X; area.pos.y = LABEL_POS_Y; /* Find an optimal size for the widget. */ wtk_label_size_hint(&area.size, demo_string); /* * Create the label and check the return value if an error occurred * while creating the label. */ lbl = wtk_label_create(parent, &area, demo_string, GFX_COLOR(255, 255, 255), NULL, false); if (!lbl) { goto error_widget; } /* Draw the label by showing the label widget's window. */ win_show(wtk_label_as_child(lbl)); /* Application slider */ area.pos.x = SLIDER_POS_X; area.pos.y = SLIDER_POS_Y; area.size.x = SLIDER_SIZE_X; area.size.y = SLIDER_SIZE_Y; /* * Create the slider and check the return value if an error occurred * while creating the slider. */ slider = wtk_slider_create(parent, &area, SLIDER_MAX_VALUE, SLIDER_MAX_VALUE / 2, WTK_SLIDER_HORIZONTAL | WTK_SLIDER_CMD_RELEASE, (win_command_t)SLIDER_ID); if (!slider) { goto error_widget; } /* Draw the slider by showing the slider widget's window. */ win_show(wtk_slider_as_child(slider)); /* Application progress bar, placed right of the slider. */ area.pos.x += area.size.x + SLIDER_PB_SPACING_X; area.size.x = PB_SIZE_X; area.size.y = PB_SIZE_Y; /* * Create the progress bar and check the return value if an error * occurred while creating the progress bar. */ progress_bar = wtk_progress_bar_create(parent, &area, SLIDER_MAX_VALUE, SLIDER_MAX_VALUE / 2, GFX_COLOR(255, 255, 0), GFX_COLOR(90, 90, 90), WTK_PROGRESS_BAR_HORIZONTAL); if (!progress_bar) { goto error_widget; } /* Draw the progress bar by showing the progress bar widget's window. */ win_show(wtk_progress_bar_as_child(progress_bar)); /** \todo Add code to set up button here. */ /** \todo Add code to set up basic frame here. */ return; error_widget: /* Destroy widget and all sub-widgets. */ win_destroy(wtk_basic_frame_as_child(main_frame)); error_frame: /* Wait forever if an error occurred during setup. */ while (1) { } }