<commit_before>
/**
 * @file lv_rotary.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_rotary.h"
#if LV_USE_ROTARY != 0

#include "../lv_misc/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_core/lv_indev.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_math.h"
#include "lv_img.h"

/*********************
 *      DEFINES
 *********************/
#define LV_OBJX_NAME "lv_rotary"

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param);
static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part);
// static void draw_bg(lv_obj_t * rotary, const lv_area_t * clip_area);
// static void draw_indic(lv_obj_t * rotary, const lv_area_t * clip_area);
static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area);

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_design_cb_t ancestor_design;
static lv_signal_cb_t ancestor_signal;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/**
 * Create a rotary objects
 * @param par pointer to an object, it will be the parent of the new rotary
 * @param copy pointer to a rotary object, if not NULL then the new object will be copied from it
 * @return pointer to the created rotary
 */
lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy)
{
    LV_LOG_TRACE("rotary create started");

    /*Create the ancestor rotary*/
    lv_obj_t * rotary = lv_arc_create(par, copy);
    LV_ASSERT_MEM(rotary);
    if(rotary == NULL) return NULL;

    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(rotary);
    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(rotary);

    /*Allocate the rotary type specific extended data*/
    lv_rotary_ext_t * ext = lv_obj_allocate_ext_attr(rotary, sizeof(lv_rotary_ext_t));
    LV_ASSERT_MEM(ext);
    if(ext == NULL) {
        lv_obj_del(rotary);
        return NULL;
    }

    /*Initialize the allocated 'ext' */
    ext->arc.rotation_angle = 0;
    ext->arc.bg_angle_start = 135;
    ext->arc.bg_angle_end = 45;
    ext->arc.arc_angle_start = 135;
    ext->arc.arc_angle_end = 270;
    ext->cur_value = 0;
    ext->min_value = 0;
    ext->max_value = 0;
    ext->dragging = false;
    lv_style_list_init(&ext->style_knob);

    /*The signal and design functions are not copied so set them here*/
    lv_obj_set_signal_cb(rotary, lv_rotary_signal);
    lv_obj_set_design_cb(rotary, lv_rotary_design);

    /*Init the new rotary rotary*/
    if(copy == NULL) {
        lv_obj_set_click(rotary, true);
        lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST);
        lv_obj_set_ext_click_area(rotary, 0, 0, LV_DPI / 10, LV_DPI / 10);

        lv_theme_apply(rotary, LV_THEME_ROTARY);
    }
    /*Copy an existing rotary*/
    else {
        lv_rotary_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
        ext->cur_value = copy_ext->cur_value;
        ext->min_value = copy_ext->min_value;
        ext->max_value = copy_ext->max_value;
        ext->dragging = copy_ext->dragging;
        lv_style_list_copy(&ext->style_knob, &copy_ext->style_knob);

        lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL);
    }

    LV_LOG_INFO("rotary created");

    return rotary;
}

/*=====================
 * Setter functions
 *====================*/

/**
 * Set a new value on the rotary
 * @param rotary pointer to a rotary object
 * @param value new value
 * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
 */
void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim)
{
    LV_ASSERT_OBJ(rotary, LV_OBJX_NAME);

    lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary);
    if(ext->cur_value == value) return;

    int16_t new_value;
    new_value = value > ext->max_value ? ext->max_value : value;
    new_value = new_value < ext->min_value ? ext->min_value : new_value;

    if(ext->cur_value == new_value) return;
    
    ext->cur_value = new_value;

    lv_arc_set_end_angle(
        rotary,
        LV_MATH_MAP(
            ext->cur_value, 
            ext->min_value, 
            ext->max_value, 
            ext->arc.arc_angle_start, 
            ext->arc.bg_angle_end
        )
    );
}

/**<commit_msg>Fix range mapping for value setter assuming left to right indic<commit_after>
/**
 * @file lv_rotary.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_rotary.h"
#if LV_USE_ROTARY != 0

#include "../lv_misc/lv_debug.h"
#include "../lv_core/lv_group.h"
#include "../lv_core/lv_indev.h"
#include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_math.h"
#include "lv_img.h"

/*********************
 *      DEFINES
 *********************/
#define LV_OBJX_NAME "lv_rotary"

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param);
static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part);
// static void draw_bg(lv_obj_t * rotary, const lv_area_t * clip_area);
// static void draw_indic(lv_obj_t * rotary, const lv_area_t * clip_area);
static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area);

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_design_cb_t ancestor_design;
static lv_signal_cb_t ancestor_signal;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/**
 * Create a rotary objects
 * @param par pointer to an object, it will be the parent of the new rotary
 * @param copy pointer to a rotary object, if not NULL then the new object will be copied from it
 * @return pointer to the created rotary
 */
lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy)
{
    LV_LOG_TRACE("rotary create started");

    /*Create the ancestor rotary*/
    lv_obj_t * rotary = lv_arc_create(par, copy);
    LV_ASSERT_MEM(rotary);
    if(rotary == NULL) return NULL;

    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(rotary);
    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(rotary);

    /*Allocate the rotary type specific extended data*/
    lv_rotary_ext_t * ext = lv_obj_allocate_ext_attr(rotary, sizeof(lv_rotary_ext_t));
    LV_ASSERT_MEM(ext);
    if(ext == NULL) {
        lv_obj_del(rotary);
        return NULL;
    }

    /*Initialize the allocated 'ext' */
    ext->arc.rotation_angle = 0;
    ext->arc.bg_angle_start = 135;
    ext->arc.bg_angle_end = 45;
    ext->arc.arc_angle_start = 135;
    ext->arc.arc_angle_end = 270;
    ext->cur_value = 0;
    ext->min_value = 0;
    ext->max_value = 0;
    ext->dragging = false;
    lv_style_list_init(&ext->style_knob);

    /*The signal and design functions are not copied so set them here*/
    lv_obj_set_signal_cb(rotary, lv_rotary_signal);
    lv_obj_set_design_cb(rotary, lv_rotary_design);

    /*Init the new rotary rotary*/
    if(copy == NULL) {
        lv_obj_set_click(rotary, true);
        lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST);
        lv_obj_set_ext_click_area(rotary, 0, 0, LV_DPI / 10, LV_DPI / 10);

        lv_theme_apply(rotary, LV_THEME_ROTARY);
    }
    /*Copy an existing rotary*/
    else {
        lv_rotary_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
        ext->cur_value = copy_ext->cur_value;
        ext->min_value = copy_ext->min_value;
        ext->max_value = copy_ext->max_value;
        ext->dragging = copy_ext->dragging;
        lv_style_list_copy(&ext->style_knob, &copy_ext->style_knob);

        lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL);
    }

    LV_LOG_INFO("rotary created");

    return rotary;
}

/*=====================
 * Setter functions
 *====================*/

/**
 * Set a new value on the rotary
 * @param rotary pointer to a rotary object
 * @param value new value
 * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
 */
void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim)
{
    LV_ASSERT_OBJ(rotary, LV_OBJX_NAME);

    lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary);
    if(ext->cur_value == value) return;

    int16_t new_value;
    new_value = value > ext->max_value ? ext->max_value : value;
    new_value = new_value < ext->min_value ? ext->min_value : new_value;

    if(ext->cur_value == new_value) return;
    
    ext->cur_value = new_value;

    lv_arc_set_end_angle(
        rotary,
        LV_MATH_MAP(
            ext->cur_value, 
            ext->min_value, 
            ext->max_value, 
            ext->arc.arc_angle_start, 
            360 + ext->arc.bg_angle_end
        )
    );
}

/**
{'fraction_non_alphanumeric': 0.17652733118971062, 'fraction_numerical': 0.006109324758842444, 'mean_word_length': 3.5807560137457046, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1652926', 'n_tokens_mistral': 3548, 'n_tokens_neox': 3323, 'n_words': 679}