static void _rtgui_listctrl_scrollbar_onmouse(struct rtgui_listctrl* ctrl, struct rtgui_event_mouse* mouse) { rtgui_rect_t rect; rt_uint32_t height, y1; rt_uint16_t old_item; /* get scrollbar rect */ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); height = rtgui_rect_height(rect); height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items); y1 = (ctrl->current_item / ctrl->page_items) * height; rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height; rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect); old_item = ctrl->current_item; if (mouse->y < rect.y1) { if (ctrl->current_item - ctrl->page_items >= 0) ctrl->current_item -= ctrl->page_items; rtgui_listctrl_update_current(ctrl, old_item); } else if (mouse->y > rect.y2) { if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1) ctrl->current_item += ctrl->page_items; else ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items; rtgui_listctrl_update_current(ctrl, old_item); } }
static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct rtgui_dc* dc) { rtgui_rect_t rect; rt_uint32_t height, y1; /* get scrollbar rect */ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); rtgui_dc_fill_rect(dc, &rect); height = rtgui_rect_height(rect); height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items); y1 = (ctrl->current_item / ctrl->page_items) * height; rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height; rtgui_theme_draw_selected(dc, &rect); }
rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) { struct rtgui_listctrl* ctrl = RT_NULL; ctrl = RTGUI_LISTCTRL(widget); switch (event->type) { case RTGUI_EVENT_PAINT: _rtgui_listctrl_ondraw(ctrl); return RT_FALSE; case RTGUI_EVENT_RESIZE: { struct rtgui_event_resize* resize; resize = (struct rtgui_event_resize*)event; /* recalculate page items */ ctrl->page_items = resize->h / (2 + rtgui_theme_get_selected_height()); } break; case RTGUI_EVENT_MOUSE_BUTTON: { rtgui_rect_t rect; struct rtgui_event_mouse* emouse; emouse = (struct rtgui_event_mouse*)event; /* get scrollbar rect */ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect); if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) { _rtgui_listctrl_scrollbar_onmouse(ctrl, emouse); return RT_TRUE; } /* calculate selected item */ /* get physical extent information */ _rtgui_listctrl_get_rect(ctrl, &rect); rtgui_widget_rect_to_device(widget, &rect); if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && (ctrl->items_count > 0)) { rt_uint16_t index; index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height()); /* set focus */ rtgui_widget_focus(widget); { struct rtgui_rect rect; struct rtgui_dc* dc; dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl)); if (dc != RT_NULL) { /* get widget rect */ rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect); /* update focus border */ rect.x2 -= 1; rect.y2 -= 1; rtgui_dc_end_drawing(dc); } } if ((index < ctrl->page_items) && (ctrl->current_item/ctrl->page_items)* ctrl->page_items + index < ctrl->items_count) { rt_uint16_t old_item; old_item = ctrl->current_item; /* set selected item */ ctrl->current_item = (ctrl->current_item/ctrl->page_items) * ctrl->page_items + index; if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN) { /* down event */ rtgui_listctrl_update_current(ctrl, old_item); } else { /* up event */ if (ctrl->on_item != RT_NULL) { ctrl->on_item(RTGUI_WIDGET(ctrl), RT_NULL); } } } } return RT_TRUE; } case RTGUI_EVENT_KBD: { struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; if ((ekbd->type == RTGUI_KEYDOWN) && (ctrl->items_count > 0)) { rt_uint16_t old_item; old_item = ctrl->current_item; switch (ekbd->key) { case RTGUIK_LEFT: if (ctrl->current_item - ctrl->page_items >= 0) ctrl->current_item -= ctrl->page_items; rtgui_listctrl_update_current(ctrl, old_item); return RT_FALSE; case RTGUIK_UP: if (ctrl->current_item > 0) ctrl->current_item --; rtgui_listctrl_update_current(ctrl, old_item); return RT_FALSE; case RTGUIK_RIGHT: if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1) ctrl->current_item += ctrl->page_items; else { if ((((ctrl->current_item/ctrl->page_items) + 1) * ctrl->page_items) < ctrl->items_count - 1) ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items; } rtgui_listctrl_update_current(ctrl, old_item); return RT_FALSE; case RTGUIK_DOWN: if (ctrl->current_item < ctrl->items_count - 1) ctrl->current_item ++; rtgui_listctrl_update_current(ctrl, old_item); return RT_FALSE; case RTGUIK_RETURN: if (ctrl->on_item != RT_NULL) { ctrl->on_item(RTGUI_WIDGET(ctrl), RT_NULL); } return RT_FALSE; default: break; } } } return RT_FALSE; } /* use ctrl event handler */ return rtgui_widget_event_handler(widget, event); }