Selaa lähdekoodia

add draw_round_rect, update radiobox widget implementation.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@298 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 vuotta sitten
vanhempi
commit
0ce439673d

+ 15 - 0
rtgui/common/dc.c

@@ -138,6 +138,21 @@ void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect)
 	rtgui_dc_draw_vline(dc, rect->x2 - 1, rect->y1, rect->y2);
 }
 
+void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect)
+{
+	int r = 3;
+
+	rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y1 + r, r, 180, 270);
+	rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y1 + r, r, 270, 360);
+	rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y2 - r, r, 90, 180);
+	rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y2 - r, r, 0, 90);
+
+	rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y1);
+	rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y2);
+	rtgui_dc_draw_vline(dc, rect->x1, rect->y1 + r, rect->y2 - r);
+	rtgui_dc_draw_vline(dc, rect->x2, rect->y1 + r, rect->y2 - r);
+}
+
 void rtgui_dc_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect)
 {
 	if (dc == RT_NULL) return;

+ 165 - 0
rtgui/common/rtgui_system.c

@@ -658,3 +658,168 @@ void rtgui_free(void* ptr)
 
 	rt_free(ptr);
 }
+
+#if 0
+/*
+ * read/write lock implementation
+ */
+struct rtgui_rwlock* rtgui_rwlock_create()
+{
+    struct rtgui_rwlock* rwlock;
+
+    rwlock = rtgui_malloc(sizeof(struct rtgui_rwlock));
+    if (rwlock != RT_NULL)
+    {
+        rwlock->stat = RTGUI_RWLOCK_UNLOCK;
+        rwlock->reader_count = 0;
+
+        rt_sem_init(&(rwlock->rd_lock), "rwr", 0, RT_IPC_FLAG_FIFO);
+        rt_sem_init(&(rwlock->wr_lock), "rww", 0, RT_IPC_FLAG_FIFO);
+    }
+
+    return rwlock;
+}
+
+rt_err_t rtgui_rwlock_delete(struct rtgui_rwlock* rwlock)
+{
+    RT_ASSERT(rwlock != RT_NULL);
+
+    rt_sem_detach(&(rwlock->rd_lock));
+    rt_sem_detach(&(rwlock->wr_lock));
+
+    rtgui_free(rwlock);
+
+	return RT_EOK;
+}
+
+rt_err_t rtgui_rwlock_read_take(struct rtgui_rwlock* rwlock, rt_int32_t timeout)
+{
+    rt_err_t result;
+    rt_ubase_t level;
+
+    RT_ASSERT(rwlock != RT_NULL);
+    level = rt_hw_interrupt_disable();
+    switch (rwlock->stat)
+    {
+        case RTGUI_RWLOCK_UNLOCK:
+            break;
+
+        case RTGUI_RWLOCK_READING:
+            if (rwlock->wr_lock.parent.suspend_thread_count > 0)
+            {
+                /* suspend read thread */
+                result = rt_sem_take(&rwlock->rd_lock, timeout);
+                if (result != RT_EOK)
+                {
+                    rt_hw_interrupt_enable(level);
+                    return result;
+                }
+            }
+            break;
+
+        case RTGUI_RWLOCK_WRITTING:
+            /* suspend read thread */
+            result = rt_sem_take(&(rwlock->rd_lock), timeout);
+            if (result != RT_EOK)
+            {
+                rt_hw_interrupt_enable(level);
+                return result;
+            }
+            break;
+    }
+
+    /* get rwlock */
+    rwlock->reader_count ++;
+    rwlock->stat = RTGUI_RWLOCK_READING;
+
+    rt_hw_interrupt_enable(level);
+}
+
+rt_err_t rtgui_rwlock_write_take(struct rtgui_rwlock* rwlock, rt_int32_t timeout)
+{
+    rt_err_t result;
+    rt_ubase_t level;
+
+    RT_ASSERT(rwlock != RT_NULL);
+
+    level = rt_hw_interrupt_disable();
+	rwlock->stat = RTGUI_RWLOCK_WRITTING;
+	result = rt_sem_take(&(rwlock->wr_lock), timeout);
+
+	if (result != RT_EOK)
+	{
+		if (rwlock->wr_lock.parent.suspend_thread_count == 0)
+		{
+			if (rwlock->reader_count > 0)
+				rwlock->stat = RTGUI_RWLOCK_READING;
+		}
+	}
+    rt_hw_interrupt_enable(level);
+
+	return result;
+}
+
+rt_err_t rtgui_rwlock_read_release(struct rtgui_rwlock* rwlock)
+{
+    rt_ubase_t level;
+
+    RT_ASSERT(rwlock != RT_NULL);
+
+    level = rt_hw_interrupt_disable();
+    switch (rwlock->stat)
+    {
+    case RTGUI_RWLOCK_UNLOCK:
+        ASSERT(0);
+        break;
+
+    case RTGUI_RWLOCK_READING:
+        rwlock->reader_count --;
+        if (rwlock->reader_count == 0)
+            rwlock->stat = RTGUI_RWLOCK_UNLOCK;
+        break;
+
+    case RTGUI_RWLOCK_WRITTING:
+        rwlock->reader_count --;
+
+        if (rwlock->reader_count == 0)
+        {
+            /* resume write */
+            rt_sem_release(&(rwlock->wr_lock));
+        }
+        break;
+    }
+    rt_hw_interrupt_enable(level);
+}
+
+rt_err_t rtgui_rwlock_write_release(struct rtgui_rwlock* rwlock)
+{
+    rt_err_t result;
+    rt_ubase_t level;
+
+    RT_ASSERT(rwlock != RT_NULL);
+
+    level = rt_hw_interrupt_disable();
+	result = rt_sem_release(&(rwlock->wr_lock));
+
+	if ((result == RT_EOK) && (rwlock->wr_lock.parent.suspend_thread_count == 0))
+	{
+		rt_uint32_t index, reader_thread_count;
+
+		reader_thread_count = rwlock->rd_lock.parent.suspend_thread_count;
+		if (reader_thread_count > 0)
+		{
+			rwlock->stat = RTGUI_RWLOCK_READING;
+
+			/* resume all reader thread */
+			for (index = 0; index < reader_thread_count; index ++)
+			{
+				rt_sem_release(&(rwlock->rd_lock));
+			}
+		}
+		else rwlock->stat = RTGUI_RWLOCK_UNLOCK;
+	}
+	rt_hw_interrupt_enable(level);
+
+	return result;
+}
+#endif

+ 109 - 1
rtgui/common/rtgui_theme.c

@@ -470,7 +470,7 @@ void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox)
 	rtgui_dc_end_drawing(dc);
 }
 
-void rtgui_theme_draw_checkbox(rtgui_checkbox_t* checkbox)
+void rtgui_theme_draw_checkbox(struct rtgui_checkbox* checkbox)
 {
 	struct rtgui_dc* dc;
 	struct rtgui_rect rect, box_rect;
@@ -528,6 +528,114 @@ void rtgui_theme_draw_checkbox(rtgui_checkbox_t* checkbox)
 	return;
 }
 
+void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox)
+{
+	struct rtgui_dc* dc;
+	struct rtgui_rect rect, item_rect;
+	rt_size_t item_size, bord_size, index;
+
+	/* begin drawing */
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(radiobox));
+	if (dc == RT_NULL) return;
+
+	/* get widget rect */
+	rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	item_size = radiobox->item_size;
+	/* get board size */
+	if (radiobox->orient == RTGUI_VERTICAL)
+		bord_size = item_size;
+	else
+	{
+		rtgui_font_get_metrics(rtgui_dc_get_font(dc), "H", &item_rect);
+		bord_size = rtgui_rect_height(item_rect);
+	}
+
+	/* draw box */
+	rtgui_rect_inflate(&rect, -bord_size/2);
+	rtgui_dc_draw_round_rect(dc, &rect);
+	rtgui_rect_inflate(&rect, bord_size/2);
+	if (radiobox->text != RT_NULL)
+	{
+		struct rtgui_rect text_rect;
+
+		/* draw group text */
+		rtgui_font_get_metrics(rtgui_dc_get_font(dc), radiobox->text, &text_rect);
+		rtgui_rect_moveto(&text_rect, rect.x1 + 5, rect.y1);
+		rtgui_dc_fill_rect(dc, &text_rect);
+		rtgui_dc_draw_text(dc, radiobox->text, &text_rect);
+	}
+
+	/* set init item rect */
+	item_rect = rect;
+	rtgui_rect_inflate(&item_rect, - bord_size);
+
+	if (radiobox->orient == RTGUI_VERTICAL)
+	{
+		/* set the first text rect */
+		item_rect.y2 = item_rect.y1 + item_size;
+
+		/* draw each radio button */
+		for (index = 0; index < radiobox->item_count; index ++)
+		{
+			if (item_rect.y2 > rect.y2 - item_size) break;
+
+			/* draw radio */
+			if (radiobox->item_selection == index)
+			{
+				rtgui_dc_draw_focus_rect(dc, &item_rect);
+				rtgui_dc_fill_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2);
+			}
+			else
+			{
+				rtgui_dc_draw_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2);
+			}
+
+			/* draw text */
+			item_rect.x1 += item_size + 3;
+			rtgui_dc_draw_text(dc, radiobox->items[index], item_rect);
+			item_rect.x1 -= item_size + 3;
+
+			item_rect.y1 += item_size;
+			item_rect.y2 += item_size;
+		}
+	}
+	else
+	{
+		/* set the first text rect */
+		item_rect.x2 = item_rect.x1 + item_size;
+
+		/* draw each radio button */
+		for (index = 0; index < radiobox->item_count; index ++)
+		{
+			if (item_rect.x2 > rect.x2 - item_size) break;
+
+			/* draw radio */
+			if (radiobox->item_selection == index)
+			{
+				rtgui_dc_draw_focus_rect(dc, &item_rect);
+				rtgui_dc_fill_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2);
+			}
+			else
+			{
+				rtgui_dc_draw_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2);
+			}
+
+			/* draw text */
+			item_rect.x1 += item_size + 3;
+			rtgui_dc_draw_text(dc, radiobox->items[index], item_rect);
+			item_rect.x1 -= item_size + 3;
+
+			item_rect.x1 += item_size;
+			item_rect.x2 += item_size;
+		}
+	}
+
+	/* end drawing */
+	rtgui_dc_end_drawing(dc);
+}
+
 void rtgui_theme_draw_slider(struct rtgui_slider* slider)
 {
 	/* draw button */

+ 1 - 0
rtgui/include/rtgui/dc.h

@@ -104,6 +104,7 @@ void rtgui_dc_get_rect(struct rtgui_dc*dc, rtgui_rect_t* rect);
 
 void rtgui_dc_draw_line (struct rtgui_dc* dc, int x1, int y1, int x2, int y2);
 void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect);
+void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect);
 
 void rtgui_dc_draw_text (struct rtgui_dc* dc, const rt_uint8_t* text, struct rtgui_rect* rect);
 

+ 2 - 0
rtgui/include/rtgui/rtgui_theme.h

@@ -22,6 +22,7 @@
 #include <rtgui/widgets/textbox.h>
 #include <rtgui/widgets/iconbox.h>
 #include <rtgui/widgets/checkbox.h>
+#include <rtgui/widgets/radiobox.h>
 #include <rtgui/widgets/slider.h>
 #include <rtgui/widgets/progressbar.h>
 #include <rtgui/widgets/staticline.h>
@@ -38,6 +39,7 @@ void rtgui_theme_draw_label(rtgui_label_t* label);
 void rtgui_theme_draw_textbox(rtgui_textbox_t* box);
 void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox);
 void rtgui_theme_draw_checkbox(rtgui_checkbox_t* checkbox);
+void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox);
 void rtgui_theme_draw_slider(struct rtgui_slider* slider);
 void rtgui_theme_draw_progressbar(struct rtgui_progressbar* bar);
 void rtgui_theme_draw_staticline(struct rtgui_staticline* staticline);

+ 13 - 5
rtgui/include/rtgui/widgets/radiobox.h

@@ -7,19 +7,25 @@
 /** Gets the type of a radiobox */
 #define RTGUI_RADIOBOX_TYPE       (rtgui_radiobox_type_get())
 /** Casts the object to an rtgui_radiobox */
-#define RTGUI_SLIDER(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_RADIOBOX_TYPE, rtgui_radiobox_t))
+#define RTGUI_RADIOBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_RADIOBOX_TYPE, rtgui_radiobox_t))
 /** Checks if the object is an rtgui_radiobox */
-#define RTGUI_IS_SLIDER(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_RADIOBOX_TYPE))
+#define RTGUI_IS_RADIOBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_RADIOBOX_TYPE))
 
 struct rtgui_radiobox
 {
 	struct rtgui_widget parent;
 
 	/* widget private data */
-	int orient;
+	char* text; /* radio box label */
 
-	char* items;
-	int item_count, item_selection;
+	/* box orient */
+	rt_uint8_t orient;
+
+	/* item size */
+	rt_uint8_t item_size;
+
+	char** items;
+	rt_uint16_t item_count, item_selection;
 };
 typedef struct rtgui_radiobox rtgui_radiobox_t;
 
@@ -33,4 +39,6 @@ int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox);
 
 rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
 
+void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation);
+
 #endif

+ 42 - 62
rtgui/widgets/radiobox.c

@@ -42,6 +42,24 @@ static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui
 	if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
 		event->button & RTGUI_MOUSE_BUTTON_LEFT)
 	{
+		int bord_size;
+		struct rtgui_rect rect;
+
+		/* get widget rect */
+		rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
+
+		/* get board size */
+		if (radiobox->orient == RTGUI_VERTICAL)
+			bord_size = radiobox->item_size;
+		else
+		{
+			struct rtgui_rect bord_rect;
+			
+			rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect);
+			bord_size = rtgui_rect_height(bord_rect);
+		}
+		rtgui_rect_inflate(&rect, - bord_size);
+
 		if (radiobox->orient == RTGUI_VERTICAL)
 		{
 		}
@@ -53,68 +71,6 @@ static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui
 	}
 }
 
-void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox)
-{
-	struct rtgui_dc* dc;
-	struct rtgui_rect rect, item_rect, radio_rect;
-	rt_size_t item_height;
-
-	/* begin drawing */
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(label));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(label), &rect);
-    rtgui_dc_fill_rect(dc, &rect);
-
-    rtgui_dc_get_text_metrix(dc, "H", &item_rect);
-    item_height = rtgui_rect_height(item_rect);
-    radio_rect.x1 = 0; radio_rect.y1 = 0;
-    radio_rect.x2 = radio_rect.x1 + item_height;
-    radio_rect.y2 = radio_rect.y1 + item_height;
-
-    /* draw box */
-    rtgui_rect_inflat(&rect, -3);
-    rtgui_dc_draw_round_rect(dc, &rect);
-    if (radiobox->text != RT_NULL)
-    {
-        /* draw group text */
-        rtgui_dc_get_text_metrix(dc, radiobox->text, &item_rect);
-        rtgui_rect_moveto(&item_rect, rect.x1 + 5, rect.y1);
-        rtgui_dc_fill_rect(dc, &item_rect);
-
-        rtgui_dc_draw_text(dc, radiobox->text, &item_rect);
-    }
-
-    /* set the first text rect */
-    item_rect = rect;
-    item_rect.x1 += 5;
-    item_rect.y1 += item_height;
-    item_rect.y2 = item_rect.y1 + item_height;
-
-    /* draw each radio button */
-    for (index = 0; index < radiobox->item_count; index ++)
-    {
-        if (text_rect.y2 > rect.y2 - item_height) break;
-
-        /* draw radio */
-        rtgui_dc_draw_circyle(dc, );
-        if (radiobox->item_selection == index)
-        {
-            rtgui_dc_draw_focus_rect(dc, );
-            rtgui_dc_fill_circyle(dc, );
-        }
-
-        /* draw text */
-        rtgui_dc_draw_text(dc, radiobox->items[index], text_rect);
-
-        text_rect.y1 += item_height;
-        text_rect.y2 += item_height;
-    }
-
-    /* end drawing */
-	rtgui_dc_end_drawing(dc);
-}
-
 rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
 {
 	struct rtgui_radiobox* radiobox = (struct rtgui_radiobox*)widget;
@@ -184,6 +140,30 @@ struct rtgui_radiobox* rtgui_radiobox_create(int orient, char** radio_items, int
 
 		/* set proper of control */
 		rtgui_radiobox_set_orientation(radiobox, orient);
+		if (orient == RTGUI_VERTICAL)
+		{
+			struct rtgui_rect rect;
+			rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect);
+
+			radiobox->item_size = rtgui_rect_height(rect);
+		}
+		else
+		{
+			int index;
+			struct rtgui_font* font;
+			struct rtgui_rect rect;
+
+			/* set init item size */
+			radiobox->item_size = 0;
+			
+			font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox));
+			for (index = 0; index < number; index ++)
+			{
+				rtgui_font_get_metrics(font, radio_items[index], &rect);
+				if (rtgui_rect_width(rect) > radiobox->item_size)
+					radiobox->item_size = rtgui_rect_width(rect);
+			}
+		}
 	}
 
 	return radiobox;