diff options
| author | [email protected] <[email protected]> | 2012-11-26 02:42:52 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-11-26 02:42:52 +0000 |
| commit | 62447b2cd84b529f7dbf6712c29d7ac4ff0c1e12 (patch) | |
| tree | 399aa1bbc0d4c632d7dc2804ed76e5c62b5cec27 /components/rtgui/widgets/plot.c | |
| parent | 9789907ca1b4c43ee34fac6e94e5a48f76aaca3c (diff) | |
sync RTGUI with github(https://github.com/RT-Thread/RTGUI) 9ae08379da5b698d6facc40bd0415de2e254ae9c
As always, full log is in GitHub.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2449 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/rtgui/widgets/plot.c')
| -rw-r--r-- | components/rtgui/widgets/plot.c | 231 |
1 files changed, 167 insertions, 64 deletions
diff --git a/components/rtgui/widgets/plot.c b/components/rtgui/widgets/plot.c index 6881295d87..9c3018a5c3 100644 --- a/components/rtgui/widgets/plot.c +++ b/components/rtgui/widgets/plot.c @@ -1,5 +1,5 @@ /* - * File : plot.h + * File : plot.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2012, RT-Thread Development Team * @@ -15,42 +15,32 @@ #include <rtgui/rtgui_system.h> #include <rtgui/dc.h> #include <rtgui/widgets/plot.h> +#include <rtgui/widgets/plot_curve.h> static void _rtgui_plot_constructor(struct rtgui_plot *plot) { - plot->base_point.x = plot->base_point.y = 0; - plot->curve_container.curve = RT_NULL; - plot->curve_container.next = RT_NULL; + plot->base_x = plot->base_y = 0; + plot->ptype = RTGUI_PLOT_TYPE_SCAN; + plot->scale_x = plot->scale_y = 1; - /* init widget and set event handler */ rtgui_object_set_event_handler(RTGUI_OBJECT(plot), rtgui_plot_event_handler); } -static void _free_curve_container_recursive(struct rtgui_plot_curve_container *cnt) -{ - if (!cnt) - return; - _free_curve_container_recursive(cnt->next); - rtgui_free(cnt); -} - static void _rtgui_plot_destructor(struct rtgui_plot *plot) { - _free_curve_container_recursive(plot->curve_container.next); } DEFINE_CLASS_TYPE(plot, "plot", - RTGUI_WIDGET_TYPE, + RTGUI_MV_VIEW_TYPE, _rtgui_plot_constructor, _rtgui_plot_destructor, sizeof(struct rtgui_plot)); -struct rtgui_plot *rtgui_plot_create(struct rtgui_plot_curve *curve) +struct rtgui_plot *rtgui_plot_create(void) { struct rtgui_plot *plot; - plot = (struct rtgui_plot *)rtgui_widget_create(RTGUI_PLOT_TYPE); - plot->curve_container.curve = curve; + plot = RTGUI_PLOT(rtgui_widget_create(RTGUI_PLOT_TYPE)); return plot; } @@ -58,45 +48,40 @@ RTM_EXPORT(rtgui_plot_create); void rtgui_plot_destroy(struct rtgui_plot *plot) { - rtgui_widget_destroy(RTGUI_WIDGET(plot)); + rtgui_mv_view_destroy(RTGUI_MV_VIEW(plot)); } RTM_EXPORT(rtgui_plot_destroy); -void rtgui_plot_set_base_point(struct rtgui_plot *plot, rt_uint16_t x, rt_uint16_t y) +void rtgui_plot_set_base(struct rtgui_plot *plot, + rtgui_plot_curve_dtype x, rtgui_plot_curve_dtype y) { - plot->base_point.x = x; - plot->base_point.y = y; + plot->base_x = x; + plot->base_y = y; } -RTM_EXPORT(rtgui_plot_set_base_point); +RTM_EXPORT(rtgui_plot_set_base); -void rtgui_plot_append_curve(struct rtgui_plot *plot, struct rtgui_plot_curve *curve) +rt_inline int _rtgui_plot_curve_calc_x(struct rtgui_plot *plot, rtgui_plot_curve_dtype x) { - struct rtgui_plot_curve_container *cur_cnt, *next_cnt; - - RT_ASSERT(plot); - - next_cnt = rtgui_malloc(sizeof(*next_cnt)); - next_cnt->curve = curve; - next_cnt->next = RT_NULL; + return (x - plot->base_x) / plot->scale_x; +} - cur_cnt = &plot->curve_container; - while (cur_cnt->next) - { - cur_cnt = cur_cnt->next; - } - cur_cnt->next = next_cnt; +rt_inline int _rtgui_plot_curve_calc_y(struct rtgui_plot *plot, rtgui_plot_curve_dtype y, rt_uint16_t height) +{ + return height - (y - plot->base_y) / plot->scale_y; } -RTM_EXPORT(rtgui_plot_append_curve); static void _rtgui_plot_curve_onpaint( - struct rtgui_dc *dc, - struct rtgui_plot_curve *curve, - struct rtgui_point base) + struct rtgui_dc *dc, + struct rtgui_plot *plot, + struct rtgui_plot_curve *curve, + rt_uint16_t start_idx, + rt_uint16_t stop_idx) { struct rtgui_rect rect; rt_uint16_t height; int last_x, last_y; rtgui_color_t old_color; + rtgui_plot_curve_dtype *x_data, *y_data; rtgui_dc_get_rect(dc, &rect); height = rtgui_rect_height(rect); @@ -104,16 +89,18 @@ static void _rtgui_plot_curve_onpaint( old_color = RTGUI_DC_FC(dc); RTGUI_DC_FC(dc) = curve->color; - if (curve->x_data) + x_data = rtgui_plot_curve_get_x(curve); + y_data = rtgui_plot_curve_get_y(curve); + if (x_data) { rt_size_t i; - last_x = curve->x_data[0] + base.x; - last_y = height - curve->y_data[0] - base.y; - for (i = 1; i < curve->length; i++) + last_x = _rtgui_plot_curve_calc_x(plot, x_data[start_idx]); + last_y = _rtgui_plot_curve_calc_y(plot, y_data[start_idx], height); + for (i = start_idx + 1; i < stop_idx; i++) { - int cur_x = curve->x_data[i] + base.x; - int cur_y = height - curve->y_data[i] - base.y; + int cur_x = _rtgui_plot_curve_calc_x(plot, x_data[i]); + int cur_y = _rtgui_plot_curve_calc_y(plot, y_data[i], height); rtgui_dc_draw_line(dc, last_x, last_y, cur_x, cur_y); @@ -125,12 +112,12 @@ static void _rtgui_plot_curve_onpaint( { rt_size_t i; - last_x = 0 + base.x; - last_y = height - curve->y_data[0] - base.y; - for (i = 1; i < curve->length; i++) + last_x = _rtgui_plot_curve_calc_x(plot, start_idx); + last_y = _rtgui_plot_curve_calc_y(plot, y_data[start_idx], height); + for (i = start_idx + 1; i < stop_idx; i++) { - int cur_x = i + base.x; - int cur_y = height - curve->y_data[i] - base.y; + int cur_x = _rtgui_plot_curve_calc_x(plot, i); + int cur_y = _rtgui_plot_curve_calc_y(plot, y_data[i], height); rtgui_dc_draw_line(dc, last_x, last_y, cur_x, cur_y); @@ -141,44 +128,160 @@ static void _rtgui_plot_curve_onpaint( RTGUI_DC_FC(dc) = old_color; } -static void _rtgui_plot_onpaint(struct rtgui_object *object, struct rtgui_event *event) +static void _rtgui_plot_draw_curve(struct rtgui_plot *plot, struct rtgui_event *event) { + int i; struct rtgui_dc *dc; - struct rtgui_rect rect; - struct rtgui_plot *plot = RTGUI_PLOT(object); - struct rtgui_plot_curve_container *cnt; dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(plot)); if (dc == RT_NULL) return; - rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect); - rtgui_dc_fill_rect(dc, &rect); + if (RTGUI_MV_VIEW(plot)->model_number == 1) + { + _rtgui_plot_curve_onpaint(dc, plot, + RTGUI_PLOT_CURVE(RTGUI_MV_VIEW(plot)->model), + 0, RTGUI_MV_MODEL(RTGUI_MV_VIEW(plot)->model)->length); + } + else + { + void **curve_array = (void **)RTGUI_MV_VIEW(plot)->model; + for (i = 0; i < RTGUI_MV_VIEW(plot)->model_number; i++) + { + _rtgui_plot_curve_onpaint(dc, plot, + RTGUI_PLOT_CURVE(curve_array[i]), + 0, RTGUI_MV_MODEL(curve_array[i])->length); + } + } + + rtgui_dc_end_drawing(dc); +} + +static void _rtgui_plot_update_scale(struct rtgui_plot *plot) +{ + struct rtgui_plot_curve *curve; + struct rtgui_rect rect; + rtgui_plot_curve_dtype max_x = 0; + rtgui_plot_curve_dtype min_x = 0; + rtgui_plot_curve_dtype max_y = 0; + rtgui_plot_curve_dtype min_y = 0; + rt_uint32_t iter = 0; - for (cnt = &plot->curve_container; cnt; cnt = cnt->next) + rtgui_widget_get_rect(RTGUI_WIDGET(plot), &rect); + + curve = RTGUI_PLOT_CURVE( + rtgui_mv_view_foreach_in_model(RTGUI_MV_VIEW(plot), &iter)); + max_x = curve->max_x; + min_x = curve->min_x; + max_y = curve->max_y; + min_y = curve->min_y; + + while (curve) { - _rtgui_plot_curve_onpaint(dc, cnt->curve, plot->base_point); + if (curve->max_x > max_x) + max_x = curve->max_x; + if (curve->min_x < min_x) + min_x = curve->min_x; + if (curve->max_y > max_y) + max_y = curve->max_y; + if (curve->min_y < min_y) + min_y = curve->min_y; + + curve = RTGUI_PLOT_CURVE( + rtgui_mv_view_foreach_in_model(RTGUI_MV_VIEW(plot), &iter)); } + plot->scale_x = (max_x - min_x + rtgui_rect_width(rect)) / rtgui_rect_width(rect); + plot->scale_y = (max_y - min_y + rtgui_rect_height(rect)) / rtgui_rect_height(rect); +} + +rt_bool_t rtgui_plot_ondraw(struct rtgui_plot *plot, struct rtgui_event *event) +{ + struct rtgui_dc *dc; + struct rtgui_rect rect; + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(plot)); + if (dc == RT_NULL) + return RT_FALSE; + + rtgui_widget_get_rect(RTGUI_WIDGET(plot), &rect); + + rtgui_dc_fill_rect(dc, &rect); + + _rtgui_plot_draw_curve(plot, event); + rtgui_dc_end_drawing(dc); + + return RT_FALSE; +} + +rt_bool_t rtgui_plot_onmvmodel(struct rtgui_plot *plot, struct rtgui_event *event) +{ + struct rtgui_event_mv_model *emodel = (struct rtgui_event_mv_model *)event; + + RT_ASSERT(plot); + RT_ASSERT(event); + + switch (plot->ptype) + { + case RTGUI_PLOT_TYPE_SCAN: + _rtgui_plot_update_scale(plot); + rtgui_plot_ondraw(plot, event); + case RTGUI_PLOT_TYPE_INCREMENTAL: + { + rt_uint16_t old_sc_x = plot->scale_x; + rt_uint16_t old_sc_y = plot->scale_y; + + _rtgui_plot_update_scale(plot); + + if (old_sc_x != plot->scale_x || old_sc_y != plot->scale_y) + { + /* we need to repaint the whole widget as the scale changed. */ + rtgui_plot_ondraw(plot, event); + } + else + { + /* get dc for _rtgui_plot_curve_onpaint */ + struct rtgui_dc *dc; + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(plot)); + if (dc == RT_NULL) + return RT_FALSE; + + /* only draw the newly recieved data */ + _rtgui_plot_curve_onpaint(dc, plot, + RTGUI_PLOT_CURVE(emodel->model), + emodel->first_data_changed_idx, + emodel->last_data_changed_idx + 1); + + rtgui_dc_end_drawing(dc); + } + } + return RT_TRUE; + default: + RT_ASSERT(0); + } + + return RT_TRUE; } rt_bool_t rtgui_plot_event_handler(struct rtgui_object *object, struct rtgui_event *event) { struct rtgui_plot *plot; + RTGUI_WIDGET_EVENT_HANDLER_PREPARE; plot = RTGUI_PLOT(object); + switch (event->type) { case RTGUI_EVENT_PAINT: - _rtgui_plot_onpaint(object, event); - break; + _rtgui_plot_update_scale(RTGUI_PLOT(object)); + return rtgui_plot_ondraw(plot, event); + case RTGUI_EVENT_MV_MODEL: + return rtgui_plot_onmvmodel(plot, event); default: return rtgui_widget_event_handler(object, event); } - - return RT_FALSE; } RTM_EXPORT(rtgui_plot_event_handler); |
