Beispiel #1
0
/*
    总是将孩子节点加在子节点链的最右边

    如果 obj 在对象树中
    那么完成添加工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
    这是为了保证遍历的正确
*/
si_t object_insert_child(struct object* parent, struct object* child)
{
	struct object* tree = NULL;

	if(NULL == parent)
	{
		return 0;
	}

	/* 父节点有右子节点 */
	if(parent->rchild != NULL)
	{
		parent->rchild->parent = child;

		/* 父节点的右子节点作为自己的左子节点 */
		child->lchild = parent->rchild;
	}

	child->parent = parent;
	parent->rchild = child;

	/* 找到这棵树根节点的父节点 */
	tree = object_get_root(parent)->parent;

	/* child 在对象树中 */
	/* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
	/* 更新最左边节点 */
	tree->lchild = object_tree_l_most_node(tree->parent);
	/* 更新最右边节点 */
	tree->rchild = object_tree_r_most_node(tree->parent);

	return 0;
}
Beispiel #2
0
void object_move_first(struct object* obj)
{
	struct object * tree = NULL, * parent = NULL;
	/* 如果活动窗口不是顶层窗口也不是父窗口的右子节点 */
	/* 将活动窗口变成父窗口的右子节点 */
	if(obj == obj->parent->parent || obj == obj->parent->rchild)
	{
		return 0;
	}
	/* 找到 win_info_ptr 的父窗口 */
	parent = obj->parent;
	while(parent == parent->parent->lchild)
	{
		parent = parent->parent;
	}
	parent = parent->parent;

	/* obj 有左子节点 */
	/* obj 在末端 */
	if(obj->lchild != NULL)
	{
		obj->lchild->parent = obj->parent;
		obj->parent->lchild = obj->lchild;
	}
	/* obj 没有左子节点 */
	/* obj 在中间*/
	else
	{
		obj->parent->lchild = NULL;
	}

	obj->lchild = parent->rchild;
	parent->rchild->parent =obj;

	obj->parent = parent;
	parent->rchild = obj;

	/* 找到这棵树根节点的父节点 */
	tree = object_get_root(parent)->parent;

	/* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
	/* 此时 tree == root->parent */

	/* 更新最左边节点 */
	tree->lchild = object_tree_l_most_node(tree->parent);
	/* 更新最右边节点 */
	tree->rchild = object_tree_r_most_node(tree->parent);
}
Beispiel #3
0
/*
    总是将孩子节点加在子节点链的最左边

    如果 obj 在对象树中
    那么完成添加工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
    这是为了保证遍历的正确
*/
si_t object_attach_child(struct object * obj, struct object * child)
{
    struct object * tree;

    /* parent 没有子对象 */
    if(obj->rchild == NULL)
    {
        /* 作为上层对象的右子节点 */
        obj->rchild = child;
        child->parent = obj;
    }
    else
    {
        obj = obj->rchild;

        /* 一直往左走 */
        while(obj->lchild != NULL)
        {
            obj = obj->lchild;
        }

        /* 作为同层对象的左子节点 */
        obj->lchild = child;
        child->parent = obj;
    }

    /* 找到这棵树根节点的父节点 */
    /* 没有的话 tree == NULL */
	tree = object_get_root(obj)->parent;

    /* obj 在对象树中 */
    /* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
    /* 此时 tree == root->parent */
    if(tree != NULL)
    {
        /* 更新最左边节点 */
        tree->lchild = object_tree_l_most_node(tree->parent);
        /* 更新最右边节点 */
        tree->rchild = object_tree_r_most_node(tree->parent);
    }

    return 0;
}
Beispiel #4
0
struct node_t *random_tree(ui_t count)
{
    struct node_t *root = calloc(1, sizeof(struct node_t));
    struct node_t *fakeroot = calloc(1, sizeof(struct node_t));
    static struct node_t **nodes;
    ui_t i;

    root->obj.parent = &fakeroot->obj;
    fakeroot->obj.parent = &root->obj;
    fakeroot->obj.lchild = object_tree_l_most_node(&root->obj);
    fakeroot->obj.rchild = object_tree_r_most_node(&root->obj);
    nodes = calloc(count, sizeof(struct node_t *));
    nodes[0] = root;
    nodes[0]->obj.id = 0;
    for (i = 1; i < count; i++) {
        struct node_t *par = nodes[rand() % i];
        nodes[i] = calloc(1, sizeof(struct node_t));
        nodes[i]->obj.id = i;
        object_attach_child(OBJECT_POINTER(par), OBJECT_POINTER(nodes[i]));
    }
    free(nodes);
    return root;
}
/*
   总是将孩子节点加在子节点链的最右边

   如果 parent 在对象树中
   那么完成添加工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
   这是为了保证遍历的正确
   */
si_t application_add_window(struct window * parent, struct window * window)
{
	struct object node, * tree;

	/* 添加顶层窗口 */
	if(parent == NULL)
	{
		/* node 的父节点是 window */
		node.parent = OBJECT_POINTER(window);
		node.lchild = object_tree_l_most_node(OBJECT_POINTER(window));
		node.rchild = object_tree_r_most_node(OBJECT_POINTER(window));
		node.name = NULL;
		node.id = 0;

		/* 将窗口添加到向量 */
		vector_push_back(&(global_application.window_vector), &node, sizeof(struct object));

		tree = vector_back(&(global_application.window_vector));

		/* window 的父节点是 node */
		window->parent = tree;
	}
	/* 添加非顶层窗口 */
	else
	{
		object_insert_child(OBJECT_POINTER(parent), OBJECT_POINTER(window));
	}
	/**
	 * if already running in app_exec
	 **/
	if(global_application.exec_flag)
	{
		union message msg;
		msg.base.type = MESSAGE_TYPE_WIDGET_REPAINT;
		msg.widget_repaint.area = window->area;

		if(global_application.focus != NULL)
		{
			struct window* w = WINDOW_POINTER(global_application.focus);
			struct object* tree, *node, *tree_real_parent;
			w->is_activated = 0;
			msg.widget_repaint.area = w->area;
			if(w->callback != NULL)
			{
				w->callback(w, &msg);
			}

			node = OBJECT_POINTER(w);
			tree = node->parent;
			tree_real_parent = tree->parent;
			tree->parent = node;
			node = object_tree_l_most_node(tree);
			while(node != NULL)
			{
				union message msg;
				msg.base.type = MESSAGE_TYPE_WIDGET_REPAINT;
				msg.widget_repaint.area = WIDGET_POINTER(node)->area;
				if(WIDGET_POINTER(node)->callback != NULL)
					WIDGET_POINTER(node)->callback(node, &msg);

				node = object_tree_iterator_increment(tree, node);
			}
			tree->parent = tree_real_parent;
		}

		window->descriptor = register_window((parent == NULL ? 0 : parent->descriptor), window->title, 
			window->area.x, window->area.y, window->area.width, window->area.height, 
			window->minimize_enable, window->maximize_enable, window->modal);
		if(window->descriptor == 0)
		{
			EGUI_PRINT_ERROR("failed to register window");
			application_exit();
			return -1;
		}

		/**
		 * find icon for the application
		 **/
		if((window->icon_path = (char*)malloc(256)) == NULL)
		{
			EGUI_PRINT_SYS_ERROR("failed to malloc for icon path. malloc");
			application_exit();
			return -1;
		}
		else
		{
			/**
			 * in C89 standard, snprintf() is NOT included in <stdio.h>
			 * so you have to use sprintf, which may be dangerous. be careful
			 **/
			sprintf(window->icon_path, "%s/icons/%s.bmp", global_application.icon_root_path, global_application.name);
			if(access(window->icon_path, R_OK) == -1)
			{
				sprintf(window->icon_path, "%s/icons/default.bmp", global_application.icon_root_path);
			}
		}

		msg.widget_repaint.area = window->area;
		global_application.focus = window;
		window->is_activated = 1;
		if(window->callback != NULL)
		{
			window->callback(window, &msg);
		}
	}

	return 0;
}
Beispiel #6
0
si_t object_delete(struct object* object, void(*destructor)(void*))
{
	if(object->parent->parent == object)
	{
		object_tree_for_each(object, destructor);
	}
	else
	{
		/* 找到这棵树根节点的父节点 */
		struct object* tree = object_get_root(object)->parent;

		/* 是父节点的右子节点 */
		if(object == object->parent->rchild)
		{
			/* object 没有左子节点 */
			/* parent 的下一层对象只有 object */
			if(object->lchild == NULL)
			{
				/* 清除父节点中的指针 */
				object->parent->rchild = NULL;
			}
			/* object 有左子节点 */
			/* parent 的下一层有多个对象 */
			else
			{
				/* 处理 object 同层的对象 */
				object->parent->rchild = object->lchild;
				object->lchild->parent = object->parent;

				/* 清空 object->lchild */
				object->lchild = NULL;
			}
		}
		/* 是父节点的左子节点 */
		/* 此时 parent 的下一层有多个对象 */
		else if(object == object->parent->lchild)
		{
			/* object 没有左子节点 */
			/* object 处于末端 */
			if(object->lchild == NULL)
			{
				/* 清除父节点中的指针 */
				object->parent->lchild = NULL;
			}
			/* object 有左子节点 */
			/* object 处于中间 */
			else
			{
				/* 处理 object 同层的对象 */
				object->parent->lchild = object->lchild;
				object->lchild->parent = object->parent;

				/* 清空 object->lchild */
				object->lchild = NULL;
			}
		}

		object_tree_for_each(object, destructor);

		/* 必须更新 root->parent 节点的 lchild 和 rchild */
		/* 此时 tree == root->parent */
		if(tree != NULL)
		{
			/* 更新最左边节点 */
			tree->lchild = object_tree_l_most_node(tree->parent);
			/* 更新最右边节点 */
			tree->rchild = object_tree_r_most_node(tree->parent);
		}

	}
	return 0;
}
Beispiel #7
0
/*
    如果 obj 有左子节点
    那么这个左子节点并不是 obj 子对象
    所以在析构以 obj 为根的树之前一定要要将 obj->lchild 成员清空

    如果 obj 在对象树中
    那么完成删除工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员
    这是为了保证遍历的正确
*/
si_t object_remove(struct object * obj)
{
    struct object * tree;

    /* obj 有父对象 */
    if(obj->parent != NULL)
    {
        /* 找到这棵树根节点的父节点 */
        /* 没有的话 tree == NULL */
		tree = object_get_root(obj)->parent;

        /* obj 是由父节点右子节点 */
        if(obj == obj->parent->rchild)
        {
            /* obj 没有左子节点 */
            /* parent 的下一层对象只有 obj */
            if(obj->lchild == NULL)
            {
                /* 清除父节点中的指针 */
                obj->parent->rchild = NULL;
            }
            /* obj 有左子节点 */
            /* parent 的下一层有多个对象 */
            else
            {
                /* 处理 obj 同层的对象 */
                obj->parent->rchild = obj->lchild;
                obj->lchild->parent = obj->parent;

                /* 清空 obj->lchild */
                obj->lchild = NULL;
            }
        }
        /* obj 是由父节点左子节点 */
        /* 此时 parent 的下一层有多个对象 */
        else if(obj == obj->parent->lchild)
        {
            /* obj 没有左子节点 */
            /* obj 处于末端 */
            if(obj->lchild == NULL)
            {
                /* 清除父节点中的指针 */
                obj->parent->lchild = NULL;
            }
            /* obj 有左子节点 */
            /* obj 处于中间 */
            else
            {
                /* 处理 obj 同层的对象 */
                obj->parent->lchild = obj->lchild;
                obj->lchild->parent = obj->parent;

                /* 清空 obj->lchild */
                obj->lchild = NULL;
            }
        }

        /* 删除 obj 以及它的所有子对象 */
        object_tree_free(obj);

        /* obj 在对象树中 */
        /* 必须更新 root->parent 节点的 lchild 成员和 rchild 成员 */
        /* 此时 tree == root->parent */
        if(tree != NULL)
        {
            /* 更新最左边节点 */
            tree->lchild = object_tree_l_most_node(tree->parent);
            /* 更新最右边节点 */
            tree->rchild = object_tree_r_most_node(tree->parent);
        }
    }
    /* 没有父对象 */
    else
    {
        /* 清空 obj->lchild */
        obj->lchild = NULL;

        /* 删除 obj 以及它的所有子对象 */
        object_tree_free(obj);
    }

    return 0;
}