static void rtgui_list_view_calc(struct rtgui_list_view* view)
{
    rtgui_rect_t rect;
    rt_uint32_t image_width, image_height;
    rt_ubase_t text_width, text_height;
    rt_ubase_t item_width, item_height;

    if (view->items_count == 0) return;

    /* get image width and height */
    if (view->items[0].image != RT_NULL) {
        image_width  = view->items[0].image->w;
        image_height = view->items[0].image->h;
    } else {
        image_width  = 0;
        image_height = 0;
    }

    rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect);

    text_height = rtgui_rect_height(rect);
    text_width = rtgui_rect_width(rect);

    rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);

    item_width = (image_width + LIST_MARGIN);
    if (item_width < (text_width + LIST_MARGIN)) item_width = text_width + LIST_MARGIN;
    item_height = image_height + 8 + text_height + LIST_MARGIN;
    if (item_width > item_height) item_height = item_width;
    else item_width = item_height;

    view->row_items = (rtgui_rect_height(rect) - 2 * LIST_MARGIN) / item_height;
    view->col_items = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / item_width;
    view->page_items = view->row_items * view->col_items;
}
Exemple #2
0
static void rtgui_image_hdcmm_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *dst_rect)
{
    rt_uint8_t *ptr;
    rt_uint16_t y, w, h;
    struct rtgui_image_hdcmm *hdc;

    RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);

    /* this dc is not visible */
    if (rtgui_dc_get_visible(dc) != RT_TRUE) return;

    hdc = (struct rtgui_image_hdcmm *) image;
    RT_ASSERT(hdc != RT_NULL);

    /* the minimum rect */
    if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
    else w = rtgui_rect_width(*dst_rect);
    if (image->h < rtgui_rect_height(*dst_rect)) h = image->h;
    else h = rtgui_rect_height(*dst_rect);


    /* get pixel pointer */
    ptr = hdc->pixels;

    for (y = 0; y < h; y ++)
    {
        dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y, ptr);
        ptr += hdc->pitch;
    }
}
rtgui_view_t *demo_view_buffer_animation(rtgui_workbench_t* workbench)
{
	rtgui_view_t *view;

	view = demo_view(workbench, "DC 缓冲区动画");
	if (view != RT_NULL)
		rtgui_widget_set_event_handler(RTGUI_WIDGET(view), animation_event_handler);

	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "缓冲动画", &text_rect);
	if (dc_buffer == RT_NULL)
	{
		rtgui_rect_t rect;

		rect.x1 = 0; rect.x2 = rtgui_rect_width(text_rect) + 2;
		rect.y1 = 0; rect.y2 = rtgui_rect_height(text_rect) + 2;

		/* 创建 DC Buffer,长 50,宽 50 */
		dc_buffer = rtgui_dc_buffer_create(rtgui_rect_width(rect), rtgui_rect_height(rect));
		RTGUI_DC_FC(dc_buffer) = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view));
		rtgui_dc_fill_rect(dc_buffer, &rect);
		RTGUI_DC_FC(dc_buffer) = black;
		rect.x1 = 1; rect.y1 = 1;
		rtgui_dc_draw_text(dc_buffer, "缓冲动画", &rect);
	}

	/* 启动定时器以触发动画 */
	timer = rtgui_timer_create(1, RT_TIMER_FLAG_PERIODIC, timeout, (void*)view);
	rtgui_timer_start(timer);

	return view;
}
Exemple #4
0
static void rtgui_list_view_calc(struct rtgui_list_view* view)
{
	/* get image of first item*/
	rtgui_image_t *image;
	rtgui_rect_t rect;
	rt_ubase_t text_width, text_height;
	rt_ubase_t item_width, item_height;

	if (view->items_count == 0) return;

	image = view->items[0].image;
	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect);

	text_height = rtgui_rect_height(rect);
	text_width = rtgui_rect_width(rect);

	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);

	item_width = (image->w + LIST_MARGIN);
	if (item_width < (text_width + LIST_MARGIN)) item_width = text_width + LIST_MARGIN;
	item_height = image->h + 3 + text_height + LIST_MARGIN; 

	view->row_items = (rtgui_rect_height(rect) - 2 * LIST_MARGIN) / item_height;
	view->col_items = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / item_width;
	view->page_items = view->row_items * view->col_items;
}
Exemple #5
0
void rtgui_edit_adjust_scroll(rtgui_scrollbar_t *bar)
{
	struct rtgui_edit *edit;
	
	RT_ASSERT(bar != RT_NULL);
	
	if(bar->WIDGET_GROUP != RT_NULL)
	{
		rtgui_rect_t rect;
		rt_uint32_t _left=0,_top=0,_width=RTGUI_DEFAULT_SB_WIDTH,_len=0;

		edit = bar->WIDGET_GROUP;
		rtgui_widget_get_rect(edit, &rect);
		rtgui_widget_rect_to_device(edit,&rect);
		if(bar->orient==RTGUI_HORIZONTAL)
		{
			if(RTGUI_WIDGET_IS_HIDE(edit->hscroll))
			{
				if(edit->max_rows > edit->row_per_page)
				{
					RTGUI_WIDGET_SHOW(edit->hscroll);
					rtgui_scrollbar_set_line_step(edit->hscroll, 1);
					rtgui_scrollbar_set_page_step(edit->hscroll, edit->row_per_page);
					rtgui_scrollbar_set_range(edit->hscroll, edit->max_rows);
				}
				else
					RTGUI_WIDGET_HIDE(edit->vscroll);
				rtgui_widget_update_clip(RTGUI_WIDGET(edit));
			}
			else
			{
				_left = RTGUI_WIDGET_BORDER_SIZE(edit);
				_top = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER_SIZE(edit)-_width;
				_len = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER_SIZE(edit)*2;
				
				if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll)) 
					_len -= _width;
				rect.x1 += _left;
				rect.y1 += _top;
				rect.x2 = rect.x1+_len;
				rect.y2 = rect.y1+_width;
			}
		}
		else if(bar->orient==RTGUI_VERTICAL)
		{
			_left = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER_SIZE(edit)-_width;
			_top = RTGUI_WIDGET_BORDER_SIZE(edit);
			_len = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER_SIZE(edit)*2;
			
			if(!RTGUI_WIDGET_IS_HIDE(edit->hscroll))  
				_len -= _width;
			rect.x1 += _left;
			rect.y1 += _top;
			rect.x2 = rect.x1+_width;
			rect.y2 = rect.y1+_len;
		}
		rtgui_widget_set_rect(bar,&rect);
	}
}
Exemple #6
0
/* get active area length */
rt_uint32_t get_sbar_active_len(rtgui_scrollbar_t *bar)
{
	rtgui_rect_t rect;

	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);

	if(bar->orient & RTGUI_VERTICAL)
		return rtgui_rect_height(rect) - 2*rtgui_rect_width(rect);
	else
		return rtgui_rect_width(rect) - 2*rtgui_rect_height(rect);
}
Exemple #7
0
static void rtgui_image_hdc_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *dst_rect)
{
    rt_uint16_t y, w, h;
    struct rtgui_image_hdc *hdc;

    RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);

    /* this dc is not visible */
    if (rtgui_dc_get_visible(dc) != RT_TRUE) return;

    hdc = (struct rtgui_image_hdc *) image->data;
    RT_ASSERT(hdc != RT_NULL);

    /* the minimum rect */
    if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
    else w = rtgui_rect_width(*dst_rect);
    if (image->h < rtgui_rect_height(*dst_rect)) h = image->h;
    else h = rtgui_rect_height(*dst_rect);

    if (hdc->pixels != RT_NULL)
    {
        rt_uint8_t *ptr;

        /* get pixel pointer */
        ptr = hdc->pixels;

        for (y = 0; y < h; y ++)
        {
            dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y, ptr);
            ptr += hdc->pitch;
        }
    }
    else
    {
        rt_uint8_t *ptr;
        ptr = rtgui_malloc(hdc->pitch);
        if (ptr == RT_NULL) return; /* no memory */

        /* seek to the begin of pixel data */
        rtgui_filerw_seek(hdc->filerw, hdc->pixel_offset, RTGUI_FILE_SEEK_SET);

        for (y = 0; y < h; y ++)
        {
            /* read pixel data */
            if (rtgui_filerw_read(hdc->filerw, ptr, 1, hdc->pitch) != hdc->pitch)
                break; /* read data failed */

            dc->engine->blit_line(dc, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y, ptr);
        }

        rtgui_free(ptr);
    }
}
Exemple #8
0
rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar)
{
	rtgui_rect_t rect;
	rt_uint32_t result;

	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);

	if(bar->orient & RTGUI_VERTICAL)
		result = rtgui_rect_height(rect) - 2*rtgui_rect_width(rect) - bar->thumb_len;
	else
		result = rtgui_rect_width(rect) - 2*rtgui_rect_height(rect) - bar->thumb_len;

	return result;
}
static void _calc_width(rtgui_textview_t *textview)
{
	rtgui_rect_t rect;
	rt_uint16_t width, height;

	width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6;
	height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent);

	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect);
	textview->line_width = width / rtgui_rect_width(rect) + 1;
	textview->line_page_count = height / (rtgui_rect_height(rect) + 3);

	/* set minimal value */
	if (textview->line_page_count == 0) textview->line_page_count = 1;
}
Exemple #10
0
struct rtgui_radiobox *rtgui_radiobox_create(const char *label, int orient, char **radio_items, int number)
{
    struct rtgui_radiobox *radiobox;

    radiobox = (struct rtgui_radiobox *) rtgui_widget_create(RTGUI_RADIOBOX_TYPE);
    if (radiobox != RT_NULL)
    {
        rt_uint8_t board_size;
        struct rtgui_rect rect;

        radiobox->items = radio_items;
        radiobox->item_count = number;
        radiobox->item_selection = -1;
        radiobox->text = rt_strdup(label);

        /* set proper of control */
        rtgui_radiobox_set_orientation(radiobox, orient);
        rtgui_font_get_metrics(RTGUI_WIDGET_FONT(radiobox), "H", &rect);
        board_size = rtgui_rect_height(rect);

        if (orient == RTGUI_VERTICAL)
        {
            radiobox->item_size = board_size;
        }
        else
        {
            int index;
            struct rtgui_font *font;
            struct rtgui_rect rect;

            /* set init item size */
            radiobox->item_size = 0;

            font = RTGUI_WIDGET_FONT(radiobox);
            for (index = 0; index < number; index ++)
            {
                rtgui_font_get_metrics(font, radio_items[index], &rect);
                if ((board_size + 3 + rtgui_rect_width(rect)) > radiobox->item_size)
                    radiobox->item_size = board_size + 3 + rtgui_rect_width(rect);
            }
        }

        if (radiobox->item_size < RADIO_BOX_H + 2)
            radiobox->item_size = RADIO_BOX_H + 2;
    }

    return radiobox;
}
Exemple #11
0
static void rtgui_textbox_init_caret(rtgui_textbox_t *box, rt_uint16_t position)
{
	int x, y;
	rtgui_color_t color;
	rtgui_rect_t rect;
	int ofs = 0;

	RT_ASSERT(box != RT_NULL);

	if (!RTGUI_WIDGET_IS_FOCUSED(box))
		return;

	rtgui_textbox_get_caret_rect(box, &box->caret_rect, position);
	rect = box->caret_rect;
	rtgui_widget_rect_to_device(RTGUI_WIDGET(box), &rect);

	if (box->caret == RT_NULL)
		box->caret = rtgui_malloc(rtgui_rect_width(rect) * rtgui_rect_height(rect) * sizeof(rtgui_color_t));

	for (x = rect.x1; x < rect.x2; x++)
	{
		for (y = rect.y1; y < rect.y2; y++)
		{
			rtgui_graphic_driver_get_default()->ops->get_pixel(&color, x, y);
			*(box->caret + ofs) = color;
			ofs++;
		}
	}
}
static void _rtgui_textbox_constructor(rtgui_textbox_t *box)
{
	rtgui_rect_t rect;

	RTGUI_WIDGET_FLAG(RTGUI_WIDGET(box)) |= RTGUI_WIDGET_FLAG_FOCUSABLE;

	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler);
	rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus);
	rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus);
#ifndef RTGUI_USING_SMALL_SIZE
	rtgui_widget_set_onkey(RTGUI_WIDGET(box), rtgui_textbox_onkey);
#endif

	RTGUI_WIDGET_FOREGROUND(box) = black;
	RTGUI_WIDGET_BACKGROUND(box) = white;
	/* set default text align */
	RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_CENTER_VERTICAL;
	/* set proper of control */
	box->caret_timer = RT_NULL;
	box->caret = RT_NULL;

	box->line = box->line_begin = box->position = 0;
	box->flag = RTGUI_TEXTBOX_SINGLE;
	/* allocate default line buffer */
	box->text = RT_NULL;
	rtgui_textbox_set_mask_char(box, '*');

	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(box), "H", &rect);
	box->font_width = rtgui_rect_width(rect);
	box->on_enter = RT_NULL;
	box->dis_length = 0;
	box->first_pos = 0;
}
Exemple #13
0
static void _rtgui_textbox_constructor(rtgui_textbox_t *box)
{
	rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT};
	rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);

	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler);
	rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus);
	rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus);

	/* set default text align */
	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;

	/* set proper of control */
	box->caret_timer = rtgui_timer_create(RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC, 
		_rtgui_textbox_caret_timeout, box);

	box->line = box->line_begin = box->position = 0;
	box->flag = RTGUI_TEXTBOX_SINGLE;

	/* allocate default line buffer */
	box->text = RT_NULL;

	rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect);
	box->font_width = rtgui_rect_width(rect);
}
static rt_bool_t app_list_view_onmouse(struct app_list_view *view,
                                       struct rtgui_event_mouse *emouse)
{
    if (rtgui_rect_contains_point(&view->view_rect,
                                  emouse->x, emouse->y) == RT_EOK)
    {
        rt_uint16_t index;
        rt_uint16_t old_item;

        /* get old item */
        old_item = view->current_item;

        {
            rt_uint16_t x, y;
            rt_uint16_t item_height, item_width;


            item_width = (rtgui_rect_width(view->view_rect) - 2 * LIST_MARGIN) /
                         view->col_items;
            item_height = (rtgui_rect_height(view->view_rect) - 4) / view->row_items;
            x = emouse->x - view->view_rect.x1;
            y = emouse->y - view->view_rect.y1;

            index = (y / item_height * view->col_items) + x / item_width;

            if ((index + (view->current_page * view->page_items) <
                    view->items_count))
            {

                if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
                {
                    view->current_item = index + (view->current_page *
                                                  view->page_items);
                    /* down event */
                    // rtgui_list_view_update_icon(view, old_item);
                }
                else
                {
                    if (view->current_item == index + (view->current_page *
                                                       view->page_items))
                    {
                        rt_kprintf("mouse up,current item:%d\n", view->current_item);
                        /* up event */
                        if (view->on_select != RT_NULL)
                        {
                            view->on_select(&view->items[view->current_item]);
                        }
                    }
                }

            }
        }


        return RT_TRUE;
    }

    return RT_FALSE;
}
static void gui_win_entry(void* parameter)
{
	const struct rtgui_graphic_driver* gd = rtgui_graphic_driver_get_default();
	struct rt_messagequeue *mq;
	rtgui_win_t *win;
	rtgui_button_t *button;
	rtgui_point_t p;
	rtgui_rect_t rect = {0,0,200,180};
	rtgui_label_t *label;
	rtgui_font_t *font;
	
	/* 创建GUI应用需要的消息队列 */
	mq = rt_mq_create("demo_win", 256, 32, RT_IPC_FLAG_FIFO);
	/* 注册当前线程 */
	rtgui_thread_register(rt_thread_self(), mq);

	/* 窗口居中 */
	rtgui_rect_moveto(&rect, (gd->width - rtgui_rect_width(rect))/2, (gd->height - rtgui_rect_height(rect))/2);
	/* 创建窗口 */
	win = rtgui_win_create(RT_NULL,"demo_win",&rect,RTGUI_WIN_DEFAULT);
	if(win == RT_NULL) return;
 
	/* 取得客户区坐标零点 */
	p = rtgui_win_get_client_zero(win);
	label = rtgui_label_create(win, "hello world!", p.x+5, p.y+5, 100,25);
	font = rtgui_font_refer("asc", 12);	
	RTGUI_WIDGET_FONT(label) = font;

	button = rtgui_button_create(win, "Exit", (rtgui_rect_width(rect)-50)/2,
								rtgui_rect_height(rect)-40,50,25);
	rtgui_button_set_onbutton(button,rtgui_win_close);

	rtgui_widget_set_event_handler(win, demo_gui_win_event_handler);
	
	rtgui_win_show(win,RT_FALSE);
	
	/* 执行工作台事件循环 */
	rtgui_win_event_loop(win);

	demo_win_inited = RT_FALSE;
	
	/* 去注册GUI线程 */
	rtgui_thread_deregister(rt_thread_self());
	rt_mq_delete(mq);
}
Exemple #16
0
static void rtgui_list_view_onicondraw(struct rtgui_list_view *view, struct rtgui_dc *dc)
{
    struct rtgui_rect rect, item_rect, drawing_rect;
    rt_ubase_t c, r, item_index; /* col and row index */
    rt_ubase_t item_width, item_height;
    rtgui_image_t *image;

    if (view->items_count == 0) return;

    rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
    item_index = (view->current_item / view->page_items) * view->page_items;

    item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / view->col_items;
    item_height = (rtgui_rect_height(rect) - 4) / view->row_items;
    image = view->items[0].image;

    for (r = 0; r < view->row_items; r ++)
    {
        for (c = 0; c < view->col_items; c ++)
        {
            if (item_index < view->items_count)
            {
                item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
                item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
                item_rect.x2 = item_rect.x1 + item_width;
                item_rect.y2 = item_rect.y1 + item_height;

                if (item_index == view->current_item)
                {
                    rtgui_theme_draw_selected(dc, &item_rect);
                }

                drawing_rect.x1 = drawing_rect.y1 = 0;
                drawing_rect.x2 = image->w;
                drawing_rect.y2 = image->h;
                rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
                drawing_rect.y1 += 5;
                drawing_rect.y2 += 5;
                rtgui_image_blit(view->items[item_index].image, dc, &drawing_rect);

                item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
                item_rect.x1 += 3;
                item_rect.x2 -= 3;
                rtgui_font_get_metrics(RTGUI_WIDGET_FONT(view), view->items[item_index].name,
                                       &drawing_rect);
                rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
                rtgui_dc_draw_text(dc, view->items[item_index].name, &drawing_rect);

                item_index ++;
            }
            else break;
        }
    }
}
Exemple #17
0
struct rtgui_dc*
rtgui_graphic_driver_get_rect_buffer(const struct rtgui_graphic_driver *driver,
                                     struct rtgui_rect *r)
{
    int w, h;
    struct rtgui_dc_buffer *buffer;
    rt_uint8_t *pixel, *dst;
    struct rtgui_rect src, rect;

    /* use virtual framebuffer in default */
    if (driver == RT_NULL) driver = _current_driver;

    if (r == RT_NULL)
    {
        rtgui_graphic_driver_get_rect(driver, &rect);
    }
    else
    {
        rtgui_graphic_driver_get_rect(driver, &src);
        rect = *r;
        rtgui_rect_intersect(&src, &rect);
    }

    w = rtgui_rect_width (rect);
    h = rtgui_rect_height(rect);
    if (!(w && h) || driver->framebuffer == RT_NULL)
        return RT_NULL;

    /* create buffer DC */
    buffer = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(driver->pixel_format, w, h);
    if (buffer == RT_NULL)
        return (struct rtgui_dc*)buffer;

    /* get source pixel */
    pixel = (rt_uint8_t*)driver->framebuffer
            + rect.y1 * driver->pitch
            + rect.x1 * rtgui_color_get_bpp(driver->pixel_format);

    dst = buffer->pixel;

    while (h--)
    {
        memcpy(dst, pixel, buffer->pitch);

        dst += buffer->pitch;
        pixel += driver->pitch;
    }

    return (struct rtgui_dc*)buffer;
}
Exemple #18
0
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;

    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)
    {
        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);
}
Exemple #19
0
void _rtgui_edit_constructor(struct rtgui_edit *edit)
{
	rtgui_rect_t font_rect;
	RTGUI_WIDGET_FLAG(edit) |= RTGUI_WIDGET_FLAG_FOCUSABLE;

	rtgui_widget_set_event_handler(edit, rtgui_edit_event_handler);
	rtgui_widget_set_onfocus(edit, rtgui_edit_onfocus);
	rtgui_widget_set_onunfocus(edit, rtgui_edit_onunfocus);
	
	RTGUI_WIDGET_FC(edit) = theme.foreground;
	RTGUI_WIDGET_BC(edit) = theme.blankspace;
	/* set default text align */
	RTGUI_WIDGET_TEXTALIGN(edit) = RTGUI_ALIGN_CENTER_VERTICAL;
	/* set proper of control */
	edit->caret_timer = RT_NULL;
	edit->caret = RT_NULL;

	edit->tabsize = 4;
	edit->margin  = 1;
	edit->max_rows = edit->max_cols = 0;
	edit->visual.x = edit->visual.y = 0;
	edit->upleft.x = edit->upleft.y = 0;
	edit->row_per_page = edit->col_per_page = 0;

	edit->update_buf = RT_NULL;
	edit->flag = RTGUI_EDIT_NONE;
#ifdef RTGUI_EDIT_USING_SCROLL
	edit->flag |= RTGUI_EDIT_VSCROLL;
	edit->flag |= RTGUI_EDIT_HSCROLL;
#endif
	/* allocate default line buffer */
	edit->bzsize = 16;
	
	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(edit), "H", &font_rect);
	edit->font_width = rtgui_rect_width(font_rect);
	edit->font_height = rtgui_rect_height(font_rect);

	edit->dbl_buf = rtgui_dc_buffer_create(edit->font_width*2+1, edit->font_height+1);
	
	edit->head = RT_NULL;
	edit->tail = RT_NULL;
	edit->first_line = RT_NULL;
#ifdef RTGUI_EDIT_USING_SCROLL	
	edit->hscroll = RT_NULL;
	edit->vscroll = RT_NULL;
#endif
}
Exemple #20
0
struct rtgui_container* demo_plot(void)
{
    struct rtgui_container *cnt;
    struct rtgui_plot_curve *curve1, *curve2, *curve3;
    struct rtgui_plot *plot;
    struct rtgui_rect rect;

    cnt = demo_view("ÇúÏß»æͼ");

    plot = rtgui_plot_create();

    curve1 = rtgui_plot_curve_create();
    rtgui_plot_curve_set_y(curve1, sin_ydata);
    RTGUI_MV_MODEL(curve1)->length = sizeof(sin_ydata)/sizeof(sin_ydata[0]);
    curve1->min_x = 0;
    curve1->max_x = sizeof(sin_ydata)/sizeof(sin_ydata[0]);
    curve1->min_y = -100;
    curve1->min_y = 100;
    curve1->color = red;
    rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve1), RTGUI_MV_VIEW(plot));

    curve2 = rtgui_plot_curve_create();
    rtgui_plot_curve_set_y(curve2, cos_ydata);
    RTGUI_MV_MODEL(curve2)->length = sizeof(cos_ydata)/sizeof(cos_ydata[0]);
    curve2->min_x = 0;
    curve2->max_x = sizeof(cos_ydata)/sizeof(cos_ydata[0]);
    curve1->min_y = -50;
    curve1->min_y = 50;
    curve2->color = blue;
    rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve2), RTGUI_MV_VIEW(plot));

    curve3 = rtgui_plot_curve_create();
    rtgui_plot_curve_set_x(curve3, cos_ydata);
    rtgui_plot_curve_set_y(curve3, sin_ydata);
    RTGUI_MV_MODEL(curve3)->length = sizeof(sin_ydata)/sizeof(sin_ydata[0]);
    curve3->color = black;
    rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve3), RTGUI_MV_VIEW(plot));

    rtgui_widget_get_rect(RTGUI_WIDGET(cnt), &rect);
    rtgui_widget_set_rect(RTGUI_WIDGET(plot), &rect);
    rtgui_plot_set_base(plot,
            -rtgui_rect_width(rect)/3, rtgui_rect_height(rect)/2);

    rtgui_container_add_child(cnt, RTGUI_WIDGET(plot));

    return cnt;
}
static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
{
	RT_ASSERT(slider != RT_NULL);
	RT_ASSERT(event  != RT_NULL);

	if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
		event->button & RTGUI_MOUSE_BUTTON_LEFT)
	{
		int sel;
		int range = slider->max - slider->min;
		int x0, xsize;
		int x;
		x0 = 1 + slider->thumb_width/2;

		if (slider->orient == RTGUI_VERTICAL)
		{
			x = event->y - RTGUI_WIDGET(slider)->extent.y1;
			x -= x0;
			xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
		}
		else
		{
			x = event->x - RTGUI_WIDGET(slider)->extent.x1;
			x -= x0;
			xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
		}

		if (x <= 0)
		{
			sel = slider->min;
		}
		else if (x >= xsize)
		{
			sel = slider->max;
		}
		else
		{
			sel = ((range * x) + xsize/2) / xsize;
			sel += slider->min;
		}

		rtgui_widget_focus(RTGUI_WIDGET(slider));
		rtgui_slider_set_value(slider, sel);
		if (slider->on_changed != RT_NULL) /* invoke callback function */
			slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
	}
}
Exemple #22
0
static void rtgui_textbox_get_caret_rect(rtgui_textbox_t *box, rtgui_rect_t *rect, rt_uint16_t position)
{
	int font_h, box_h;
	rtgui_rect_t item_rect;

	RT_ASSERT(box != RT_NULL);

	rtgui_widget_get_rect(RTGUI_WIDGET(box), rect);

	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(box), "H", &item_rect);
	font_h = rtgui_rect_height(item_rect);
    box->font_width = rtgui_rect_width(item_rect);
	box_h = rtgui_rect_height(*rect);

	rect->x1 += position * box->font_width + 2;
	rect->x2 = rect->x1 + 2;
	rect->y1 += (box_h - font_h) / 2;
	rect->y2 = rect->y1 + font_h;
}
Exemple #23
0
static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect)
{
	int x, y;
    int w, h;
	struct rtgui_blit_info info;
	struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default();

    RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL);
    RT_ASSERT(image->data != RT_NULL);

#define blending(s, d, a) (((unsigned)(((s) - (d)) * (a)) >> 8) + (d))

	/* this dc is not visible */
	if (rtgui_dc_get_visible(dc) != RT_TRUE) return;

	w = _UI_MIN(image->w, rtgui_rect_width(*rect));
	h = _UI_MIN(image->h, rtgui_rect_height(*rect));

	/* border checking */
	if (rect->x1 < 0) { x = -rect->x1; w += rect->x1; }
	else x = 0;

	if (rect->y1 < 0) { y = -rect->y1; h += rect->y1; }
	else y = 0;

	if (w < 0 || h < 0) return; /* no drawing */

	if ((dc->type == RTGUI_DC_CLIENT) || (dc->type == RTGUI_DC_HW && hw_driver->framebuffer == RT_NULL))
	{
		int dx, dy, start_x;
		rtgui_rect_t r;
		rtgui_color_t *pixel;
		rt_uint8_t alpha;
		rtgui_widget_t *owner = RT_NULL;

		if (dc->type == RTGUI_DC_CLIENT)
		{
			/* get owner and calculate dx,dy */
			owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
			dx = owner->extent.x1; dy = owner->extent.y1;
		}
Exemple #24
0
void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *erect)
{
	rtgui_rect_t rect;

	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
	if(bar->orient & RTGUI_VERTICAL)
	{
		/* vertical scroll bar */
		erect->x1 = rect.x1;
		erect->x2 = rect.x2;
		erect->y1 = rect.y1 + rtgui_rect_width(rect) + get_scrollbar_pos(bar);
		erect->y2 = erect->y1 + bar->thumb_len;
	}
	else
	{
		/* horizontal scroll bar */
		erect->x1 = rect.x1 + rtgui_rect_height(rect) + get_scrollbar_pos(bar);
		erect->x2 = erect->x1 + bar->thumb_len;
		erect->y1 = rect.y1;
		erect->y2 = rect.y2;
	}
}
Exemple #25
0
static rt_bool_t rtgui_textbox_onkey(struct rtgui_object *widget, rtgui_event_t *event)
{
	rtgui_textbox_t *box = RTGUI_TEXTBOX(widget);
	struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event;
	rt_size_t length;
	rt_uint16_t posbak = box->position;

	RT_ASSERT(box != RT_NULL);
	RT_ASSERT(ekbd != RT_NULL);

	/* handle the key at down time and nothing to do with up */
	if (RTGUI_KBD_IS_UP(ekbd))
		return RT_TRUE;

	if (box->dis_length == 0)
	{
		rtgui_rect_t rect;

		rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);

		if (box->font_width == 0)
			return RT_FALSE;

		box->dis_length = ((rtgui_rect_width(rect) - 5) / box->font_width) & ~0x1;
	}

	length = rt_strlen((char*)box->text);
	if (ekbd->key == RTGUIK_DELETE)
	{
        int chw;
        unsigned char *c;

        if (TB_ABSPOS(box) == length)
        {
            goto _exit;
        }
        chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box)).char_width;

        /* remove character */
        for (c = &box->text[TB_ABSPOS(box)]; c[chw] != '\0'; c++)
            *c = c[chw];
        *c = '\0';
	}
	else if (ekbd->key == RTGUIK_BACKSPACE)
	{
		/* delete front character */
		if (box->position == 0)
		{
			if(box->first_pos == 0)
                goto _exit;

            if(box->first_pos > box->dis_length)
            {
                int head_fix;
                int chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box) - 1).char_width;

                rt_memmove(box->text + TB_ABSPOS(box) - chw,
                           box->text + TB_ABSPOS(box),
                           length - TB_ABSPOS(box) + 1);

                head_fix = 0;
                /* FIXME: */
                if (box->text[box->first_pos - box->dis_length - chw] > 0x80)
                {
                    int i;

                    for (i = box->first_pos - box->dis_length - chw;
                         i < box->first_pos;
                         i++)
                    {
                        if (box->text[i] > 0x80)
                            head_fix++;
                        else
                            break;
                    }
                    /* if the head is in middle of wide char, move one less
                     * byte */
                    head_fix = head_fix % 2;
                }

                box->first_pos = box->first_pos - box->dis_length
                                 + head_fix - chw;
                box->position  = box->dis_length - head_fix;
            }
            else
            {
                int chw;
                if (box->text[TB_ABSPOS(box) - 1] < 0x80)
                {
                    /* also copy the \0 */
                    rt_memmove(box->text + TB_ABSPOS(box) - 1,
                               box->text + TB_ABSPOS(box),
                                  length - TB_ABSPOS(box) + 1);
                    chw = 1;
                }
                else
                {
                    rt_memmove(box->text + TB_ABSPOS(box) - 2,
                               box->text + TB_ABSPOS(box),
                                  length - TB_ABSPOS(box) + 1);
                    chw = 2;
                }
                box->position = box->first_pos - chw;
                box->first_pos = 0;
            }
		}
		else
		{
            unsigned char *c;
            int chw;

            chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box) - 1).char_width;

            /* remove character */
            for (c = &box->text[TB_ABSPOS(box) - chw]; c[chw] != '\0'; c++)
                *c = c[chw];
            *c = '\0';

            box->position -= chw;
		}
	}
	else if (ekbd->key == RTGUIK_LEFT)
	{
        int chw;

        if (box->first_pos == 0 && box->position == 0)
            goto _exit;

        if (box->text[TB_ABSPOS(box) - 1] > 0x80)
            chw = 2;
        else
            chw = 1;

		/* move to prev */
		if (box->position >= chw)
		{
            box->position -= chw;
		}
		else
		{
            if (box->first_pos >= chw)
                box->first_pos -= chw;
            else
                box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RIGHT)
	{
        int chw;

        if ((TB_ABSPOS(box) + 2) <= length &&
            box->text[TB_ABSPOS(box)] > 0x80)
            chw = 2;
        else
            chw = 1;

		/* move to next */
		if (TB_ABSPOS(box) < length)
		{
			if(box->position + chw <= box->dis_length)
				box->position += chw;
			else
            {
                /* always move one wide char when the first char is wide */
                if (box->text[box->first_pos] > 0x80)
                {
                    box->first_pos += 2;
                    if (chw == 2)
                    {
                        int i;
                        int head_fix = 0;
                        for (i = box->first_pos;
                             i < box->first_pos + box->dis_length;
                             i++)
                        {
                            if (box->text[i] > 0x80)
                                head_fix++;
                        }
                        head_fix %= 2;
                        if (head_fix)
                        {
                            box->first_pos += 2;
                            box->position = box->dis_length - 1;
                        }
                    }
                    else if (chw == 1)
                        /* we have moved the box by 2 bytes but the last one is
                         * a narrow char */
                        box->position -= 1;
                    else
                        RT_ASSERT(0);
                }
                else
                    box->first_pos += chw;
            }
		}
	}
	else if (ekbd->key == RTGUIK_HOME)
	{
		/* move cursor to start */
		box->position = 0;
		box->first_pos = 0;
	}
	else if (ekbd->key == RTGUIK_END)
	{
		/* move cursor to end */
		if(length > box->dis_length)
		{
			box->position = box->dis_length;
			box->first_pos = length - box->dis_length;
		}
		else
		{
			box->position = length;
			box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RETURN)
	{
		if (box->on_enter != RT_NULL)
		{
			box->on_enter(box, event);
		}
	}
	else if (ekbd->key == RTGUIK_NUMLOCK)
	{
		/* change numlock state */
		/*
		extern void update_number_lock(void);
		update_number_lock();
		*/
	}
	else
    {
        rt_uint16_t chr;
        int chw;

        if (!(ekbd->unicode || isprint(ekbd->key)))
            goto _exit;

        if (ekbd->unicode)
        {
            chr = ekbd->unicode;
            chw = 2;
        }
        else
        {
            chr = ekbd->key;
            chw = 1;
        }

        if (box->flag & RTGUI_TEXTBOX_DIGIT)
        {
            /* only input digit */
            if (!isdigit(chr))
            {
                /* exception: '.' and '-' */
                if (chr != '.' && chr != '-')return RT_FALSE;
                if (chr == '.' && strchr((char*)box->text, '.'))return RT_FALSE;

                if (chr == '-')
                {
                    if (length + chw > box->line_length) return RT_FALSE;

                    if (strchr((char*)box->text, '-'))
                    {
                        unsigned char *c;
                        for (c = &box->text[0]; c != &box->text[length]; c++)
                            *c = *(c + 1);
                        box->text[length] = '\0';
                        box->position --;
                        goto _exit;
                    }
                    else
                    {
                        unsigned char *c;
                        for (c = &box->text[length]; c != &box->text[0]; c--)
                            *c = *(c - 1);
                        box->text[0] = '-';
                        box->text[length + 1] = '\0';
                        box->position ++;
                        goto _exit;
                    }
                }
            }
        }

        if (length + chw > box->line_length)
            return RT_FALSE;

        if (TB_ABSPOS(box) <= length - 1)
        {
            unsigned char *c;

            for (c = &box->text[length + chw - 1];
                 c != &box->text[TB_ABSPOS(box)];
                 c -= 1)
                *c = *(c - chw);
        }

        if (chw == 1)
        {
            box->text[TB_ABSPOS(box)] = chr;
        }
        else if (chw == 2)
        {
            box->text[TB_ABSPOS(box)] = chr >> 8;
            box->text[TB_ABSPOS(box)+1] = chr & 0xFF;
        }
        else
        {
Exemple #26
0
static rt_bool_t rtgui_list_view_onmouse(struct rtgui_list_view* view, struct rtgui_event_mouse* emouse)
{
	rtgui_rect_t rect;

	/* calculate selected item */

	/* get physical extent information */
	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
	rtgui_widget_rect_to_device(RTGUI_WIDGET(view), &rect);

	if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
	{
		rt_uint16_t index;
		rt_uint16_t old_item;

		/* get old item */
		old_item = view->current_item;

		switch (view->flag)
		{
		case RTGUI_LIST_VIEW_LIST:
			index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());

			if ((index < view->items_count) && (index < view->page_items))
			{
				/* set selected item */
				view->current_item = (view->current_item/view->page_items) * view->page_items + index;
				if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
				{
					/* down event */
					rtgui_list_view_update_list(view, old_item);
				}
				else
				{
					/* up event */
					if (view->items[view->current_item].action != RT_NULL)
					{
						view->items[view->current_item].action(view->items[view->current_item].parameter);
					}
				}
			}
			break;

		case RTGUI_LIST_VIEW_ICON:
			{
				rt_uint16_t x, y;
				rt_uint16_t item_height, item_width;
				rt_ubase_t current_page;

				item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
				item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
				x = emouse->x - rect.x1;
				y = emouse->y - rect.y1;

				index = (y / item_height * view->col_items) + x / item_width;
				current_page = view->current_item / view->page_items;

				if ((index + (current_page * view->page_items) < view->items_count))
				{
					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
					{
						view->current_item = index + (current_page * view->page_items);

						/* down event */
						rtgui_list_view_update_icon(view, old_item);
					}
					else
					{
						/* up event */
						if (view->items[view->current_item].action != RT_NULL)
						{
							view->items[view->current_item].action(view->items[view->current_item].parameter);
						}
					}
				}
			}
			break;

		case RTGUI_LIST_VIEW_REPORT:
			break;
		}

		return RT_TRUE;
	}

	return RT_FALSE;
}
Exemple #27
0
static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_uint16_t old_item)
{
	struct rtgui_rect rect, item_rect, drawing_rect;
	rt_ubase_t c, r; /* col and row index */
	rt_ubase_t item_width, item_height;
	rtgui_image_t* image;
	struct rtgui_dc* dc;

	if ((view->items_count == 0) ||
		(old_item == view->current_item))
		return;

	if (old_item/view->page_items != view->current_item/view->page_items)
	{
		/* it's not a same page, update all */
		rtgui_widget_update(RTGUI_WIDGET(view));
		return;
	}

	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
	if (dc == RT_NULL) return;

	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);

	item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
	item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
	image = view->items[0].image;

	/* update old item */
	r = (old_item % view->page_items)/ view->col_items;
	c = (old_item % view->page_items)% view->col_items;
	item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
	item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
	item_rect.x2 = item_rect.x1 + item_width;
	item_rect.y2 = item_rect.y1 + item_height;
	rtgui_dc_fill_rect(dc, &item_rect);

	/* draw image */
	drawing_rect.x1 = drawing_rect.y1 = 0;
	drawing_rect.x2 = image->w;
	drawing_rect.y2 = image->h;
	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
	drawing_rect.y1 += 3; drawing_rect.y2 += 3;
	rtgui_image_blit(view->items[old_item].image, dc, &drawing_rect);

	/* draw text */
	item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
	item_rect.x1 += 3; item_rect.x2 -=3;
	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[old_item].name, 
		&drawing_rect);
	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
	rtgui_dc_draw_text(dc, view->items[old_item].name, &drawing_rect);

	/* update new item as selected */
	r = (view->current_item % view->page_items) / view->col_items;
	c = (view->current_item % view->page_items) % view->col_items;
	item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
	item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
	item_rect.x2 = item_rect.x1 + item_width;
	item_rect.y2 = item_rect.y1 + item_height;
	rtgui_theme_draw_selected(dc, &item_rect);

	/* draw image */
	drawing_rect.x1 = 0;
	drawing_rect.y1 = 3;
	drawing_rect.x2 = image->w;
	drawing_rect.y2 = 3 + image->h;

	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
	rtgui_image_blit(view->items[view->current_item].image, dc, &drawing_rect);

	/* draw text */
	item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
	item_rect.x1 += 3; item_rect.x2 -=3;
	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), 
		view->items[view->current_item].name, 
		&drawing_rect);
	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
	rtgui_dc_draw_text(dc, view->items[view->current_item].name, &drawing_rect);

	rtgui_dc_end_drawing(dc);
}
/* blit a dc to another dc */
static void rtgui_dc_buffer_blit(struct rtgui_dc *self, struct rtgui_point *dc_pt, struct rtgui_dc *dest, rtgui_rect_t *rect)
{
	int pitch;
	rt_uint16_t rect_width, rect_height;
	struct rtgui_rect _rect, *dest_rect;
    struct rtgui_point dc_point;
    struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;

    if (rtgui_dc_get_visible(dest) == RT_FALSE)
        return;

	/* use the (0,0) origin point */
    if (dc_pt == RT_NULL)
        dc_point = rtgui_empty_point;
    else
    {
        dc_point = *dc_pt;
    }

    rtgui_dc_get_rect(dest, &_rect);
	/* use the rect of dest dc */
	if (rect == RT_NULL)
	{
		dest_rect = &_rect;
	}
	else
    {
        dest_rect = rect;
        if (dest_rect->x1 > _rect.x2 || dest_rect->y1 > _rect.y2)
            return;
        if (dest_rect->x1 < 0)
        {
            if (-dest_rect->x1 > dc->width)
                return;
            dc_point.x += -dest_rect->x1;
            dest_rect->x1 = 0;
        }
        if (dest_rect->y1 < 0)
        {
            if (-dest_rect->y1 > dc->height)
                return;
            dc_point.y += -dest_rect->y1;
            dest_rect->y1 = 0;
        }
        if (dest_rect->x2 > _rect.x2)
            dest_rect->x2 = _rect.x2;
        if (dest_rect->y2 > _rect.y2)
            dest_rect->y2 = _rect.y2;
    }

    if (dc_point.x > dc->width || dc_point.y > dc->height)
        return;

	/* get the minimal width and height */
	rect_width  = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x);
	rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y);

    if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
    {
		int index;
        rt_uint8_t *line_ptr, *pixels;
        rtgui_blit_line_func blit_line;
		struct rtgui_graphic_driver *hw_driver;

		hw_driver = rtgui_graphic_driver_get_default();
        /* prepare pixel line */
		pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);

        if (hw_driver->bits_per_pixel == _dc_get_bits_per_pixel(dc))
        {
			if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
			{
				rt_uint8_t *hw_pixels;
				struct rtgui_dc_hw *hw;

				hw = (struct rtgui_dc_hw*)dest;

				/* NOTES: the rect of DC is the logic coordination.
				 * It should be converted to client
				 */
				if (dest_rect != &_rect)
				{
					/* use local rect */
					_rect = *dest_rect;
					dest_rect = &_rect;
				}
				rtgui_rect_moveto(dest_rect, hw->owner->extent.x1, hw->owner->extent.y1);

				pitch = rtgui_color_get_bpp(hw_driver->pixel_format) * rect_width;
				hw_pixels = (rt_uint8_t*)(hw_driver->framebuffer + dest_rect->y1 * hw_driver->pitch +
					dest_rect->x1 * rtgui_color_get_bpp(hw_driver->pixel_format));

				/* do the blit with memory copy */
				for (index = 0; index < rect_height; index ++)
				{
					rt_memcpy(hw_pixels, pixels, pitch);
					pixels += dc->pitch;
					hw_pixels += hw_driver->pitch;
				}
			}
			else
			{
	            /* it's the same bits per pixel, draw it directly */
	            for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index++)
	            {
	                dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, index, pixels);
					pixels += dc->pitch;
	            }
			}
        }
        else
        {
			struct rtgui_graphic_driver *hw_driver;

			hw_driver = rtgui_graphic_driver_get_default();

			if ((dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888) && (dest->type == RTGUI_DC_HW) &&
				(hw_driver->framebuffer != RT_NULL) &&
				(hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565))
			{
				/* do the fast ARGB to RGB565 blit */
				struct rtgui_blit_info info;
				struct rtgui_widget *owner;

				/* blit source */
				info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
				info.src_fmt = dc->pixel_format;
				info.src_h = rect_height;
				info.src_w = rect_width;
				info.src_pitch = dc->pitch;
				info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);

				owner = ((struct rtgui_dc_hw*)dest)->owner;

				/* blit destination */
				info.dst = (rt_uint8_t*)hw_driver->framebuffer;
				info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch +
                    (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format);
				info.dst_fmt = hw_driver->pixel_format;
				info.dst_h = rect_height;
				info.dst_w = rect_width;
				info.dst_pitch = hw_driver->pitch;
				info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);

				rtgui_blit(&info);
			}
			else
			{
	            /* get blit line function */
	            blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel), rtgui_color_get_bpp(dc->pixel_format));
	            /* calculate pitch */
	            pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
	            /* create line buffer */
	            line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel));

	            /* draw each line */
	            for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
	            {
	                /* blit on line buffer */
	                blit_line(line_ptr, (rt_uint8_t *)pixels, pitch);
	                pixels += dc->pitch;

	                /* draw on hardware dc */
	                dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, index, line_ptr);
	            }

	            /* release line buffer */
	            rtgui_free(line_ptr);
			}
        }
    }
	else if (dest->type == RTGUI_DC_BUFFER)
	{
		struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest;

		if (dest_dc->pixel_format == dc->pixel_format && dest_dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
		{
			int index;
			rt_uint8_t *pixels, *dest_pixels;

			/* get pitch */
			pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);

			pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);
			dest_pixels = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);

			for (index = 0; index < rect_height; index ++)
			{
				rt_memcpy(dest_pixels, pixels, pitch);
				pixels += dc->pitch;
				dest_pixels += dest_dc->pitch;
			}
		}
		else /* use rtgui_blit to handle buffer blit */
		{
			/* do the fast ARGB to RGB565 blit */
			struct rtgui_blit_info info;

			/* blit source */
			info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
			info.src_fmt = dc->pixel_format;
			info.src_h = rect_height;
			info.src_w = rect_width;
			info.src_pitch = dc->pitch;
			info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);

			/* blit destination */
			info.dst = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);
			info.dst_fmt = dest_dc->pixel_format;
			info.dst_h = rect_height;
			info.dst_w = rect_width;
			info.dst_pitch = dest_dc->pitch;
			info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_dc->pixel_format);

			rtgui_blit(&info);
		}
	}
}
Exemple #29
0
static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect)
{
    rt_uint16_t x, y, w, h;
    rtgui_color_t *ptr;
    struct rtgui_image_png *png;
    int fg_maxsample;
    int ialpha;
    float alpha;
    rtgui_color_t color;
    rtgui_color_t c, bgcolor;
    int fc[3], bc[3];
    struct rtgui_graphic_driver *hwdev = rtgui_graphic_get_device();

    RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL);
    RT_ASSERT(image->data != RT_NULL);

    png = (struct rtgui_image_png *) image->data;

	w = _UI_MIN(image->w, rtgui_rect_width(*rect));
	h = _UI_MIN(image->h, rtgui_rect_height(*rect));

    fg_maxsample = (1 << png->info_ptr->bit_depth) - 1;

    if (png->pixels != RT_NULL)
    {
        ptr = (rtgui_color_t *)png->pixels;
        bgcolor = RTGUI_DC_BC(dc);
        bc[0] = RTGUI_RGB_R(bgcolor);
        bc[1] = RTGUI_RGB_G(bgcolor);
        bc[2] = RTGUI_RGB_B(bgcolor);

        /* draw each point within dc */
        for (y = 0; y < h; y ++)
        {
            for (x = 0; x < w; x++)
            {
                c = *ptr;
                ialpha = RTGUI_RGB_A(c);
                if (ialpha == 0)
                {
                    /*
                     * Foreground image is transparent hear.
                     * If the background image is already in the frame
                     * buffer, there is nothing to do.
                     */
                }
                else if (ialpha == fg_maxsample)
                {
                    /*
                     * Copy foreground pixel to frame buffer.
                     */
                    rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, c);
                }
                else
                {
                    /* output = alpha * foreground + (1-alpha) * background */
                    /*
                     * Compositing is necessary.
                     * Get floating-point alpha and its complement.
                     * Note: alpha is always linear: gamma does not
                     * affect it.
                     */
                    fc[0] = RTGUI_RGB_R(c);
                    fc[1] = RTGUI_RGB_G(c);
                    fc[2] = RTGUI_RGB_B(c);

                    alpha = (float) ialpha / fg_maxsample;
                    color = RTGUI_RGB((rt_uint8_t)(fc[0] * alpha + bc[0] * (1 - alpha)),
                                      (rt_uint8_t)(fc[1] * alpha + bc[1] * (1 - alpha)),
                                      (rt_uint8_t)(fc[2] * alpha + bc[2] * (1 - alpha)));
                    rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, color);
                }
                /* move to next color buffer */
                ptr ++;
            }
        }
    }
    else
    {
        png_bytep row;
        png_bytep data;

        row = (png_bytep) rtgui_malloc(png_get_rowbytes(png->png_ptr, png->info_ptr));
        if (row == RT_NULL) return ;

        switch (png->info_ptr->color_type)
        {
		case PNG_COLOR_TYPE_RGB:
			for (y = 0; y < h; y++)
			{
				png_read_row(png->png_ptr, row, png_bytep_NULL);
				for (x = 0; x < w; x++)
				{
					data = &(row[x * 3]);
					rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1,
											  RTGUI_RGB(data[0], data[1], data[2]));
				}
			}
			break;
			
        case PNG_COLOR_TYPE_RGBA:
            for (y = 0; y < h; y++)
            {
                png_read_row(png->png_ptr, row, png_bytep_NULL);
                for (x = 0; x < w; x++)
                {
                    data = &(row[x * 4]);
                    if (data[3] != 0)
                    {
                        rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1,
                                                  RTGUI_ARGB(data[3], data[0], data[1], data[2]));
                    }
                }
            }

            break;

        case PNG_COLOR_TYPE_PALETTE:
            for (y = 0; y < h; y++)
            {
                png_read_row(png->png_ptr, row, png_bytep_NULL);
                for (x = 0; x < w; x++)
                {
                    data = &(row[x]);

                    rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1,
                                              RTGUI_ARGB(0, png->info_ptr->palette[data[0]].red,
                                                         png->info_ptr->palette[data[0]].green,
                                                         png->info_ptr->palette[data[0]].blue));
                }
            }

        default:
            break;
        };

        rtgui_free(row);
    }
}
Exemple #30
0
rt_bool_t demo_bitmap_showbox(struct rtgui_object* object, struct rtgui_event* event)
{
	rtgui_container_t *container;
	rtgui_widget_t *widget;
	
	RT_ASSERT(object != RT_NULL);

	container = RTGUI_CONTAINER(object);
	widget = RTGUI_WIDGET(object);

	if(event->type == RTGUI_EVENT_PAINT)
	{
		int w, h;
		rtgui_rect_t rect;
		struct rtgui_dc *dc;
		struct rtgui_image *image = bmpdt.showimg;
		/* 如果从其他标签切换到当前标签, image应该是RT_NULL, 重置它 */
		if(image == RT_NULL && bmpdt.image != RT_NULL)
		{
			image = bmpdt.image;
			bmpdt.scale = 1.0f;
			bmpdt.angle = 0.0f;
			rtgui_widget_get_rect(RTGUI_WIDGET(bmpdt.showbox), &bmpdt.lastrect);
			rtgui_rect_inflate(&bmpdt.lastrect, -RTGUI_WIDGET_BORDER(bmpdt.showbox));
		}

		dc = rtgui_dc_begin_drawing(widget);
		if (dc == RT_NULL)
			return RT_FALSE;
		
		rtgui_widget_get_rect(widget, &rect);
		/* 在绘制边框后, 再将rect缩小填充背景, 可以降低闪烁现象 */
		rtgui_dc_draw_border(dc, &rect, RTGUI_WIDGET_BORDER_STYLE(widget));
		rtgui_rect_inflate(&rect, -RTGUI_WIDGET_BORDER(widget));
		w = rtgui_rect_width(bmpdt.lastrect);
		h = rtgui_rect_height(bmpdt.lastrect);
		if(w > rtgui_rect_width(rect)) w = rtgui_rect_width(rect);
		if(h > rtgui_rect_height(rect)) h = rtgui_rect_height(rect);
		
		/* fill container with background */
		/*
		* 参数lastrect会记录上一次绘图所用区域
		* 每次重绘时,只需与lastrect比较,即可得知那些背景区域需要刷新
		* 例如当放大图片时,lastrect比当前绘图区小,所有无需更新背景区,
		* 当缩小图片时, 也仅需要更新绘图区比lastrect大的区域.
		*/
		if(image != RT_NULL)
		{	/* 减少不必要的绘图 */
			rtgui_rect_t rc;
			if(w > image->w)
			{
				rc.x1 = image->w;
				rc.y1 = bmpdt.lastrect.y1;
				rc.x2 = bmpdt.lastrect.x2;
				rc.y2 = (h > image->h) ? image->h : bmpdt.lastrect.y2;
				rtgui_dc_fill_rect(dc, &rc);
			}
			if(h > image->h)
			{
				rc.x1 = bmpdt.lastrect.x1;
				rc.y1 = image->h;
				rc.x2 = bmpdt.lastrect.x2;
				rc.y2 = bmpdt.lastrect.y2;
				rtgui_dc_fill_rect(dc, &rc);
			}
		}
		else
			rtgui_dc_fill_rect(dc, &bmpdt.lastrect);

		/* 将图像数据blit到画布上 */
		if (image != RT_NULL)
		{
			int value;
			rtgui_image_blit(image, dc, &rect);
			bmpdt.lastrect.x1 = bmpdt.lastrect.y1 = RTGUI_WIDGET_BORDER(bmpdt.showbox);

			if(image->w > rtgui_rect_width(rect))
				value = rtgui_rect_width(rect);
			else
				value = image->w;
			bmpdt.lastrect.x2 = bmpdt.lastrect.x1 + value;

			if(image->h > rtgui_rect_height(rect))
				value = rtgui_rect_height(rect);
			else
				value = image->h;
			bmpdt.lastrect.y2 = bmpdt.lastrect.y1 + value;
		}

		rtgui_dc_end_drawing(dc);
		return RT_FALSE;
	}
	return rtgui_container_event_handler(object, event);
}