123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /*
- * File : box.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2009-10-16 Bernard first version
- */
- #include <rtgui/dc.h>
- #include <rtgui/widgets/box.h>
- static void _rtgui_box_constructor(rtgui_box_t *box)
- {
- /* init widget and set event handler */
- rtgui_object_set_event_handler(RTGUI_OBJECT(box), RT_NULL);
- /* set proper of control */
- box->orient = RTGUI_HORIZONTAL;
- box->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
- box->container = RT_NULL;
- }
- DEFINE_CLASS_TYPE(box, "box",
- RTGUI_OBJECT_TYPE,
- _rtgui_box_constructor,
- RT_NULL,
- sizeof(struct rtgui_box));
- struct rtgui_box* rtgui_box_create(int orientation, int border_size)
- {
- struct rtgui_box* box;
- box = (struct rtgui_box*) rtgui_object_create (RTGUI_BOX_TYPE);
- if (box != RT_NULL)
- {
- box->orient = orientation;
- box->border_size = border_size;
- }
- return box;
- }
- static void rtgui_box_layout_vertical(rtgui_box_t* box)
- {
- rtgui_list_t *node;
- rt_int32_t box_width;
- rt_int32_t space_count;
- rt_int32_t next_x, next_y;
- rt_int32_t total_height, space_height;
- struct rtgui_event_resize size_event;
- struct rtgui_widget *container_widget;
-
- /* prepare the resize event */
- RTGUI_EVENT_RESIZE_INIT(&size_event);
- container_widget = RTGUI_WIDGET(box->container);
- /* find spaces */
- space_count = 0;
- total_height = 0;
- space_height = 0;
- rtgui_list_foreach(node, &(box->container->children))
- {
- rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
- if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++;
- else total_height += widget->mini_height;
- }
- /* calculate the height for each spaces */
- if (space_count != 0)
- {
- space_height = (rtgui_rect_height(container_widget->extent) - total_height - (box->border_size << 1)) / space_count;
- }
- /* init (x, y) and box width */
- next_x = container_widget->extent.x1 + box->border_size;
- next_y = container_widget->extent.y1 + box->border_size;
- box_width = rtgui_rect_width(container_widget->extent) - (box->border_size << 1);
- /* layout each widget */
- rtgui_list_foreach(node, &(box->container->children))
- {
- rtgui_rect_t *rect;
- rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
- /* get extent of widget */
- rect = &(widget->extent);
- /* reset rect */
- rtgui_rect_moveto(rect, -rect->x1, -rect->y1);
- rect->x2 = widget->mini_width;
- rect->y2 = widget->mini_height;
- /* left in default */
- rtgui_rect_moveto(rect, next_x, next_y);
- if (widget->align & RTGUI_ALIGN_EXPAND)
- {
- /* expand on horizontal */
- rect->x2 = rect->x1 + (rt_int16_t)box_width;
- }
- if (widget->align & RTGUI_ALIGN_CENTER_VERTICAL)
- {
- /* center */
- rt_uint32_t mid;
- mid = box_width - rtgui_rect_width(*rect);
- mid = mid /2;
- rect->x1 = next_x + mid;
- rect->x2 = next_x + box_width - mid;
- }
- else if (widget->align & RTGUI_ALIGN_RIGHT)
- {
- /* right */
- rect->x1 = next_x + box_width - rtgui_rect_width(*rect);
- rect->x2 = next_x + box_width;
- }
- if (widget->align & RTGUI_ALIGN_STRETCH)
- {
- rect->y2 = rect->y1 + space_height;
- }
- /* process resize event */
- size_event.x = rect->x1;
- size_event.y = rect->y1;
- size_event.w = rect->x2 - rect->x1;
- size_event.h = rect->y2 - rect->y1;
- RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
- &size_event.parent);
- /* point to next height */
- next_y = rect->y2 + box->border_size;
- }
- }
- static void rtgui_box_layout_horizontal(rtgui_box_t* box)
- {
- rtgui_list_t *node;
- rt_int32_t box_height;
- rt_int32_t space_count;
- rt_int32_t next_x, next_y;
- rt_int32_t total_width, space_width;
- struct rtgui_event_resize size_event;
- struct rtgui_widget *container_widget;
- /* prepare the resize event */
- RTGUI_EVENT_RESIZE_INIT(&size_event);
- container_widget = RTGUI_WIDGET(box->container);
- /* find spaces */
- space_count = 0;
- total_width = 0;
- space_width = 0;
- rtgui_list_foreach(node, &(box->container->children))
- {
- rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
- if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++;
- else total_width += widget->mini_width;
- }
- if (space_count != 0)
- {
- /* calculate the height for each spaces */
- space_width = (rtgui_rect_width(container_widget->extent) - total_width) / space_count;
- }
- /* init (x, y) and box height */
- next_x = container_widget->extent.x1 + box->border_size;
- next_y = container_widget->extent.y1 + box->border_size;
- box_height = rtgui_rect_height(container_widget->extent) - (box->border_size << 1);
- /* layout each widget */
- rtgui_list_foreach(node, &(box->container->children))
- {
- rtgui_rect_t *rect;
- rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
- /* get extent of widget */
- rect = &(widget->extent);
- /* reset rect */
- rtgui_rect_moveto(rect, -rect->x1, -rect->y1);
- rect->x2 = widget->mini_width;
- rect->y2 = widget->mini_height;
- /* top in default */
- rtgui_rect_moveto(rect, next_x, next_y);
- if (widget->align & RTGUI_ALIGN_EXPAND)
- {
- /* expand on vertical */
- rect->y2 = rect->y1 + box_height;
- }
- if (widget->align & RTGUI_ALIGN_CENTER_HORIZONTAL)
- {
- /* center */
- rt_uint32_t mid;
- mid = box_height - rtgui_rect_height(*rect);
- mid = mid /2;
- rect->y1 = next_y + mid;
- rect->y2 = next_y + box_height - mid;
- }
- else if (widget->align & RTGUI_ALIGN_RIGHT)
- {
- /* right */
- rect->y1 = next_y + box_height - rtgui_rect_height(*rect);
- rect->y2 = next_y + box_height;
- }
- if (widget->align & RTGUI_ALIGN_STRETCH)
- {
- rect->x2 = rect->x1 + space_width;
- }
- /* process resize event */
- size_event.x = rect->x1;
- size_event.y = rect->y1;
- size_event.w = rect->x2 - rect->x1;
- size_event.h = rect->y2 - rect->y1;
- RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
- &size_event.parent);
- /* point to next width */
- next_x = rect->x2 + box->border_size;
- }
- }
- void rtgui_box_layout(rtgui_box_t* box)
- {
- RT_ASSERT(box != RT_NULL);
- if (box->container == RT_NULL) return;
- if (box->orient & RTGUI_VERTICAL)
- {
- rtgui_box_layout_vertical(box);
- }
- else
- {
- rtgui_box_layout_horizontal(box);
- }
- /* update box and its children clip */
- if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box->container)))
- {
- rtgui_widget_update_clip(RTGUI_WIDGET(box->container));
- }
- }
|