* Added layout-friendly constructor.

* Reordered functions to match the order in the header (and vice versa).
* Removed unused private functions.
* Updated the header to follow our coding style.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31088 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-06-17 14:56:57 +00:00
parent 42f07f3fea
commit 08a3563801
2 changed files with 338 additions and 377 deletions
+32 -30
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _OUTLINE_LIST_VIEW_H #ifndef _OUTLINE_LIST_VIEW_H
@@ -15,7 +15,12 @@ class BOutlineListView : public BListView {
public: public:
BOutlineListView(BRect frame, const char* name, BOutlineListView(BRect frame, const char* name,
list_view_type type = B_SINGLE_SELECTION_LIST, list_view_type type = B_SINGLE_SELECTION_LIST,
uint32 resizeMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 resizeMode
= B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS
| B_NAVIGABLE);
BOutlineListView(const char* name,
list_view_type type = B_SINGLE_SELECTION_LIST,
uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS
| B_NAVIGABLE); | B_NAVIGABLE);
BOutlineListView(BMessage* archive); BOutlineListView(BMessage* archive);
@@ -53,7 +58,8 @@ class BOutlineListView : public BListView {
virtual void MakeEmpty(); virtual void MakeEmpty();
bool FullListIsEmpty() const; bool FullListIsEmpty() const;
void FullListDoForEach(bool (*func)(BListItem* item)); void FullListDoForEach(bool (*func)(BListItem* item));
void FullListDoForEach(bool (*func)(BListItem* item, void *), void*); void FullListDoForEach(
bool (*func)(BListItem* item, void*), void*);
BListItem* Superitem(const BListItem* item); BListItem* Superitem(const BListItem* item);
@@ -63,7 +69,8 @@ class BOutlineListView : public BListView {
bool IsExpanded(int32 fullListIndex); bool IsExpanded(int32 fullListIndex);
virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, virtual BHandler* ResolveSpecifier(BMessage* message, int32 index,
BMessage* specifier, int32 what, const char* property); BMessage* specifier, int32 what,
const char* property);
virtual status_t GetSupportedSuites(BMessage* data); virtual status_t GetSupportedSuites(BMessage* data);
virtual status_t Perform(perform_code d, void* arg); virtual status_t Perform(perform_code d, void* arg);
@@ -74,15 +81,18 @@ class BOutlineListView : public BListView {
virtual void AllDetached(); virtual void AllDetached();
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
void FullListSortItems(int (*compareFunc)(const BListItem* first, void FullListSortItems(int (*compareFunc)(
const BListItem* first,
const BListItem* second)); const BListItem* second));
void SortItemsUnder(BListItem* underItem, bool oneLevelOnly, void SortItemsUnder(BListItem* underItem,
int (*compareFunc)(const BListItem* first, bool oneLevelOnly, int (*compareFunc)(
const BListItem* first,
const BListItem* second)); const BListItem* second));
int32 CountItemsUnder(BListItem* under, bool oneLevelOnly) const; int32 CountItemsUnder(BListItem* under,
BListItem* EachItemUnder(BListItem* underItem, bool oneLevelOnly, bool oneLevelOnly) const;
BListItem* (*eachFunc)(BListItem* item, void* arg), BListItem* EachItemUnder(BListItem* underItem,
void* arg); bool oneLevelOnly, BListItem* (*eachFunc)(
BListItem* item, void* arg), void* arg);
BListItem* ItemUnderAt(BListItem* underItem, bool oneLevelOnly, BListItem* ItemUnderAt(BListItem* underItem, bool oneLevelOnly,
int32 index) const; int32 index) const;
@@ -96,38 +106,30 @@ class BOutlineListView : public BListView {
virtual void _ReservedOutlineListView3(); virtual void _ReservedOutlineListView3();
virtual void _ReservedOutlineListView4(); virtual void _ReservedOutlineListView4();
typedef BListView _inherited;
int32 FullListIndex(int32 index) const;
int32 ListViewIndex(int32 index) const;
protected: protected:
virtual void ExpandOrCollapse(BListItem* underItem, bool expand); virtual void ExpandOrCollapse(BListItem* underItem, bool expand);
virtual BRect LatchRect(BRect itemRect, int32 level) const; virtual BRect LatchRect(BRect itemRect, int32 level) const;
virtual void DrawLatch(BRect itemRect, int32 level, bool collapsed, virtual void DrawLatch(BRect itemRect, int32 level,
bool highlighted, bool misTracked); bool collapsed, bool highlighted,
virtual void DrawItem(BListItem* item, BRect itemRect, bool complete = false); bool misTracked);
virtual void DrawItem(BListItem* item, BRect itemRect,
bool complete = false);
private: private:
int32 _FullListIndex(int32 index) const;
void _PopulateTree(BList* tree, BList& target, void _PopulateTree(BList* tree, BList& target,
int32& firstIndex, bool onlyVisible); int32& firstIndex, bool onlyVisible);
void _SortTree(BList* tree, bool oneLevelOnly, void _SortTree(BList* tree, bool oneLevelOnly,
int (*compareFunc)(const BListItem* a, const BListItem* b)); int (*compareFunc)(const BListItem* a,
const BListItem* b));
void _DestructTree(BList* tree); void _DestructTree(BList* tree);
BList* _BuildTree(BListItem* underItem, int32& index); BList* _BuildTree(BListItem* underItem, int32& index);
BListItem* _RemoveItem(BListItem* item, int32 fullListIndex);
bool _SwapItems(int32 first, int32 second);
void _CullInvisibleItems(BList &list); void _CullInvisibleItems(BList &list);
BListItem* RemoveOne(int32 fullListIndex); bool _SwapItems(int32 first, int32 second);
BListItem* _RemoveItem(BListItem* item, int32 fullListIndex);
static void TrackInLatchItem(void *);
static void TrackOutLatchItem(void *);
bool OutlineSwapItems(int32 a, int32 b);
bool OutlineMoveItem(int32 from, int32 to);
bool OutlineReplaceItem(int32 index, BListItem* item);
void CommonMoveItems(int32 from, int32 count, int32 to);
BListItem* _SuperitemForIndex(int32 fullListIndex, int32 level, BListItem* _SuperitemForIndex(int32 fullListIndex, int32 level,
int32* _superIndex = NULL); int32* _superIndex = NULL);
int32 _FindPreviousVisibleIndex(int32 fullListIndex); int32 _FindPreviousVisibleIndex(int32 fullListIndex);
+211 -252
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2008, Haiku Inc. * Copyright 2001-2009, Haiku Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -12,22 +12,23 @@
//! BOutlineListView represents a "nestable" list view. //! BOutlineListView represents a "nestable" list view.
#include <OutlineListView.h> #include <OutlineListView.h>
#include <Window.h>
#include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <algorithm> #include <Window.h>
#include <binary_compatibility/Interface.h> #include <binary_compatibility/Interface.h>
const float kLatchHeight = 8.0f; typedef int (*compare_func)(const BListItem* a, const BListItem* b);
const float kLatchWidth = 4.0f;
struct ListItemComparator { struct ListItemComparator {
ListItemComparator(int (*compareFunc)(const BListItem *, const BListItem *)) ListItemComparator(compare_func compareFunc)
: fCompareFunc(compareFunc) :
fCompareFunc(compareFunc)
{ {
} }
@@ -37,9 +38,43 @@ struct ListItemComparator {
} }
private: private:
int (*fCompareFunc)(const BListItem *, const BListItem *); compare_func fCompareFunc;
}; };
const float kLatchHeight = 8.0f;
const float kLatchWidth = 4.0f;
static void
_GetSubItems(BList& sourceList, BList& destList, BListItem* parent, int32 start)
{
for (int32 i = start; i < sourceList.CountItems(); i++) {
BListItem* item = (BListItem*)sourceList.ItemAt(i);
if (item->OutlineLevel() <= parent->OutlineLevel())
break;
destList.AddItem(item);
}
}
static void
_DoSwap(BList& list, int32 firstIndex, int32 secondIndex, BList* firstItems,
BList* secondItems)
{
BListItem* item = (BListItem*)list.ItemAt(firstIndex);
list.SwapItems(firstIndex, secondIndex);
list.RemoveItems(secondIndex + 1, secondItems->CountItems());
list.RemoveItems(firstIndex + 1, firstItems->CountItems());
list.AddList(secondItems, firstIndex + 1);
int32 newIndex = list.IndexOf(item);
if (newIndex + 1 < list.CountItems())
list.AddList(firstItems, newIndex + 1);
else
list.AddList(firstItems);
}
// #pragma mark - // #pragma mark -
@@ -50,6 +85,13 @@ BOutlineListView::BOutlineListView(BRect frame, const char* name,
} }
BOutlineListView::BOutlineListView(const char* name, list_view_type type,
uint32 flags)
: BListView(name, type, flags)
{
}
BOutlineListView::BOutlineListView(BMessage* archive) BOutlineListView::BOutlineListView(BMessage* archive)
: BListView(archive) : BListView(archive)
{ {
@@ -340,7 +382,7 @@ BOutlineListView::FullListIndexOf(BPoint point) const
int32 index = BListView::IndexOf(point); int32 index = BListView::IndexOf(point);
if (index > 0) if (index > 0)
index = FullListIndex(index); index = _FullListIndex(index);
return index; return index;
} }
@@ -597,8 +639,8 @@ BOutlineListView::Perform(perform_code code, void* _data)
{ {
perform_data_get_height_for_width* data perform_data_get_height_for_width* data
= (perform_data_get_height_for_width*)_data; = (perform_data_get_height_for_width*)_data;
BOutlineListView::GetHeightForWidth(data->width, &data->min, &data->max, BOutlineListView::GetHeightForWidth(data->width, &data->min,
&data->preferred); &data->max, &data->preferred);
return B_OK; return B_OK;
} }
case PERFORM_CODE_SET_LAYOUT: case PERFORM_CODE_SET_LAYOUT:
@@ -692,7 +734,8 @@ BOutlineListView::SortItemsUnder(BListItem* underItem, bool oneLevelOnly,
// Populate to the full list // Populate to the full list
_PopulateTree(tree, fFullList, firstIndex, false); _PopulateTree(tree, fFullList, firstIndex, false);
if (underItem == NULL || (underItem->IsItemVisible() && underItem->IsExpanded())) { if (underItem == NULL
|| (underItem->IsItemVisible() && underItem->IsExpanded())) {
// Populate to BListView's list // Populate to BListView's list
firstIndex = fList.IndexOf(underItem) + 1; firstIndex = fList.IndexOf(underItem) + 1;
lastIndex = firstIndex; lastIndex = firstIndex;
@@ -715,91 +758,9 @@ BOutlineListView::SortItemsUnder(BListItem* underItem, bool oneLevelOnly,
_DestructTree(tree); _DestructTree(tree);
} }
void
BOutlineListView::_PopulateTree(BList* tree, BList& target,
int32& firstIndex, bool onlyVisible)
{
BListItem** items = (BListItem**)target.Items();
int32 count = tree->CountItems();
for (int32 index = 0; index < count; index++) {
BListItem* item = (BListItem*)tree->ItemAtFast(index);
items[firstIndex++] = item;
if (item->HasSubitems() && (!onlyVisible || item->IsExpanded()))
_PopulateTree(item->fTemporaryList, target, firstIndex, onlyVisible);
}
}
void
BOutlineListView::_SortTree(BList* tree, bool oneLevelOnly,
int (*compareFunc)(const BListItem* a, const BListItem* b))
{
BListItem **items = (BListItem **)tree->Items();
std::sort(items, items + tree->CountItems(), ListItemComparator(compareFunc));
if (oneLevelOnly)
return;
for (int32 index = tree->CountItems(); index-- > 0;) {
BListItem* item = (BListItem*)tree->ItemAt(index);
if (item->HasSubitems())
_SortTree(item->fTemporaryList, false, compareFunc);
}
}
void
BOutlineListView::_DestructTree(BList* tree)
{
for (int32 index = tree->CountItems(); index-- > 0;) {
BListItem* item = (BListItem*)tree->ItemAt(index);
if (item->HasSubitems())
_DestructTree(item->fTemporaryList);
}
delete tree;
}
BList*
BOutlineListView::_BuildTree(BListItem* underItem, int32& fullIndex)
{
int32 fullCount = FullListCountItems();
uint32 level = underItem != NULL ? underItem->OutlineLevel() + 1 : 0;
BList* list = new BList;
if (underItem != NULL)
underItem->fTemporaryList = list;
while (fullIndex < fullCount) {
BListItem *item = FullListItemAt(fullIndex);
// If we jump out of the subtree, break out
if (item->fLevel < level)
break;
// If the level matches, put them into the list
// (we handle the case of a missing sublevel gracefully)
list->AddItem(item);
fullIndex++;
if (item->HasSubitems()) {
// we're going deeper
_BuildTree(item, fullIndex);
}
}
return list;
}
int32 int32
BOutlineListView::CountItemsUnder(BListItem* underItem, BOutlineListView::CountItemsUnder(BListItem* underItem, bool oneLevelOnly) const
bool oneLevelOnly) const
{ {
int32 i = FullListIndexOf(underItem); int32 i = FullListIndexOf(underItem);
if (i == -1) if (i == -1)
@@ -883,88 +844,6 @@ BOutlineListView::ItemUnderAt(BListItem* underItem,
return NULL; return NULL;
} }
static void _GetSubItems(BList &sourceList, BList &destList,
BListItem *parent, int32 start)
{
for (int32 i = start; i < sourceList.CountItems(); i++) {
BListItem *item = (BListItem *)sourceList.ItemAt(i);
if (item->OutlineLevel() <= parent->OutlineLevel())
break;
destList.AddItem(item);
}
}
static void
_DoSwap(BList &list, int32 firstIndex, int32 secondIndex, BList *firstItems,
BList *secondItems)
{
BListItem *item = (BListItem *)list.ItemAt(firstIndex);
list.SwapItems(firstIndex, secondIndex);
list.RemoveItems(secondIndex + 1, secondItems->CountItems());
list.RemoveItems(firstIndex + 1, firstItems->CountItems());
list.AddList(secondItems, firstIndex + 1);
int32 newIndex = list.IndexOf(item);
if (newIndex + 1 < list.CountItems())
list.AddList(firstItems, newIndex + 1);
else
list.AddList(firstItems);
}
void
BOutlineListView::_CullInvisibleItems(BList &list)
{
int32 index = 0;
while (index < list.CountItems()) {
if (reinterpret_cast<BListItem *>(list.ItemAt(index))->IsItemVisible())
++index;
else
list.RemoveItem(index);
}
}
bool
BOutlineListView::_SwapItems(int32 first, int32 second)
{
// same item, do nothing
if (first == second)
return true;
// fail, first item out of bounds
if ((first < 0) || (first >= CountItems()))
return false;
// fail, second item out of bounds
if ((second < 0) || (second >= CountItems()))
return false;
int32 firstIndex = min_c(first, second);
int32 secondIndex = max_c(first, second);
BListItem *firstItem = ItemAt(firstIndex);
BListItem *secondItem = ItemAt(secondIndex);
BList firstSubItems, secondSubItems;
if (Superitem(firstItem) != Superitem(secondItem))
return false;
if (!firstItem->IsItemVisible() || !secondItem->IsItemVisible())
return false;
int32 fullFirstIndex = FullListIndex(firstIndex);
int32 fullSecondIndex = FullListIndex(secondIndex);
_GetSubItems(fFullList, firstSubItems, firstItem, fullFirstIndex + 1);
_GetSubItems(fFullList, secondSubItems, secondItem, fullSecondIndex + 1);
_DoSwap(fFullList, fullFirstIndex, fullSecondIndex, &firstSubItems,
&secondSubItems);
_CullInvisibleItems(firstSubItems);
_CullInvisibleItems(secondSubItems);
_DoSwap(fList, firstIndex, secondIndex, &firstSubItems,
&secondSubItems);
_RecalcItemTops(firstIndex);
_RescanSelection(firstIndex, secondIndex + secondSubItems.CountItems());
Invalidate(Bounds());
return true;
}
bool bool
BOutlineListView::DoMiscellaneous(MiscCode code, MiscData* data) BOutlineListView::DoMiscellaneous(MiscCode code, MiscData* data)
@@ -989,30 +868,6 @@ void BOutlineListView::_ReservedOutlineListView3() {}
void BOutlineListView::_ReservedOutlineListView4() {} void BOutlineListView::_ReservedOutlineListView4() {}
int32
BOutlineListView::FullListIndex(int32 index) const
{
BListItem *item = ItemAt(index);
if (item == NULL)
return -1;
return FullListIndexOf(item);
}
int32
BOutlineListView::ListViewIndex(int32 index) const
{
BListItem *item = ItemAt(index);
if (item == NULL)
return -1;
return BListView::IndexOf(item);
}
void void
BOutlineListView::ExpandOrCollapse(BListItem* underItem, bool expand) BOutlineListView::ExpandOrCollapse(BListItem* underItem, bool expand)
{ {
@@ -1081,13 +936,164 @@ BOutlineListView::DrawItem(BListItem* item, BRect itemRect, bool complete)
if (item->fHasSubitems) if (item->fHasSubitems)
DrawLatch(itemRect, item->fLevel, !item->IsExpanded(), false, false); DrawLatch(itemRect, item->fLevel, !item->IsExpanded(), false, false);
itemRect.left += (item->fLevel) * 10.0f + 15.0f; itemRect.left += item->fLevel * 10.0f + 15.0f;
item->DrawItem(this, itemRect, complete); item->DrawItem(this, itemRect, complete);
} }
/*! int32
\brief Removes a single item from the list and all of its children. BOutlineListView::_FullListIndex(int32 index) const
{
BListItem* item = ItemAt(index);
if (item == NULL)
return -1;
return FullListIndexOf(item);
}
void
BOutlineListView::_PopulateTree(BList* tree, BList& target,
int32& firstIndex, bool onlyVisible)
{
BListItem** items = (BListItem**)target.Items();
int32 count = tree->CountItems();
for (int32 index = 0; index < count; index++) {
BListItem* item = (BListItem*)tree->ItemAtFast(index);
items[firstIndex++] = item;
if (item->HasSubitems() && (!onlyVisible || item->IsExpanded()))
_PopulateTree(item->fTemporaryList, target, firstIndex, onlyVisible);
}
}
void
BOutlineListView::_SortTree(BList* tree, bool oneLevelOnly,
int (*compareFunc)(const BListItem* a, const BListItem* b))
{
BListItem** items = (BListItem**)tree->Items();
std::sort(items, items + tree->CountItems(), ListItemComparator(compareFunc));
if (oneLevelOnly)
return;
for (int32 index = tree->CountItems(); index-- > 0;) {
BListItem* item = (BListItem*)tree->ItemAt(index);
if (item->HasSubitems())
_SortTree(item->fTemporaryList, false, compareFunc);
}
}
void
BOutlineListView::_DestructTree(BList* tree)
{
for (int32 index = tree->CountItems(); index-- > 0;) {
BListItem* item = (BListItem*)tree->ItemAt(index);
if (item->HasSubitems())
_DestructTree(item->fTemporaryList);
}
delete tree;
}
BList*
BOutlineListView::_BuildTree(BListItem* underItem, int32& fullIndex)
{
int32 fullCount = FullListCountItems();
uint32 level = underItem != NULL ? underItem->OutlineLevel() + 1 : 0;
BList* list = new BList;
if (underItem != NULL)
underItem->fTemporaryList = list;
while (fullIndex < fullCount) {
BListItem* item = FullListItemAt(fullIndex);
// If we jump out of the subtree, break out
if (item->fLevel < level)
break;
// If the level matches, put them into the list
// (we handle the case of a missing sublevel gracefully)
list->AddItem(item);
fullIndex++;
if (item->HasSubitems()) {
// we're going deeper
_BuildTree(item, fullIndex);
}
}
return list;
}
void
BOutlineListView::_CullInvisibleItems(BList& list)
{
int32 index = 0;
while (index < list.CountItems()) {
if (reinterpret_cast<BListItem*>(list.ItemAt(index))->IsItemVisible())
++index;
else
list.RemoveItem(index);
}
}
bool
BOutlineListView::_SwapItems(int32 first, int32 second)
{
// same item, do nothing
if (first == second)
return true;
// fail, first item out of bounds
if ((first < 0) || (first >= CountItems()))
return false;
// fail, second item out of bounds
if ((second < 0) || (second >= CountItems()))
return false;
int32 firstIndex = min_c(first, second);
int32 secondIndex = max_c(first, second);
BListItem* firstItem = ItemAt(firstIndex);
BListItem* secondItem = ItemAt(secondIndex);
BList firstSubItems, secondSubItems;
if (Superitem(firstItem) != Superitem(secondItem))
return false;
if (!firstItem->IsItemVisible() || !secondItem->IsItemVisible())
return false;
int32 fullFirstIndex = _FullListIndex(firstIndex);
int32 fullSecondIndex = _FullListIndex(secondIndex);
_GetSubItems(fFullList, firstSubItems, firstItem, fullFirstIndex + 1);
_GetSubItems(fFullList, secondSubItems, secondItem, fullSecondIndex + 1);
_DoSwap(fFullList, fullFirstIndex, fullSecondIndex, &firstSubItems,
&secondSubItems);
_CullInvisibleItems(firstSubItems);
_CullInvisibleItems(secondSubItems);
_DoSwap(fList, firstIndex, secondIndex, &firstSubItems,
&secondSubItems);
_RecalcItemTops(firstIndex);
_RescanSelection(firstIndex, secondIndex + secondSubItems.CountItems());
Invalidate(Bounds());
return true;
}
/*! \brief Removes a single item from the list and all of its children.
Unlike the BeOS version, this one will actually delete the children, too, Unlike the BeOS version, this one will actually delete the children, too,
as there should be no reference left to them. This may cause problems for as there should be no reference left to them. This may cause problems for
@@ -1133,54 +1139,7 @@ BOutlineListView::_RemoveItem(BListItem* item, int32 fullIndex)
} }
BListItem * /*! Returns the super item before the item specified by \a fullListIndex
BOutlineListView::RemoveOne(int32 fullListIndex)
{
return NULL;
}
void
BOutlineListView::TrackInLatchItem(void *)
{
}
void
BOutlineListView::TrackOutLatchItem(void *)
{
}
bool
BOutlineListView::OutlineSwapItems(int32 a, int32 b)
{
return false;
}
bool
BOutlineListView::OutlineMoveItem(int32 from, int32 to)
{
return false;
}
bool
BOutlineListView::OutlineReplaceItem(int32 index, BListItem *item)
{
return false;
}
void
BOutlineListView::CommonMoveItems(int32 from, int32 count, int32 to)
{
}
/*!
Returns the super item before the item specified by \a fullListIndex
and \a level. and \a level.
*/ */
BListItem* BListItem*