00009__使用Awtk绘制饼图

  1. pieslice.h

    /**
     * File:   pieslice.h
     * Author: AWTK Develop Team
     * Brief:  pieslice
     *
     * Copyright (c) 2018 - 2018  Guangzhou ZHIYUAN Electronics Co.,Ltd.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * License file for more details.
     *
     */
    
    /**
     * History:
     * ================================================================
     * 2018-11-10  created
     *
     */
    
    #ifndef TK_PIESLICE_H
    #define TK_PIESLICE_H
    
    #include "base/widget.h"
    
    BEGIN_C_DECLS
    
    typedef struct _pieslice_t {
      widget_t widget;
      bool_t is_exploded;
      bool_t is_label_visible;
      bool_t clock_wise;
      bool_t pressed;
      float_t explode_distancefactor;
      float_t radius;
      float_t start_angle;
      float_t angle_span;
      float_t vertical_position;
      float_t horizontal_position;
      const char* label_text;
      xy_t x_center_point;
      xy_t y_center_point;
      color_t color;
      float_t value;
    } pieslice_t;
    
    widget_t* pieslice_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
    
    ret_t pieslice_set_start_angle(widget_t* widget, float_t start_angle);
    
    ret_t pieslice_set_angle_span(widget_t* widget, float_t angle_span);
    
    ret_t pieslice_set_color(widget_t* widget, color_t color);
    
    ret_t pieslice_set_exploaded(widget_t* widget, bool_t is_exploded);
    
    #define WIDGET_TYPE_PIESLICE "pieslice"
    #define PIESLICE(widget) ((pieslice_t*)(widget))
    
    END_C_DECLS
    
    #endif /*TK_PIESLICE_H*/
    
    
  2. pieslice.c

    /**
     * File:   pieslice.c
     * Author: AWTK Develop Team
     * Brief:  pieslice
     *
     * Copyright (c) 2018 - 2018  Guangzhou ZHIYUAN Electronics Co.,Ltd.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * License file for more details.
     *
     */
    
    /**
     * History:
     * ================================================================
     * 2018-11-10  created
     *
     */
    
    #include "base/mem.h"
    #include "base/utils.h"
    #include "base/widget_vtable.h"
    #include "base/window_manager.h"
    #include "charts/pieslice.h"
    
    
    static ret_t pieslice_on_event(widget_t* widget, event_t* e) {
      uint16_t type = e->type;
      pieslice_t* pieslice = PIESLICE(widget);
    
      switch (type) {
        case EVT_POINTER_DOWN: {
          pieslice->pressed = TRUE;
          widget_set_state(widget, WIDGET_STATE_PRESSED);
          widget_grab(widget->parent, widget);
    
          // pieslice_t* pieslice = PIESLICE(widget);
          // pieslice->radius = pieslice->radius * (1 + pieslice->explode_distancefactor);
          // pointer_event_t evt = *(pointer_event_t*)e;
          // evt.e = event_init(EVT_PAINT, widget);
          // widget_dispatch(widget, (event_t*)&evt);
    
          break;
        }
        case EVT_POINTER_DOWN_ABORT: {
          pieslice->pressed = FALSE;
          widget_ungrab(widget->parent, widget);
          widget_set_state(widget, WIDGET_STATE_NORMAL);
          break;
        }
        case EVT_POINTER_UP: {
          pointer_event_t evt = *(pointer_event_t*)e;
          if (pieslice->pressed && widget_is_point_in(widget, evt.x, evt.y, FALSE)) {
            evt.e = event_init(EVT_CLICK, widget);
            // pieslice_pointer_up_cleanup(widget);
            widget_dispatch(widget, (event_t*)&evt);
          } else {
            // pieslice_pointer_up_cleanup(widget);
          }
    
          break;
        }
        case EVT_POINTER_LEAVE:
          widget_set_state(widget, WIDGET_STATE_NORMAL);
    
          // pieslice_t* pieslice = PIESLICE(widget);
          // pieslice->radius = pieslice->radius * (1 - pieslice->explode_distancefactor);
          // pointer_event_t evt = *(pointer_event_t*)e;
          // evt.e = event_init(EVT_PAINT, widget);
          // widget_dispatch(widget, (event_t*)&evt);
    
          break;
        case EVT_POINTER_ENTER:
          widget_set_state(widget, WIDGET_STATE_OVER);
          break;
        default:
          break;
      }
    
      return RET_OK;
    }
    
    static ret_t pieslice_on_paint_self(widget_t* widget, canvas_t* c) {
      style_t* style = widget->astyle;
      color_t trans = color_init(0, 0, 0, 0);
      vgcanvas_t* vg = canvas_get_vgcanvas(c);
      pieslice_t* pieslice = PIESLICE(widget);
      color_t color = style_get_color(style, STYLE_ID_FG_COLOR, trans);
      if (vg != NULL) {
        vgcanvas_save(vg);
        vgcanvas_begin_path(vg);
        vgcanvas_set_line_width(vg, 1);
        vgcanvas_set_stroke_color(vg, color_init(0, 0xff, 0, 0xff));
        vgcanvas_set_fill_color(vg, pieslice->color);
        vgcanvas_translate(vg, pieslice->x_center_point, pieslice->y_center_point);
        vgcanvas_move_to(vg, 0, 0);
        vgcanvas_arc(vg, 0, 0, pieslice->radius, pieslice->start_angle, pieslice->angle_span, FALSE);
        vgcanvas_fill(vg);
        vgcanvas_close_path(vg);
        vgcanvas_restore(vg);
      }
    
      color = style_get_color(style, STYLE_ID_TEXT_COLOR, trans);
      if (pieslice->is_label_visible) {
        
      }
    
      return RET_OK;
    }
    
    static ret_t pieslice_get_prop(widget_t* widget, const char* name, value_t* v) {
      pieslice_t* pieslice = PIESLICE(widget);
      return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
    
      return RET_NOT_FOUND;
    }
    
    static ret_t pieslice_set_prop(widget_t* widget, const char* name, const value_t* v) {
      return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
    
      return RET_NOT_FOUND;
    }
    
    ret_t pieslice_set_start_angle(widget_t* widget, float_t start_angle){
      pieslice_t* pieslice = PIESLICE(widget);
      return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
    
      pieslice->start_angle = start_angle;
      
      return widget_invalidate(widget, NULL);
    }
    
    ret_t pieslice_set_angle_span(widget_t* widget, float_t angle_span){
      pieslice_t* pieslice = PIESLICE(widget);
      return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
    
      pieslice->angle_span = angle_span;
    
      return widget_invalidate(widget, NULL);
    }
    
    ret_t pieslice_set_color(widget_t* widget, color_t color){
      pieslice_t* pieslice = PIESLICE(widget);
      return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
    
      pieslice->color = color;
    
      return widget_invalidate(widget, NULL);
    }
    
    ret_t pieslice_set_exploaded(widget_t* widget, bool_t is_exploded){
      if(is_exploded){
        pieslice_t* pieslice = PIESLICE(widget);
        pieslice->radius = pieslice->radius * (1 + pieslice->explode_distancefactor);
        paint_event_t evt;
        evt.e = event_init(EVT_PAINT, widget);
        widget_dispatch(widget, (event_t*)&evt);
       
        // window_manager()
      }
    
      return RET_OK;
    }
    static const widget_vtable_t s_pieslice_vtable = {
        .size = sizeof(pieslice_t),
        .type = WIDGET_TYPE_PIESLICE,
        .create = pieslice_create,
        .on_paint_self = pieslice_on_paint_self,
        .on_event = pieslice_on_event,
        .get_prop = pieslice_get_prop,
        .set_prop = pieslice_set_prop};
    
    widget_t* pieslice_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
      pieslice_t* pieslice = TKMEM_ZALLOC(pieslice_t);
      widget_t* widget = WIDGET(pieslice);
      return_value_if_fail(pieslice != NULL, NULL);
    
      widget_init(widget, parent, &s_pieslice_vtable, x, y, w, h);
    
      pieslice->is_exploded = FALSE;
      pieslice->is_label_visible = FALSE;
      pieslice->clock_wise = FALSE;
      pieslice->pressed = FALSE;
      pieslice->explode_distancefactor = 0.15;
      pieslice->radius = tk_min(w, h) / 2;
      pieslice->horizontal_position = 0.5;
      pieslice->vertical_position = 0.5;
      pieslice->x_center_point = x + (w * pieslice->horizontal_position);
      pieslice->y_center_point = y + (h * pieslice->vertical_position);
      pieslice->start_angle = 0.0;
      pieslice->angle_span = M_PI / 2;
      pieslice->label_text = "";
      pieslice->color = color_init(0, 0xff, 0, 0xff);
    
      return widget;
    }
    
    
  3. piechar.h

    /**
     * File:   piechar.h
     * Author: AWTK Develop Team
     * Brief:  piechar
     *
     * Copyright (c) 2018 - 2018  Guangzhou ZHIYUAN Electronics Co.,Ltd.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * License file for more details.
     *
     */
    
    /**
     * History:
     * ================================================================
     * 2018-11-10  created
     *
     */
    
    #ifndef TK_PIECHAR_H
    #define TK_PIECHAR_H
    
    #include "base/widget.h"
    #include "base/array.h"
    
    BEGIN_C_DECLS
    
    typedef struct _piechar_t {
      widget_t widget;
      float_t total;
      array_t pieslice_array;
    } piechar_t;
    
    widget_t* piechar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
    
    ret_t piechar_pieslice_add(widget_t* parent, const char* label_text, float_t value, color_t color, bool_t is_finish);
    
    #define WIDGET_TYPE_PIECHAR "piechar"
    #define PIECHAR(widget) ((piechar_t*)(widget))
    
    END_C_DECLS
    
    #endif /*TK_PIECHAR_H*/
    
    
  4. piechar.c

    /**
     * File:   piechar.c
     * Author: AWTK Develop Team
     * Brief:  piechar
     *
     * Copyright (c) 2018 - 2018  Guangzhou ZHIYUAN Electronics Co.,Ltd.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * License file for more details.
     *
     */
    
    /**
     * History:
     * ================================================================
     * 2018-11-10  created
     *
     */
    
    #include "base/mem.h"
    #include "base/utils.h"
    #include "base/widget_vtable.h"
    #include "base/image_manager.h"
    #include "charts/piechar.h"
    #include "charts/pieslice.h"
    
    #define PIESLICE_NUM 15
    
    static ret_t piechar_get_prop(widget_t* widget, const char* name, value_t* v) {
      pieslice_t* pieslice = PIESLICE(widget);
      return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
    
      return RET_NOT_FOUND;
    }
    
    static ret_t  piechar_set_prop(widget_t* widget, const char* name, const value_t* v) {
      return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
    
      return RET_NOT_FOUND;
    }
    
    ret_t piechar_pieslice_add(widget_t* parent, const char* label_text, float_t value, color_t color, bool_t is_finish){
      pieslice_t* pieslice = pieslice_create(parent, parent->x, parent->y, parent->w, parent->h);
    
      return_value_if_fail(pieslice != NULL, RET_BAD_PARAMS);
      
      piechar_t* piechar = PIECHAR(parent);
      piechar->total += value;
      pieslice->label_text = label_text;
      pieslice->value = value;
      pieslice->color = color;
      pieslice->widget.name = label_text;
      array_push(&piechar->pieslice_array, pieslice);
      // widget_set_name(pieslice, label_text);
    
      if(is_finish){ 
        float_t start_angle = 0;
        pieslice_t* iter = NULL;
        pieslice_t** all = (pieslice_t**)(piechar->pieslice_array.elms);
        int size = piechar->pieslice_array.size;
        for(int i = 0; i < size; i++){
          iter = all[i];
          float_t percent = (iter->value / piechar->total) * 2 * M_PI;
          iter->start_angle = start_angle;
          iter->angle_span = start_angle + percent;
          start_angle = iter->angle_span;
        }
      }
    
      return RET_OK;
    }
    
    static const widget_vtable_t s_piechar_vtable = {
        .size = sizeof(piechar_t),
        .type = WIDGET_TYPE_PIECHAR,
        .create = piechar_create,
        // .on_paint_self = pieslice_on_paint_self,
        .get_prop = piechar_get_prop,
        .set_prop = piechar_set_prop};
    
    widget_t* piechar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
      piechar_t* piechar = TKMEM_ZALLOC(piechar_t);
      widget_t* widget = WIDGET(piechar);
      return_value_if_fail(piechar != NULL, NULL);
    
      widget_init(widget, parent, &s_piechar_vtable, x, y, w, h);
    
      array_init(&piechar->pieslice_array, PIESLICE_NUM);
      piechar->total = 0;
    
      return widget;
    }
    
    
    
  5. demo.c

    static ret_t on_pieslice_click(void* ctx, event_t* e) {
      widget_t* win = WIDGET(ctx);
      pieslice_t* pieslice = (pieslice_t*)e->target;
      // widget_t* pieslice = widget_lookup(win, "aa", TRUE);
      // if(pieslice != NULL){
      //   pieslice_set_exploaded(pieslice, TRUE);
      // }
    
      (void)e;
      return RET_OK;
    }
    
    ret_t application_init() {
      widget_factory_register(widget_factory(), WIDGET_TYPE_PIESLICE, pieslice_create);
    
      widget_t* win = window_create(NULL, 0, 0, 0, 0);
    
      widget_t* piechar = piechar_create(win, 0, 0, 400, 400);
      piechar_pieslice_add(piechar, "aa", 1.0f, color_init(0xff, 0, 0, 0xff), FALSE);
      piechar_pieslice_add(piechar, "bb", 2.0f, color_init(0, 0xff, 0, 0xff), FALSE);
      piechar_pieslice_add(piechar, "cc", 3.0f, color_init(0, 0, 0xff, 0xff), FALSE);
      piechar_pieslice_add(piechar, "dd", 4.0f, color_init(0, 0, 0xaa, 0xff), TRUE);
    
      piechar_t* ppiechar = PIECHAR(piechar);
      pieslice_t* iter = NULL;
      pieslice_t** all = (pieslice_t**)(ppiechar->pieslice_array.elms);
      int size = ppiechar->pieslice_array.size;
      for(int i = 0; i < size; i++){
        iter = all[i];
         widget_on(iter, EVT_CLICK, on_pieslice_click, win);
      }
    
      // widget_t* pieslice = pieslice_create(win, 10, 10, 200, 200);
      // pieslice_set_start_angle(pieslice, 0);
      // pieslice_set_angle_span(pieslice, 3.14);
    
      // widget_t* pieslice1 = pieslice_create(win, 10, 10, 200, 200);
      // pieslice_set_start_angle(pieslice1, 3.14);
      // pieslice_set_angle_span(pieslice1, 3.14*2);
      // pieslice_set_color(pieslice1, color_init(0xff, 0, 0, 0xff));
      
      // widget_t* circle = progress_circle_create(win, 0 , 0, 150, 150);
      // progress_circle_set_value(circle, 15);
      // progress_circle_set_line_width(circle, 18);
      // progress_circle_set_start_angle(circle, 30);
      // progress_circle_set_max(circle, 90);
    
      return RET_OK;
    }
    
    

猜你喜欢

转载自blog.csdn.net/tang935892307/article/details/84729426