si_t application_widget_absolute_area (struct widget * w, struct rectangle * result) { struct object * self, * parent; struct rectangle temp, parent_area; si_t flag = 0; *result = w->area; /* windows always use absolute coordinates. */ if(w->is_window) { return 0; } parent_area.x = 0; parent_area.y = 0; temp.x = w->area.x; temp.y = w->area.y; temp.width = w->area.width; temp.height = w->area.height; self = OBJECT_POINTER(w); while((parent = object_parent(self)) != NULL) { parent_area.width = WIDGET_POINTER(parent)->area.width; parent_area.height = WIDGET_POINTER(parent)->area.height; if(area_intersection(&parent_area, &temp, result) == -1) { flag = 1; break; } temp.x = (result->x += WIDGET_POINTER(parent)->area.x); temp.y = (result->y += WIDGET_POINTER(parent)->area.y); temp.width = result->width; temp.height = result->height; self = parent; if(WIDGET_POINTER(parent)->is_window) { break; } } if(flag == 1) { return -1; } else { return 0; } }
si_t panel_default_mouse_release(struct panel* pnl , union message * msg) { /* panel_event_in_which_widget(pnl, msg);*/ si_t flag = 0; struct widget * wgt; struct rectangle area; struct object * tree, *node ; tree = OBJECT_POINTER(pnl); node = tree->rchild; while(node != NULL) { widget_absolute_area(WIDGET_POINTER(node), &area); if(point_in_area(&(msg->mouse.cursor_position), &area)) { wgt = (struct widget*)node; wgt->callback(wgt, msg); flag = 1; break; } node = object_tree_iterator_decrement(tree,node); } if(flag == 0) { /* * panel doesn't have children. * so ,do nothing * */ } return 1; }
struct tab* tab_init(void) { struct tab * addr; /* 分配存储空间 */ addr = (struct tab *)malloc(sizeof(struct tab)); if(addr == NULL) { EGUI_PRINT_SYS_ERROR("fail to malloc"); return NULL; } if(NULL == (addr = widget_init_common(WIDGET_POINTER(addr), 0))) { return NULL; } /* struct tab 的成员 */ addr->name = "struct tab"; /* 用全局样式对象初始化tab样式 */ tab_init_with_default_style(addr); addr->border_size = 0; addr->header = tab_header_init(); addr->header->parent_tab = addr; object_attach_child(OBJECT_POINTER(addr), OBJECT_POINTER(addr->header)); return addr; }
si_t panel_default_widget_repaint(struct panel* pnl , union message * msg) { struct rectangle area; /* 绘制panel本身的区域 */ widget_absolute_area( WIDGET_POINTER( pnl ), &area ); set_area(pnl->gd,area.x,area.y,area.width,area.height); set_color(pnl->gd, pnl->back_color.r, pnl->back_color.g, pnl->back_color.b, pnl->back_color.a); fill_rectangle(pnl->gd, area.x , area.y, area.width, area.height); /* 绘制panel子控件的区域 */ /* tree = OBJECT_POINTER(pnl); node = tree->rchild; while(node != NULL) { printf("%d ",i++); wgt = (struct widget*)node; widget_absolute_area(wgt,&area); printf("child_area(%d,%d,%d,%d) ",area.x, area.y,area.width,area.height); wgt->callback(wgt, msg); node = object_tree_iterator_decrement(tree,node); } */ return 1; }
void * panel_init(si_t id) { struct panel * addr; /* 分配存储空间 */ addr = (struct panel *)malloc(sizeof(struct panel)); if(addr == NULL) { EGUI_PRINT_SYS_ERROR("fail to malloc"); return NULL; } if(!(addr=widget_init_common(WIDGET_POINTER(addr), id))) { return NULL; } addr->name = "struct panel"; /* 用全局样式对象初始化panel样式 */ panel_init_with_default_style(addr); /* 默认的回调函数 */ addr->callback = panel_default_callback ; return addr; }
si_t panel_exit(struct panel * i) { /* vector_exit( &(i->widget_vector) ); */ return widget_exit(WIDGET_POINTER(i)); }
extern void text_line_register_move_handler(struct text_line* t, struct widget* w, si_t event, void(* handler)(struct widget*, struct widget*, si_t)) { struct text_line_subscribe_info si; si.subscriber = w; si.publisher = WIDGET_POINTER(t); si.event = event; si.handler = handler; list_push_back(&t->subscribe_info_list, &si, sizeof(struct text_line_subscribe_info)); }
void spinbox_register_move_handler(struct spinbox *pub, struct widget *sub, si_t event, widget_event_handler handler) { struct widget_subscribe_info si; si.subscriber = sub; si.publisher = WIDGET_POINTER(pub); si.event = event; si.handler = handler; list_push_back(&pub->subscribe_info_list, &si, sizeof(si)); }
int main() { si_t video_access_mode = VIDEO_ACCESS_MODE_BUFFER; si_t app_type = APPLICATION_TYPE_NORMAL; struct window * w; struct scroll_bar* s; struct label* l; char show[25]; /* 初始化用户应用程序 */ application_init(video_access_mode, app_type, "scroll_bar"); /* 申请窗口 */ w = window_init("window with scroll_bar"); /* 申请失败 */ if(w == NULL) { application_exit(); return -1; } window_set_bounds(w, 300, 100, 448, 200); s = scroll_bar_init(1, 400, 20); /* 申请失败 */ if(s == NULL) { application_exit(); return -1; } scroll_bar_set_bounds(s, 428, 0, 20, 200); l = label_init(show); /* 申请失败 */ if(l == NULL) { application_exit(); return -1; } label_set_bounds(l, 10, 40, 400, 20); sprintf(show, "not started"); scroll_bar_register_move_handler(s, WIDGET_POINTER(l), SCROLL_BAR_EVENT_ALL, label_handler); object_attach_child(OBJECT_POINTER(w), OBJECT_POINTER(s)); object_attach_child(OBJECT_POINTER(w), OBJECT_POINTER(l)); /* 添加顶层窗口 */ application_add_window(NULL, w); /* 设置主窗口 */ application_set_main_window(w); /* 运行 */ application_exec(); return 0; }
/** * traverse the whole window vector and widget tree increamentally * * @param do_for_each_widget: function pointer which uses the each widget as parameter * @param msg: pointer to message * @return: NULL if traversal all, otherwise returns the specific widget that stopped the traversal **/ static struct widget* application_widgets_for_each_increament(struct widget*(*do_for_each_widget)(struct widget*, union message*), union message* msg) { int n, i; struct object* tree, *node; n = vector_size(&(global_application.window_vector)); for(i = 0; i != n; ++ i) { tree = vector_at(&(global_application.window_vector), i); node = tree->lchild; while(node != NULL) { if(do_for_each_widget(WIDGET_POINTER(node), msg)) return WIDGET_POINTER(node); node = object_tree_iterator_increment(tree, node); } } return NULL; }
static si_t handle_window_activate (union message * msg) { struct object* node; si_t n = 0, i = 0; node = OBJECT_POINTER(application_widgets_for_each_increament(do_find_window, msg)); if(node == NULL) { return 0; } object_move_first(node); if(global_application.focus != NULL) { dispatch_msg_to_subchilds(node, MESSAGE_TYPE_WINDOW_DEACTIVATE); } global_application.focus = WINDOW_POINTER(node); if(WIDGET_POINTER(node)->callback != NULL) { WIDGET_POINTER(node)->callback(node, msg); } dispatch_msg_to_subchilds(node, MESSAGE_TYPE_WIDGET_REPAINT); /** * 次序提前 **/ node = object_get_root(node)->parent; n = vector_size(&global_application.window_vector); for(i = 0; i < n; ++ i) { if(vector_at(&global_application.window_vector, i) == node) { vector_move_back(&global_application.window_vector, i); break; } } return 0; }
/* 一般用户并不需要调用这个 用户应用程序退出之后,application 会释放这个控件所占的空间。 而窗口管理程序会释放所有资源,包括申请的每个图形设备。 */ si_t spinbox_exit(struct spinbox * b) { list_exit(&b->subscribe_info_list); text_line_exit(b->text_number); button_exit(b->button_up); button_exit(b->button_down); return widget_exit(WIDGET_POINTER(b)); }
/** * dispatch msg to all subchild of a widget * * @param node: the widget * @param type: msg type * @return: 0 **/ static si_t dispatch_msg_to_subchilds(struct object* node, int type) { struct object* n, *t, *parent; /** * change the structure of the tree just for this **/ n = node; t = n->parent; parent = t->parent; t->parent = n; n = object_tree_l_most_node(t); while(n != NULL) { union message msg; /** * pack the message **/ if(type == MESSAGE_TYPE_WINDOW_DEACTIVATE) { msg.base.type = MESSAGE_TYPE_WINDOW_DEACTIVATE; } else if(type == MESSAGE_TYPE_WIDGET_REPAINT) { struct widget* w = WIDGET_POINTER(n); msg.widget_repaint.type = MESSAGE_TYPE_WIDGET_REPAINT; msg.widget_repaint.area = w->area; } else if(type == MESSAGE_TYPE_WINDOW_MINIMIZE || type == MESSAGE_TYPE_WINDOW_RESTORE) { msg.base.window_descriptor = WINDOW_POINTER(n)->descriptor; } if(WIDGET_POINTER(n)->callback != NULL) WIDGET_POINTER(n)->callback(n, &msg); n = object_tree_iterator_increment(t, n); } t->parent = parent; return 0; }
si_t shortcut_default_widget_show(struct shortcut* sh , union message * msg) { struct rectangle area; NOT_USED(msg); application_widget_absolute_area(WIDGET_POINTER(sh), &area); set_area( sh->gd, area.x, area.y, area.width, area.height ); update( sh->gd ); return 0; }
/** * @brief 用panel全局样式对象初始化panel对象 * * @param style panel样式对象指针 * @param p panel指针 * * @return 成功返回0,否则返回-1 **/ static si_t panel_init_with_default_style(struct panel * p) { char *config_path = get_config_path("panel.cfg"); si_t res = widget_init_with_default_style(config_path, WIDGET_POINTER(p), &panel_default_style.common, NULL, 0); free(config_path); return res; }
/** * @brief 用tab全局样式对象初始化tab对象 * * @param style tab样式对象指针 * @param b tab指针 * * @return 成功返回0,否则返回-1 **/ static si_t tab_init_with_default_style(struct tab * b) { char *config_path = get_config_path("tab.cfg"); si_t res = widget_init_with_default_style(config_path, WIDGET_POINTER(b), &tab_default_style.common, NULL, 0); free(config_path); return res; }
void spinbox_set_bounds(struct spinbox * b, si_t x, si_t y, si_t width , si_t height) { widget_set_bounds(WIDGET_POINTER(b), x, y, width, height); text_line_set_bounds(b->text_number, 0, 0, b->area.width-b->area.height, b->area.height); button_set_bounds(b->button_up, b->area.width-b->area.height+1, 0, b->area.height, b->area.height/2); button_set_bounds(b->button_down, b->area.width-b->area.height+1, b->area.height/2+1, b->area.height, b->area.height/2); }
/* * @breif 本函数功能是通过判断 * */ si_t shortcut_update_all_areas ( struct shortcut * sh ) { struct rectangle area; /* 总字数 , 单字宽度,单字高度,每行字数 ,总行数,最后一行的字数 */ si_t char_total_num ; si_t font_height; si_t font_width; si_t text_line_num; si_t maxlen; application_widget_absolute_area(WIDGET_POINTER(sh), &area); if(shortcut_get_is_text_visiable(sh) == 1) { /* 总字数 , 单字宽度,单字高度 */ char_total_num = strlen( sh->text ); font_height = get_font_height( sh->gd ) ; font_width = get_font_width( sh->gd ) ; maxlen = area.width * 2 / font_width; text_line_num = char_total_num / maxlen + 1; if( font_height > sh->area.height || font_width >sh->area.width) { EGUI_PRINT_ERROR("font for desktop shortcut is too large"); return -1; } sh->text_field.x = area.x ; sh->text_field.y = area.y + area.height - ( text_line_num * font_height ); sh->text_field.width = area.width; sh->text_field.height = text_line_num * font_height ; sh->img_field.x = area.x ; //sh->img_field.x = area.x + area.width/4 ; sh->img_field.y = area.y ; sh->img_field.width = area.width ; sh->img_field.height = area.height - sh->text_field.height; } else { sh->img_field.x = area.x ; sh->img_field.y = area.y ; sh->img_field.width = area.width ; sh->img_field.height = area.height ; } return 1; }
/** * param is a pointer to a pointer * because focus_list store the descriptor of widget * so the data pointer in focus_list node points to the descriptor of widget * which is also pointer of widget, so... * got it? **/ static si_t application_keybd_lose_focus(void* wptr) { struct widget* w = WIDGET_POINTER(*(struct widget**)wptr); if(w->keybd_focus) { w->keybd_focus = 0; if(w->callback != NULL) { union message msg; msg.base.type = MESSAGE_TYPE_KEYBD_LEAVE; w->callback(w, &msg); } } return 0; }
void *shortcut_init(si_t id) { struct shortcut * addr; /* 分配存储空间 */ addr = (struct shortcut *)malloc(sizeof(struct shortcut)); if(addr == NULL) { EGUI_PRINT_SYS_ERROR("fail to malloc"); return NULL; } if(!(addr=widget_init_common(WIDGET_POINTER(addr), id))) { return NULL; } addr->name = "struct shortcut"; addr->img_field.x = 0; addr->img_field.y = 0; addr->img_field.width = 0; addr->img_field.height = 0; addr->text_field.x = 0; addr->text_field.y = 0; addr->text_field.width = 0; addr->text_field.height = 0; addr->is_text_visiable = 0; addr->flag = 0; addr->position_x=0; addr->position_y=0; addr->last_do_time.tv_sec=0; addr->last_do_time.tv_usec=0; memset(addr->img_path , 0 ,sizeof(char)*255); memset(addr->img_normal_path , 0 ,sizeof(char)*255); memset(addr->img_select_path , 0 ,sizeof(char)*255); memset(addr->text , 0, sizeof(char)*255); /* 默认的回调函数 */ addr->callback = shortcut_default_callback; return addr; }
/* }}} */ extern si_t text_line_default_widget_show(struct text_line* t, union message* msg) { struct rectangle area; widget_absolute_area(WIDGET_POINTER(t), &area); /* 设置区域 */ set_area (t->gd, area.x, area.y, area.width, area.height); /* 更新 */ update(t->gd); return 0; }
si_t panel_default_widget_show(struct panel* pnl , union message * msg) { struct rectangle area; struct object *tree, *node; struct widget * wgt; /* 先显示panel本身的,即更新绘图设备 */ widget_absolute_area(WIDGET_POINTER(pnl), &area); set_area( pnl->gd, area.x, area.y, area.width, area.height ); update( pnl->gd ); /* 绘制panel子控件的区域 */ tree = OBJECT_POINTER(pnl); node = tree->rchild; while(node != NULL) { wgt = (struct widget*)node; wgt->callback(wgt, msg); node = object_tree_iterator_decrement(tree,node); } return 1; }
void tab_set_bounds(struct tab * b, si_t x, si_t y, si_t width , si_t height) { widget_set_bounds(WIDGET_POINTER(b), x, y, width, height); }
/* 一般用户并不需要调用这个 用户应用程序退出之后,application 会释放这个控件所占的空间。 而窗口管理程序会释放所有资源,包括申请的每个图形设备。 */ si_t tab_exit(struct tab * b) { tab_header_exit(b->header); return widget_exit(WIDGET_POINTER(b)); }
void _widget_destructor(void* arg){ struct widget* w=WIDGET_POINTER(arg); graphics_device_exit(w->gd); free(arg); }
static si_t text_line_default_widget_repaint(struct text_line* t, union message* msg) { struct rectangle area; si_t x, y; /* 获得左上角的绝对坐标 */ widget_absolute_coordinate(WIDGET_POINTER(t), &x, &y); /* 获得绝对的工作区域 */ /* 将会舍弃不在父控件内的部分*/ widget_absolute_area(WIDGET_POINTER(t), &area); set_area (t->gd, area.x, area.y, area.width, area.height); /** * backgroud **/ set_color(t->gd, t->back_color.r, t->back_color.g, t->back_color.b, t->back_color.a); fill_rectangle(t->gd, area.x + 4, area.y + 4, area.width - 8, area.height - 8); /** * outter frame: black if keyboard focus; grey if not **/ if(t->keybd_focus) { /* FIXME */ set_color (t->gd, t->frame_color.r, t->frame_color.g, t->frame_color.b, t->frame_color.a); text_line_draw_frame (t->gd, area.x, area.y, area.width, area.height, 3); text_line_draw_frame (t->gd, area.x + 1, area.y + 1, area.width - 2, area.height - 2, 2); } else { /* FIXME */ set_color (t->gd, t->frame_color.r, t->frame_color.g, t->frame_color.b, t->frame_color.a); text_line_draw_frame (t->gd, area.x, area.y, area.width, area.height, 3); text_line_draw_frame (t->gd, area.x + 1, area.y + 1, area.width - 2, area.height - 2, 2); } /** * inner frame **/ set_color (t->gd, t->frame_color.r, t->frame_color.g, t->frame_color.b, t->frame_color.a); text_line_draw_frame (t->gd, area.x + 2, area.y + 2, area.width - 4, area.height - 4, 1); text_line_draw_frame (t->gd, area.x + 3, area.y + 3, area.width - 6, area.height - 6, 1); text_line_draw_frame (t->gd, area.x + 4, area.y + 4, area.width - 8, area.height - 8, 1); set_area (t->gd, area.x + 6, area.y + 6, area.width - 12, area.height - 12); /** * show text **/ text_line_default_show_text(t, area.x, area.y); return 0; }
void text_line_set_color(struct text_line* t, struct color* fore_color, struct color* back_color, struct color* frame_color) { widget_set_color(WIDGET_POINTER(t), fore_color, back_color); t->frame_color = (NULL == frame_color ? t->frame_color : *frame_color); }
void text_line_set_bounds(struct text_line* t, si_t x, si_t y, si_t width , si_t height) { widget_set_bounds(WIDGET_POINTER(t), x, y, width, height); }
void text_line_show(struct text_line* t) { widget_show(WIDGET_POINTER(t)); }
void text_line_repaint(struct text_line* t) { widget_repaint(WIDGET_POINTER(t)); }