Beispiel #1
0
INT32 GenericTreeModel::GetPreviousLeafIndex(INT32 index)
{
	if (GetSubtreeSize(index) == 0)
	{
		// this is a leaf itself. Go up
		while (GetPreviousIndex(index) == -1 && index != -1)
			index = GetParentIndex(index);
		if (index == -1)
			return -1;
		
		index = GetPreviousIndex(index);
	}

	// Go down to the leaf
	return index + GetSubtreeSize(index);
}
Beispiel #2
0
T RangeTree<T>::GetValueOnInterval(int idx, int subtree_left,
        int subtree_right, int searching_left, int searching_right) const {
//    printf("GVOI: %d v: %d sl: %d sr: %d sel: %d ser: %d\n", idx,
//            tree_[idx], subtree_left, subtree_right, searching_left,
//            searching_right);
    if (subtree_left == searching_left && subtree_right == searching_right)
        return tree_[idx];
    const int left_child_boundary = subtree_left - 1
                                    + GetSubtreeSize(subtree_left,
                                                     subtree_right) / 2;
    T left_result;
    if (IsPointInLeftChild(searching_left, subtree_left, subtree_right)) {
        left_result = GetValueOnInterval(GetLeftChild(idx),
                                         subtree_left,
                                         left_child_boundary,
                                         searching_left,
                                         std::min(searching_right,
                                                  left_child_boundary));
    }
    const int right_child_boundary = left_child_boundary + 1;
    T right_result;
    if (IsPointInRightChild(searching_right, subtree_left, subtree_right)) {
        right_result = GetValueOnInterval(GetRightChild(idx),
                                          right_child_boundary,
                                          subtree_right,
                                          std::max(searching_left,
                                                   right_child_boundary),
                                          searching_right);
    }
    if (IsPointInLeftChild(searching_right, subtree_left, subtree_right))
        return left_result;
    if (IsPointInRightChild(searching_left, subtree_left, subtree_right))
        return right_result;
    return (*operation_)(left_result, right_result);
}
Beispiel #3
0
void GenericTreeModel::Remove(INT32 index, BOOL all_children, BOOL delete_item)
{
	INT32 subtreesize = all_children ? GetSubtreeSize(index) : 0;

	BOOL broadcast = SetChangeType(TREE_CHANGED);

	GenericTreeModelItem* parent = GetGenericParentItem(index);

	if (broadcast)
	{
		BroadcastSubtreeRemoving(parent ? parent->GetIndex() : -1, index, subtreesize);
	}

	if (!all_children)
	{
		INT32 child = GetChildIndex(index);

		while (child != -1)
		{
			INT32 sibling = GetSiblingIndex(child);

			GetGenericItemByIndex(child)->SetGenericParentItem(parent);

			child = sibling;
		}
	}

	INT32 count = subtreesize + 1;

	Removing(index, count);
	UpdateSubtreeSizes(parent, -count);
	OpTreeModelItem* data;
	for(UINT32 i = index, count_item = index + count; i < count_item; i++)
		m_id_to_item.Remove(m_items.Get(i)->GetID(), &data);

	if (delete_item)
	{
		m_items.Delete(index, count);
	}
	else
	{
		m_items.Remove(index, count);
	}

	if (broadcast)
	{
		BroadcastSubtreeRemoved(parent ? parent->GetIndex() : -1, index, subtreesize);
	}
}
Beispiel #4
0
INT32 GenericTreeModel::GetNextLeafIndex(INT32 index)
{
	if (GetSubtreeSize(index) == 0)
	{
		// this is a leaf itself. Go up
		while (GetSiblingIndex(index) == -1 && index != -1)
			index = GetParentIndex(index);
		if (index == -1)
			return -1;
		
		index = GetSiblingIndex(index);
	}

	// Go down to the leaf
	while (GetChildIndex(index) != -1)
		index = GetChildIndex(index);

	return index;
}
Beispiel #5
0
void GenericTreeModel::Move(INT32 index, INT32 parent_index, INT32 previous_index)
{
	if (index == -1 || index == previous_index)
	{
		return;
	}

	INT32 subtree_size = GetSubtreeSize(index);
	INT32 count = subtree_size + 1;
	
	GenericTreeModelItem* item			= GetGenericItemByIndex(index);

	GenericTreeModelItem* parent		= item->GetGenericParentItem();
	GenericTreeModelItem* new_parent	= GetGenericItemByIndex(parent_index);
	GenericTreeModelItem* new_previous	= GetGenericItemByIndex(previous_index);

	OP_ASSERT(!new_parent || !new_previous || new_parent == new_previous->GetGenericParentItem());

	if(new_previous && !new_parent)
		new_parent = new_previous->GetGenericParentItem();

	BOOL broadcast = SetChangeType(TREE_CHANGED);

	// 1. Save item and subtree
	OpAutoArray<GenericTreeModelItem*> to_be_moved (OP_NEWA(GenericTreeModelItem*, count));
	if (!to_be_moved.get())
		return;

	for(INT32 j = 0; j < count; j++)
	{
		to_be_moved[j] = m_items.Get(index + j);
	}

	// 2. Remove the subtree
	if (broadcast)
		BroadcastSubtreeRemoving(parent ? parent->GetIndex() : -1, index, subtree_size);

	if(parent)
		UpdateSubtreeSizes(parent, -count);
	m_items.Remove(index,count);
	
	if (broadcast)
		BroadcastSubtreeRemoved(parent ? parent->GetIndex() : -1, index, subtree_size);

	// 3. Insert it in proper position,update parent of item if needed
	
	// NOTICE: index of new_previous and new_parent may have changed! dont use previous_index and parent_index here
	INT32 insert_pos = new_previous ? 
		new_previous->GetIndex()  + new_previous->GetSubtreeSize() + 1
		: new_parent ? new_parent->GetIndex() + 1 : 0;
	for(INT32 i=0; i<count; i++)
	{
		m_items.Insert(insert_pos + i, to_be_moved[i]);
	}
	item->SetGenericParentItem(new_parent);
	if(new_parent)
		UpdateSubtreeSizes(new_parent, count);

	if(broadcast)
	{
		for(INT32 i=0; i<count; i++)
			BroadcastItemAdded(insert_pos + i);
	}
}
Beispiel #6
0
INT32 GenericTreeModel::ResortItem(INT32 index)
{
	OP_ASSERT(m_sort_listener);

	if (!m_sort_listener)
		return -1;

	INT32 sibling = -1;

	// Binary search until correct sibling is found

	INT32 tree_size = GetSubtreeSize(index) + 1;
	INT32 parent = GetParentIndex(index);
	INT32 parent_tree_size = GetSubtreeSize(parent);
	INT32 lowest = 0;
	INT32 highest = parent_tree_size - tree_size;
	GenericTreeModelItem* item = GetGenericItemByIndex(index);

	while (lowest < highest)
	{
		INT32 current_position = (lowest + highest) / 2;
		INT32 pos_to_compare_to = parent + current_position + 1;

		if (pos_to_compare_to >= index)
			pos_to_compare_to += tree_size;

		// convert any grandchildren up to same level we're inserting at
		INT32 parent_of_pos_to_compare_to	= GetParentIndex(pos_to_compare_to);

		while (parent_of_pos_to_compare_to != parent)
		{
			pos_to_compare_to = parent_of_pos_to_compare_to;
			parent_of_pos_to_compare_to = GetParentIndex(pos_to_compare_to);
		}

		INT32 comparison = m_sort_listener->OnCompareItems(this, item, GetGenericItemByIndex(pos_to_compare_to));

		if (comparison > 0)
		{
			lowest = current_position + 1;
		}
		else
		{
			sibling = pos_to_compare_to;
			highest = current_position;
		}
	}

	INT32 newpos = (sibling != -1 ? sibling : parent + 1 + parent_tree_size);
	if (newpos == index)
		return newpos;

	ModelLock lock(this);

	SetChangeType(TREE_CHANGED);

	GenericTreeModelItem** items = OP_NEWA(GenericTreeModelItem*, tree_size);
	if (!items)
		return -1;

	for (INT32 i = 0; i < tree_size; i++)
		items[i] = m_items.Get(index + i);

	m_items.Remove(index, tree_size);

	if (newpos > index)
		newpos -= tree_size;

	for (INT32 i = tree_size - 1; i >= 0; i--)
		m_items.Insert(newpos, items[i]);

	OP_DELETEA(items);

	return newpos;
}
Beispiel #7
0
 static bool IsPointInRightChild(int point, int left, int right) {
     return (left + GetSubtreeSize(left, right) / 2) <= point;
 }
Beispiel #8
0
 static bool IsPointInLeftChild(int point, int left, int right) {
     return point < (left + GetSubtreeSize(left, right) / 2);
 }