/** * \brief Frame command events handler * * This function handles the command events generated by the widgets. * * \sa wtk_basic_frame_command_handler_t */ static bool widget_frame_command_handler(struct wtk_basic_frame *frame, win_command_t command_data) { char command = (uintptr_t)command_data; switch (command) { case SLIDER_ID: wtk_progress_bar_set_value(progress_bar, wtk_slider_get_value(slider)); break; case BUTTON_ID: /** \todo Add code here to handle button press. */ break; } return false; }
/** * \brief Frame handler for the application * * Handles all command events from the widgets in the application frame. * * \sa wtk_basic_frame_command_handler_t * * \param frame Pointer to the application frame * \param command_data Command event ID * * \return True if exiting, to destroy the window */ static bool widget_frame_command_handler(struct wtk_basic_frame *frame, win_command_t command_data) { struct widget_context *widget; char command; widget = (struct widget_context *)wtk_basic_frame_get_custom_data(frame); command = (uintptr_t)command_data; switch (command) { case SLIDER_ID: /* Update the progress bar when slider value changes. */ wtk_progress_bar_set_value(widget->pb, wtk_slider_get_value(widget->slider)); break; case CHECK_BOX_ID: /* Invert the colors for the progress bar. */ widget->color_invert = !widget->color_invert; app_widget_update_colors(widget); break; case RADIO_BUTTON_1_ID: /* Set first color scheme for the progress bar. */ widget->color_scheme = 0; app_widget_update_colors(widget); break; case RADIO_BUTTON_2_ID: /* Set second color scheme for the progress bar. */ widget->color_scheme = 1; app_widget_update_colors(widget); break; case BUTTON_ID: /* Reset the slider and progress bar values and update */ wtk_slider_set_value(widget->slider, 0); wtk_progress_bar_set_value(widget->pb, 0); } return false; }
/** * \brief Frame handler for the application * * Handles all command events from the widgets in the application frame. * * \sa wtk_basic_frame_command_handler_t * * \param frame Pointer to the application frame * \param command_data Command event ID * * \return True if exiting, to destroy the window */ static bool widget_frame_command_handler(struct wtk_basic_frame *frame, win_command_t command_data) { struct widget_context *widget; char command; widget = (struct widget_context *)wtk_basic_frame_get_custom_data(frame); command = (uintptr_t)command_data; switch (command) { case BUTTON_ID: /* Update the plot with the new value as set by the slider */ wtk_plot_add_value(widget->plot, wtk_slider_get_value(widget->slider)); /* Redraw the plot with the new value */ win_redraw(wtk_plot_as_child(widget->plot)); break; } return false; }
/** * \brief Application worker function. * * This task worker updates the parameters of the simulated process and the * display unless the application context has been cleared, in which case the * function returns immediately. * * Refer to the detailed description of \ref apps_tank_group for information on * the simulated process. * * If the tank level reaches 0, the indicator for demand will change color to * indicate that the supply is insufficient. If, on the other hand, it reaches * \ref VALUE_LEVEL_MAXIMUM, the alarm light changes color to indicate that the * supply is too great. * * \note The task for this worker function is enqueued by the timer callback * function. * * \param task Workqueue task for this worker function. */ static void tank_worker(struct workqueue_task *task) { struct gfx_bitmap *alarm_bitmap = NULL; bool alarm_update = false; int32_t rand; uint8_t supply; uint16_t demand; int16_t flow; int16_t level; // Quit immediately if application context has been cleared. if (!tank_ctx) { return; } // Get current values of the process parameters. level = wtk_progress_bar_get_value(tank_ctx->level); supply = wtk_slider_get_value(tank_ctx->supply); demand = wtk_progress_bar_get_value(tank_ctx->demand); rand = tank_ctx->rand; // Update the random variable if enough ticks have passed. if (--(tank_ctx->rand_ticks) == 0) { tank_ctx->rand_ticks = TICKS_PER_RANDOM_UPDATE; // Flip some LSBs to help avoid a stuck process. rand ^= demand & 0x03; // Compute new random value and store it for next iteration. rand = tank_logistic_map(rand); tank_ctx->rand = rand; } // Now, compute the new demand from a weighted scheme. demand = rand + (2 * demand) + level; demand /= 4; demand = min_u(demand, VALUE_DEMAND_MAXIMUM); /* Compute the total flow and scale it down for a smoother * simulation. */ flow = supply; flow -= demand; flow /= 4; // Compute new level for the tank. level += flow; /* Update the demand indicator. Change its color if the demand * exceeds the supply and available water in the tank. */ if (level <= 0) { if (!tank_ctx->flow_alarm) { tank_ctx->flow_alarm = true; wtk_progress_bar_set_colors(tank_ctx->demand, COLOR_DEMAND_CRITICAL, COLOR_DEMAND_BACKGROUND); } level = 0; } else { if (tank_ctx->flow_alarm) { tank_ctx->flow_alarm = false; wtk_progress_bar_set_colors(tank_ctx->demand, COLOR_DEMAND_NORMAL, COLOR_DEMAND_BACKGROUND); } } wtk_progress_bar_set_value(tank_ctx->demand, demand); /* Update the tank level indicator. * The level of the tank cannot exceed the defined maximum, * and its alarm light must be updated whenever this level * is crossed. */ if (level >= VALUE_LEVEL_MAXIMUM) { if (!tank_ctx->level_alarm) { tank_ctx->level_alarm = true; alarm_update = true; alarm_bitmap = &tank_ctx->bitmaps[BITMAP_RED_LIGHT]; } level = VALUE_LEVEL_MAXIMUM; } else { if (tank_ctx->level_alarm) { tank_ctx->level_alarm = false; alarm_update = true; alarm_bitmap = &tank_ctx->bitmaps[BITMAP_GREEN_LIGHT]; } } wtk_progress_bar_set_value(tank_ctx->level, level); /* If a level alarm update occurred, set up clipping area and draw * the new alarm light bitmap. */ if (alarm_update) { #ifdef CONFIG_GFX_USE_CLIPPING gfx_set_clipping(BITMAP_LIGHT_POSITION_X, BITMAP_LIGHT_POSITION_Y, BITMAP_LIGHT_POSITION_X + BITMAP_LIGHT_SIZE_X - 1, BITMAP_LIGHT_POSITION_Y + BITMAP_LIGHT_SIZE_Y - 1 ); #endif /* CONFIG_GFX_USE_CLIPPING */ gfx_draw_bitmap(alarm_bitmap, BITMAP_LIGHT_POSITION_X, BITMAP_LIGHT_POSITION_Y); } }