mreでのコントロール実装(三、Button実装)


buttonコントロールを実装します.他のコントロールクラスはこのように書きます.

//button.h  
 #ifndef __BUTTON_H__
#define __BUTTON_H__

#include "widget.h"

typedef void (*ButtonOnClickedFunc)(void* param1, void* param2);

typedef enum _ButtonStyle
{
    ButtonStyle1,
    ButtonStyle2,
    ButtonStyleMax
} ButtonStyle;

/*
 *     :button_create
 *     : 
 *     :
 */
Widget* button_create(int id, Rect rect, int* layer, char* text);

/*
 *     :button_set_on_clicked_func
 *     : 
 *     :
 */
void button_set_on_clicked_func(Widget* thiz, ButtonOnClickedFunc on_clicked, void* param1, void* param2);

/*
 *     :button_set_font_size
 *     : 
 *     :
 */
void button_set_font_size(Widget* thiz, font_size_t size);

/*
 *     :button_set_style
 *     : 
 *     :
 */
void button_set_style(Widget* thiz, ButtonStyle style);

/*
 *     :button_set_text
 *     : 
 *     :
 */
void button_set_text(Widget* thiz, char* text);

#endif /*__BUTTON_H__*/

//button.c  
#include "button.h"

struct _ButtonExtra;
typedef struct _ButtonExtra ButtonExtra;

#define BUTTON_MAX_TEXT 0x20

typedef enum _ButtonState
{
    BUTTON_NORMAL,
    BUTTON_PUSHDOWN, 
    BUTTON_STATE_MAX
} ButtonState;

struct _ButtonExtra
{
    char text[BUTTON_MAX_TEXT];
    font_size_t fone_size;
    ButtonStyle style;
    ButtonState state;
    
    ButtonOnClickedFunc on_clicked;
    void* param1;
    void* param2;
};

static int button_on_key_event(Widget* thiz, int event, int keycode)
{
    ButtonExtra* extra = NULL;
    if(thiz == NULL || !widget_is_visible(thiz) || NULL == thiz->extra || !widget_is_focus(thiz))
        return FALSE;

    extra = (ButtonExtra*)thiz->extra;
    if(VM_KEY_EVENT_DOWN == event)
    {
        switch(keycode)
        {
            case VM_KEY_OK:
                extra->state = BUTTON_PUSHDOWN;
                break;
            default:
                break;
        }
    }
    else if(VM_KEY_EVENT_UP == event)
    {
        switch(keycode)
        {
            case VM_KEY_OK:
                extra->state = BUTTON_NORMAL;
                if(extra && extra->on_clicked)
                    extra->on_clicked(extra->param1, extra->param2);
                break;
            default:
                break;
        }
    }
    return TRUE;
}

static int button_on_pen_event(Widget* thiz, int event, int x, int y)
{
    ButtonExtra* extra = NULL;
    if(NULL == thiz || !widget_is_visible(thiz) || NULL == thiz->extra)
        return FALSE;

    extra = (ButtonExtra*)thiz->extra;
    if(VM_PEN_EVENT_TAP == event)
    {
        if(widget_is_point_in_area(thiz, x, y))
            extra->state = BUTTON_PUSHDOWN;
    }
    else if(BUTTON_PUSHDOWN == extra->state && VM_PEN_EVENT_RELEASE == event)
    {
        extra->state = BUTTON_NORMAL;
        if(extra->on_clicked)
            extra->on_clicked(extra->param1, extra->param2);
    }
    return TRUE;
}

static int button_on_paint(Widget* thiz)
{
    ButtonExtra* extra = NULL;
    VMWCHAR button_name[BUTTON_MAX_TEXT] = {0};
    VMINT wstr_width, wstr_height;
    VMINT x_pos = widget_get_x_pos_abs(thiz);
    VMINT y_pos = widget_get_y_pos_abs(thiz);
    VMINT height = widget_get_height(thiz);
    VMINT width = widget_get_width(thiz);
    int* layer = widget_get_layer(thiz);
    int layer_hd = layer[widget_get_layer_index(thiz)];
    vm_graphic_color start_color;
    vm_graphic_color end_color;    
    vm_graphic_color color;

    if(NULL == thiz || !widget_is_visible(thiz) || NULL == thiz->extra)
        return FALSE;

    extra = (ButtonExtra*)thiz->extra;
    vm_graphic_set_font(extra->fone_size);
    vm_gb2312_to_ucs2(button_name, BUTTON_MAX_TEXT, extra->text);
    wstr_width = vm_graphic_get_string_width(button_name);
    wstr_height = vm_graphic_get_string_height(button_name);

    if(ButtonStyle1 == extra->style)
    {        
        if(BUTTON_NORMAL == extra->state)
        {
            end_color.vm_color_565 = VM_COLOR_888_TO_565(130, 130, 130);
            start_color.vm_color_565 = VM_COLOR_888_TO_565(210, 210, 210);
        }
        else if(BUTTON_PUSHDOWN == extra->state)
        {
            end_color.vm_color_565 = VM_COLOR_888_TO_565(70, 70, 70);
            start_color.vm_color_565 = VM_COLOR_888_TO_565(130, 130, 130);
        }
        color.vm_color_565 = VM_COLOR_BLACK;
        vm_graphic_setcolor(&color);
        vm_graphic_gradient_paint_rect(layer_hd, x_pos + 1, y_pos + 1,     x_pos + width - 2, y_pos + height - 2, start_color, end_color, VM_GDI_GP_VER);
        vm_graphic_roundrect_ex(layer_hd, x_pos, y_pos, width, height, 5);
        vm_graphic_textout_to_layer(layer_hd, x_pos + width/2 - wstr_width/2 - 4, y_pos + height/2 - wstr_height/2 - 3, button_name, vm_wstrlen(button_name));
    }
    else if(ButtonStyle2 == extra->style)
    {
    }

    vm_graphic_set_font(VM_MEDIUM_FONT);
    return TRUE;
}

static int button_on_destroy(Widget* thiz)
{
    return_val_if_fail(NULL != (int)thiz, -1);
    if(thiz->extra)
        WBH_FREE(thiz->extra);
    widget_deinit(thiz);
    WBH_FREE(thiz);
}

void button_set_on_clicked_func(Widget* thiz, ButtonOnClickedFunc on_clicked, void* param1, void* param2)
{
    ButtonExtra* extra = (ButtonExtra*)thiz->extra;
    extra->on_clicked = on_clicked;
    extra->param1 = param1;
    extra->param2 = param2;
}

void button_set_font_size(Widget* thiz, font_size_t size)
{
    ButtonExtra* extra = (ButtonExtra*)thiz->extra;
    extra->fone_size = size;
}

void button_set_style(Widget* thiz, ButtonStyle style)
{
    ButtonExtra* extra = (ButtonExtra*)thiz->extra;
    extra->style = style;
}

void button_set_text(Widget* thiz, char* text)
{
    ButtonExtra* extra = (ButtonExtra*)thiz->extra;
    if(NULL == text || 0 == strlen(text))
        return;
    memset(extra->text, 0, sizeof(extra->text));
    strncpy(extra->text, text, sizeof(extra->text));
}

Widget* button_create(int id, Rect rect, int* layer, char* text)
{
    Widget* thiz = NULL;
    ButtonExtra* extra = NULL;

    thiz = WBH_MALLOC(sizeof(Widget));
    extra = WBH_MALLOC(sizeof(ButtonExtra));

    extra->fone_size = VM_MEDIUM_FONT;
    extra->style = ButtonStyle1;
    strncpy(extra->text, text, sizeof(extra->text));
    thiz->extra = (void*)extra;
    
    thiz->on_key_event = button_on_key_event;
    thiz->on_pen_event = button_on_pen_event;
    thiz->on_paint = button_on_paint;
    thiz->on_destroy = button_on_destroy;

    widget_init(thiz, CONTROL_TYPE_BUTTON, id, rect, layer);
    return thiz;
}