patch by Rene Gollent:
* BListItems now store the top offset of the frame within the parent BListView. * This allows binary searching the clicked item. * ItemFrame() is now a cheap call. * Fixed several bugs in the sorting code of BOutlineListView which lead to crashes of client applications. * Implemented previously unimplemented functions in BOutlineListView. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24092 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -18,7 +18,8 @@ class BView;
|
|||||||
|
|
||||||
class BListItem : public BArchivable {
|
class BListItem : public BArchivable {
|
||||||
public:
|
public:
|
||||||
BListItem(uint32 outlineLevel = 0, bool expanded = true);
|
BListItem(uint32 outlineLevel = 0,
|
||||||
|
bool expanded = true);
|
||||||
BListItem(BMessage* archive);
|
BListItem(BMessage* archive);
|
||||||
virtual ~BListItem();
|
virtual ~BListItem();
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ class BListItem : public BArchivable {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BOutlineListView;
|
friend class BOutlineListView;
|
||||||
|
friend class BListView;
|
||||||
bool HasSubitems() const;
|
bool HasSubitems() const;
|
||||||
|
|
||||||
virtual void _ReservedListItem1();
|
virtual void _ReservedListItem1();
|
||||||
@@ -58,9 +59,11 @@ class BListItem : public BArchivable {
|
|||||||
|
|
||||||
bool IsItemVisible() const;
|
bool IsItemVisible() const;
|
||||||
void SetItemVisible(bool visible);
|
void SetItemVisible(bool visible);
|
||||||
|
inline float Top() const;
|
||||||
|
inline float Bottom() const;
|
||||||
|
void SetTop(float top);
|
||||||
private:
|
private:
|
||||||
uint32 _reserved[1];
|
float fTop;
|
||||||
BList* fTemporaryList;
|
BList* fTemporaryList;
|
||||||
float fWidth;
|
float fWidth;
|
||||||
float fHeight;
|
float fHeight;
|
||||||
@@ -72,6 +75,18 @@ class BListItem : public BArchivable {
|
|||||||
bool fVisible : 1;
|
bool fVisible : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline float
|
||||||
|
BListItem::Top(void) const
|
||||||
|
{
|
||||||
|
return fTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float
|
||||||
|
BListItem::Bottom(void) const
|
||||||
|
{
|
||||||
|
return (fTop + ceilf(fHeight) - 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
#include <StringItem.h>
|
#include <StringItem.h>
|
||||||
// to maintain source compatibility
|
// to maintain source compatibility
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ class BListView : public BView, public BInvoker {
|
|||||||
virtual void MakeFocus(bool state = true);
|
virtual void MakeFocus(bool state = true);
|
||||||
virtual void FrameResized(float newWidth, float newHeight);
|
virtual void FrameResized(float newWidth, float newHeight);
|
||||||
virtual void TargetedByScrollView(BScrollView* scroller);
|
virtual void TargetedByScrollView(BScrollView* scroller);
|
||||||
void ScrollTo(float x, float y);
|
|
||||||
virtual void ScrollTo(BPoint where);
|
virtual void ScrollTo(BPoint where);
|
||||||
|
inline void ScrollTo(float x, float y);
|
||||||
virtual bool AddItem(BListItem* item);
|
virtual bool AddItem(BListItem* item);
|
||||||
virtual bool AddItem(BListItem* item, int32 atIndex);
|
virtual bool AddItem(BListItem* item, int32 atIndex);
|
||||||
virtual bool AddList(BList* newItems);
|
virtual bool AddList(BList* newItems);
|
||||||
@@ -136,7 +136,6 @@ class BListView : public BView, public BInvoker {
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual bool DoMiscellaneous(MiscCode code, MiscData *data);
|
virtual bool DoMiscellaneous(MiscCode code, MiscData *data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BOutlineListView;
|
friend class BOutlineListView;
|
||||||
|
|
||||||
@@ -161,6 +160,7 @@ class BListView : public BView, public BInvoker {
|
|||||||
bool _TryInitiateDrag(BPoint where);
|
bool _TryInitiateDrag(BPoint where);
|
||||||
int32 _CalcFirstSelected(int32 after);
|
int32 _CalcFirstSelected(int32 after);
|
||||||
int32 _CalcLastSelected(int32 before);
|
int32 _CalcLastSelected(int32 before);
|
||||||
|
void _RecalcItemTops(int32 start);
|
||||||
virtual void DrawItem(BListItem* item, BRect itemRect,
|
virtual void DrawItem(BListItem* item, BRect itemRect,
|
||||||
bool complete = false);
|
bool complete = false);
|
||||||
|
|
||||||
@@ -174,12 +174,11 @@ class BListView : public BView, public BInvoker {
|
|||||||
int32 fFirstSelected;
|
int32 fFirstSelected;
|
||||||
int32 fLastSelected;
|
int32 fLastSelected;
|
||||||
int32 fAnchorIndex;
|
int32 fAnchorIndex;
|
||||||
float fWidth;
|
|
||||||
BMessage* fSelectMessage;
|
BMessage* fSelectMessage;
|
||||||
BScrollView* fScrollView;
|
BScrollView* fScrollView;
|
||||||
track_data* fTrack;
|
track_data* fTrack;
|
||||||
|
|
||||||
uint32 _reserved[3];
|
uint32 _reserved[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Copyright (c) 2001-2005, Haiku, Inc.
|
// Copyright (c) 2001-2008, Haiku, Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
//
|
//
|
||||||
// File Name: ListItem.cpp
|
// File Name: ListItem.cpp
|
||||||
// Author: Ulrich Wimboeck
|
// Author: Ulrich Wimboeck
|
||||||
// Marc Flerackers ([email protected])
|
// Marc Flerackers ([email protected])
|
||||||
|
// Rene Gollent
|
||||||
// Description: BListItem is the base class for BListView's items,
|
// Description: BListItem is the base class for BListView's items,
|
||||||
// BStringItem is a subclass of BListItem which draws a string.
|
// BStringItem is a subclass of BListItem which draws a string.
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -34,7 +35,8 @@
|
|||||||
|
|
||||||
|
|
||||||
BListItem::BListItem(uint32 level, bool expanded)
|
BListItem::BListItem(uint32 level, bool expanded)
|
||||||
: fWidth(0),
|
: fTop(0.0),
|
||||||
|
fWidth(0),
|
||||||
fHeight(0),
|
fHeight(0),
|
||||||
fLevel(level),
|
fLevel(level),
|
||||||
fSelected(false),
|
fSelected(false),
|
||||||
@@ -48,6 +50,7 @@ BListItem::BListItem(uint32 level, bool expanded)
|
|||||||
|
|
||||||
BListItem::BListItem(BMessage *data)
|
BListItem::BListItem(BMessage *data)
|
||||||
: BArchivable(data),
|
: BArchivable(data),
|
||||||
|
fTop(0.0),
|
||||||
fWidth(0),
|
fWidth(0),
|
||||||
fHeight(0),
|
fHeight(0),
|
||||||
fLevel(0),
|
fLevel(0),
|
||||||
@@ -226,6 +229,11 @@ BListItem::IsItemVisible() const
|
|||||||
return fVisible;
|
return fVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BListItem::SetTop(float top)
|
||||||
|
{
|
||||||
|
fTop = top;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BListItem::SetItemVisible(bool visible)
|
BListItem::SetItemVisible(bool visible)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2007, Haiku, Inc.
|
* Copyright (c) 2001-2008, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
* Marc Flerackers ([email protected])
|
* Marc Flerackers ([email protected])
|
||||||
* Stephan Assmus <[email protected]>
|
* Stephan Assmus <[email protected]>
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
|
* Rene Gollent ([email protected])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -102,8 +103,6 @@ BListView::BListView(BMessage* archive)
|
|||||||
fScrollView = NULL;
|
fScrollView = NULL;
|
||||||
fTrack = NULL;
|
fTrack = NULL;
|
||||||
|
|
||||||
fWidth = Bounds().Width();
|
|
||||||
|
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
BMessage subData;
|
BMessage subData;
|
||||||
|
|
||||||
@@ -464,7 +463,6 @@ BListView::MakeFocus(bool focused)
|
|||||||
void
|
void
|
||||||
BListView::FrameResized(float width, float height)
|
BListView::FrameResized(float width, float height)
|
||||||
{
|
{
|
||||||
fWidth = Bounds().right;
|
|
||||||
_FixupScrollBar();
|
_FixupScrollBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,15 +473,13 @@ BListView::TargetedByScrollView(BScrollView *view)
|
|||||||
fScrollView = view;
|
fScrollView = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrollTo
|
||||||
void
|
void
|
||||||
BListView::ScrollTo(BPoint point)
|
BListView::ScrollTo(BPoint point)
|
||||||
{
|
{
|
||||||
BView::ScrollTo(point);
|
BView::ScrollTo(point);
|
||||||
fWidth = Bounds().right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BListView::AddItem(BListItem *item, int32 index)
|
BListView::AddItem(BListItem *item, int32 index)
|
||||||
{
|
{
|
||||||
@@ -502,6 +498,8 @@ BListView::AddItem(BListItem *item, int32 index)
|
|||||||
|
|
||||||
item->Update(this, &font);
|
item->Update(this, &font);
|
||||||
|
|
||||||
|
_RecalcItemTops(index);
|
||||||
|
|
||||||
_FixupScrollBar();
|
_FixupScrollBar();
|
||||||
_InvalidateFrom(index);
|
_InvalidateFrom(index);
|
||||||
}
|
}
|
||||||
@@ -524,6 +522,8 @@ BListView::AddItem(BListItem* item)
|
|||||||
|
|
||||||
item->Update(this, &font);
|
item->Update(this, &font);
|
||||||
|
|
||||||
|
_RecalcItemTops(CountItems() - 1);
|
||||||
|
|
||||||
_FixupScrollBar();
|
_FixupScrollBar();
|
||||||
InvalidateItem(CountItems() - 1);
|
InvalidateItem(CountItems() - 1);
|
||||||
}
|
}
|
||||||
@@ -550,11 +550,10 @@ BListView::AddList(BList* list, int32 index)
|
|||||||
BFont font;
|
BFont font;
|
||||||
GetFont(&font);
|
GetFont(&font);
|
||||||
|
|
||||||
int32 i = 0;
|
for (int32 i = index; i <= (index + list->CountItems() - 1); i++)
|
||||||
while(BListItem *item = (BListItem*)list->ItemAt(i)) {
|
ItemAt(i)->Update(this, &font);
|
||||||
item->Update(this, &font);
|
|
||||||
i++;
|
_RecalcItemTops(index);
|
||||||
}
|
|
||||||
|
|
||||||
_FixupScrollBar();
|
_FixupScrollBar();
|
||||||
Invalidate(); // TODO
|
Invalidate(); // TODO
|
||||||
@@ -590,6 +589,8 @@ BListView::RemoveItem(int32 index)
|
|||||||
if (fLastSelected != -1 && index < fLastSelected)
|
if (fLastSelected != -1 && index < fLastSelected)
|
||||||
fLastSelected--;
|
fLastSelected--;
|
||||||
|
|
||||||
|
_RecalcItemTops(index);
|
||||||
|
|
||||||
_InvalidateFrom(index);
|
_InvalidateFrom(index);
|
||||||
_FixupScrollBar();
|
_FixupScrollBar();
|
||||||
|
|
||||||
@@ -700,14 +701,22 @@ BListView::IndexOf(BListItem *item) const
|
|||||||
int32
|
int32
|
||||||
BListView::IndexOf(BPoint point) const
|
BListView::IndexOf(BPoint point) const
|
||||||
{
|
{
|
||||||
float y = 0.0f;
|
int32 low = 0;
|
||||||
|
int32 high = fList.CountItems() - 1;
|
||||||
// TODO: somehow binary search, but items don't know their frame
|
int32 mid = -1;
|
||||||
for (int i = 0; i < fList.CountItems(); i++) {
|
float frameTop = -1.0;
|
||||||
y += ceilf(ItemAt(i)->Height());
|
float frameBottom = 1.0;
|
||||||
|
// binary search the list
|
||||||
if (point.y < y)
|
while (high >= low) {
|
||||||
return i;
|
mid = (low + high) / 2;
|
||||||
|
frameTop = ItemAt(mid)->Top();
|
||||||
|
frameBottom = ItemAt(mid)->Bottom();
|
||||||
|
if (point.y < frameTop)
|
||||||
|
high = mid - 1;
|
||||||
|
else if (point.y > frameBottom)
|
||||||
|
low = mid + 1;
|
||||||
|
else
|
||||||
|
return mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -955,6 +964,7 @@ BListView::SortItems(int (*cmp)(const void *, const void *))
|
|||||||
}
|
}
|
||||||
|
|
||||||
fList.SortItems(cmp);
|
fList.SortItems(cmp);
|
||||||
|
_RecalcItemTops(0);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,17 +1028,16 @@ BListView::FrameMoved(BPoint new_position)
|
|||||||
BRect
|
BRect
|
||||||
BListView::ItemFrame(int32 index)
|
BListView::ItemFrame(int32 index)
|
||||||
{
|
{
|
||||||
BRect frame(Bounds().left, 0, Bounds().right, -1);
|
BRect frame = Bounds();
|
||||||
|
if (index < 0 || index >= CountItems()) {
|
||||||
if (index < 0 || index >= CountItems())
|
frame.top = 0;
|
||||||
return frame;
|
frame.bottom = -1;
|
||||||
|
} else {
|
||||||
// TODO: this is very expensive, the (last) offsets could be cached
|
BListItem* item = ItemAt(index);
|
||||||
for (int32 i = 0; i <= index; i++) {
|
frame.left = 0.0;
|
||||||
frame.top = frame.bottom + 1;
|
frame.top = item->Top();
|
||||||
frame.bottom = frame.top + ceilf(ItemAt(i)->Height()) - 1;
|
frame.bottom = item->Bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1104,7 +1113,21 @@ BListView::ResizeToPreferred()
|
|||||||
void
|
void
|
||||||
BListView::GetPreferredSize(float *width, float *height)
|
BListView::GetPreferredSize(float *width, float *height)
|
||||||
{
|
{
|
||||||
BView::GetPreferredSize(width, height);
|
int32 count = CountItems();
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
float maxWidth = 0.0;
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
float itemWidth = ItemAt(i)->Width();
|
||||||
|
if (itemWidth > maxWidth)
|
||||||
|
maxWidth = itemWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
*width = maxWidth;
|
||||||
|
*height = ItemAt(count - 1)->Bottom();
|
||||||
|
} else {
|
||||||
|
BView::GetPreferredSize(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllAttached
|
// AllAttached
|
||||||
@@ -1187,7 +1210,6 @@ BListView::_InitObject(list_view_type type)
|
|||||||
fFirstSelected = -1;
|
fFirstSelected = -1;
|
||||||
fLastSelected = -1;
|
fLastSelected = -1;
|
||||||
fAnchorIndex = -1;
|
fAnchorIndex = -1;
|
||||||
fWidth = Bounds().Width();
|
|
||||||
fSelectMessage = NULL;
|
fSelectMessage = NULL;
|
||||||
fScrollView = NULL;
|
fScrollView = NULL;
|
||||||
fTrack = new track_data;
|
fTrack = new track_data;
|
||||||
@@ -1207,9 +1229,10 @@ BListView::_FixupScrollBar()
|
|||||||
BRect bounds = Bounds();
|
BRect bounds = Bounds();
|
||||||
int32 count = CountItems();
|
int32 count = CountItems();
|
||||||
|
|
||||||
float itemHeight = 0;
|
float itemHeight = 0.0;
|
||||||
for (int32 i = 0; i < count; i++)
|
|
||||||
itemHeight += ceilf(ItemAt(i)->Height());
|
if (CountItems() > 0)
|
||||||
|
itemHeight = ItemAt(CountItems() - 1)->Bottom();
|
||||||
|
|
||||||
if (bounds.Height() > itemHeight) {
|
if (bounds.Height() > itemHeight) {
|
||||||
// no scrolling
|
// no scrolling
|
||||||
@@ -1254,9 +1277,9 @@ BListView::_FontChanged()
|
|||||||
{
|
{
|
||||||
BFont font;
|
BFont font;
|
||||||
GetFont(&font);
|
GetFont(&font);
|
||||||
|
for (int32 i = 0; i < CountItems(); i++)
|
||||||
for (int i = 0; i < CountItems (); i ++)
|
|
||||||
ItemAt(i)->Update(this, &font);
|
ItemAt(i)->Update(this, &font);
|
||||||
|
_RecalcItemTops(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1525,6 +1548,8 @@ BListView::_SwapItems(int32 a, int32 b)
|
|||||||
if (Window()) {
|
if (Window()) {
|
||||||
// NOTE: window looper is assumed to be locked!
|
// NOTE: window looper is assumed to be locked!
|
||||||
if (aFrame.Height() != bFrame.Height()) {
|
if (aFrame.Height() != bFrame.Height()) {
|
||||||
|
ItemAt(a)->SetTop(bFrame.top);
|
||||||
|
ItemAt(b)->SetTop(aFrame.top);
|
||||||
// items in between shifted visually
|
// items in between shifted visually
|
||||||
Invalidate(aFrame | bFrame);
|
Invalidate(aFrame | bFrame);
|
||||||
} else {
|
} else {
|
||||||
@@ -1559,6 +1584,8 @@ BListView::_MoveItem(int32 from, int32 to)
|
|||||||
SelectionChanged();
|
SelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_RecalcItemTops((to > from) ? from : to);
|
||||||
|
|
||||||
// take care of invalidation
|
// take care of invalidation
|
||||||
if (Window()) {
|
if (Window()) {
|
||||||
// NOTE: window looper is assumed to be locked!
|
// NOTE: window looper is assumed to be locked!
|
||||||
@@ -1594,6 +1621,7 @@ BListView::_ReplaceItem(int32 index, BListItem *item)
|
|||||||
_RescanSelection(start, end);
|
_RescanSelection(start, end);
|
||||||
SelectionChanged();
|
SelectionChanged();
|
||||||
}
|
}
|
||||||
|
_RecalcItemTops(index);
|
||||||
|
|
||||||
bool itemHeightChanged = frame != ItemFrame(index);
|
bool itemHeightChanged = frame != ItemFrame(index);
|
||||||
|
|
||||||
@@ -1647,4 +1675,18 @@ BListView::_RescanSelection(int32 from, int32 to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BListView::_RecalcItemTops(int32 start)
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
if ((start < 0) || (start >= count))
|
||||||
|
return;
|
||||||
|
float top = (start == 0) ? 0.0 : ItemAt(start - 1)->Bottom() + 1.0;
|
||||||
|
|
||||||
|
for (int32 i = start; i < CountItems(); i++) {
|
||||||
|
BListItem *item = ItemAt(i);
|
||||||
|
item->SetTop(top);
|
||||||
|
top += ceilf(item->Height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2007, Haiku Inc.
|
* Copyright 2001-2008, Haiku Inc.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Marc Flerackers ([email protected])
|
* Marc Flerackers ([email protected])
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
|
* Rene Gollent ([email protected])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! BOutlineListView represents a "nestable" list view.
|
//! BOutlineListView represents a "nestable" list view.
|
||||||
|
|
||||||
#include <OutlineListView.h>
|
#include <OutlineListView.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -35,14 +37,14 @@ quick_sort_item_array(BListItem** items, int32 first, int32 last,
|
|||||||
int32 right = last;
|
int32 right = last;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
while (compareFunc(items[left], pivot) < 0) {
|
while ((compareFunc(items[left], pivot) < 0) && (left < last))
|
||||||
left++;
|
left++;
|
||||||
}
|
|
||||||
while (compareFunc(items[right], pivot) > 0) {
|
|
||||||
right--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left <= right) {
|
while ((compareFunc(items[right], pivot) > 0) && (right > first))
|
||||||
|
right--;
|
||||||
|
|
||||||
|
|
||||||
|
if (left < right) {
|
||||||
// swap entries
|
// swap entries
|
||||||
BListItem* temp = items[left];
|
BListItem* temp = items[left];
|
||||||
items[left] = items[right];
|
items[left] = items[right];
|
||||||
@@ -51,11 +53,14 @@ quick_sort_item_array(BListItem** items, int32 first, int32 last,
|
|||||||
left++;
|
left++;
|
||||||
right--;
|
right--;
|
||||||
}
|
}
|
||||||
} while (left <= right);
|
} while (left < right);
|
||||||
|
|
||||||
|
// if our subset of the array consists of two elements, then we're done recursing
|
||||||
|
if (last - first <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
// At this point, the elements in the left half are all smaller
|
// At this point, the elements in the left half are all smaller
|
||||||
// than the elements in the right half
|
// than the elements in the right half
|
||||||
|
|
||||||
if (first < right) {
|
if (first < right) {
|
||||||
// sort left half
|
// sort left half
|
||||||
quick_sort_item_array(items, first, right, compareFunc);
|
quick_sort_item_array(items, first, right, compareFunc);
|
||||||
@@ -254,16 +259,20 @@ BOutlineListView::AddItem(BListItem* item, int32 fullListIndex)
|
|||||||
bool
|
bool
|
||||||
BOutlineListView::AddList(BList* newItems)
|
BOutlineListView::AddList(BList* newItems)
|
||||||
{
|
{
|
||||||
printf("BOutlineListView::AddList Not implemented\n");
|
return AddList(newItems, FullListCountItems());
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BOutlineListView::AddList(BList* newItems, int32 fullListIndex)
|
BOutlineListView::AddList(BList* newItems, int32 fullListIndex)
|
||||||
{
|
{
|
||||||
printf("BOutlineListView::AddList Not implemented\n");
|
if ((newItems == NULL) || (newItems->CountItems() == 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < newItems->CountItems(); i++)
|
||||||
|
AddItem((BListItem *)newItems->ItemAt(i), fullListIndex + i);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -308,7 +317,12 @@ BOutlineListView::FullListItemAt(int32 fullListIndex) const
|
|||||||
int32
|
int32
|
||||||
BOutlineListView::FullListIndexOf(BPoint point) const
|
BOutlineListView::FullListIndexOf(BPoint point) const
|
||||||
{
|
{
|
||||||
return BListView::IndexOf(point);
|
int32 index = BListView::IndexOf(point);
|
||||||
|
|
||||||
|
if (index > 0)
|
||||||
|
index = FullListIndex(index);
|
||||||
|
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -386,7 +400,7 @@ void
|
|||||||
BOutlineListView::FullListDoForEach(bool (*func)(BListItem* item, void* arg),
|
BOutlineListView::FullListDoForEach(bool (*func)(BListItem* item, void* arg),
|
||||||
void* arg)
|
void* arg)
|
||||||
{
|
{
|
||||||
fList.DoForEach(reinterpret_cast<bool (*)(void*, void*)>(func), arg);
|
fFullList.DoForEach(reinterpret_cast<bool (*)(void*, void*)>(func), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -412,12 +426,12 @@ BOutlineListView::Expand(BListItem* item)
|
|||||||
uint32 level = item->fLevel;
|
uint32 level = item->fLevel;
|
||||||
int32 fullIndex = FullListIndexOf(item);
|
int32 fullIndex = FullListIndexOf(item);
|
||||||
int32 index = IndexOf(item) + 1;
|
int32 index = IndexOf(item) + 1;
|
||||||
|
int32 startIndex = index;
|
||||||
int32 count = FullListCountItems() - fullIndex - 1;
|
int32 count = FullListCountItems() - fullIndex - 1;
|
||||||
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
|
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
|
||||||
|
|
||||||
BFont font;
|
BFont font;
|
||||||
GetFont(&font);
|
GetFont(&font);
|
||||||
|
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
item = items[0];
|
item = items[0];
|
||||||
if (item->fLevel <= level)
|
if (item->fLevel <= level)
|
||||||
@@ -445,7 +459,7 @@ BOutlineListView::Expand(BListItem* item)
|
|||||||
} else
|
} else
|
||||||
items++;
|
items++;
|
||||||
}
|
}
|
||||||
|
_RecalcItemTops(startIndex);
|
||||||
_FixupScrollBar();
|
_FixupScrollBar();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
@@ -462,6 +476,7 @@ BOutlineListView::Collapse(BListItem* item)
|
|||||||
uint32 level = item->fLevel;
|
uint32 level = item->fLevel;
|
||||||
int32 fullIndex = FullListIndexOf(item);
|
int32 fullIndex = FullListIndexOf(item);
|
||||||
int32 index = IndexOf(item);
|
int32 index = IndexOf(item);
|
||||||
|
int32 startIndex = index;
|
||||||
int32 max = FullListCountItems() - fullIndex - 1;
|
int32 max = FullListCountItems() - fullIndex - 1;
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
|
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
|
||||||
@@ -483,6 +498,7 @@ BOutlineListView::Collapse(BListItem* item)
|
|||||||
items++;
|
items++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_RecalcItemTops(startIndex);
|
||||||
// fix selection hints
|
// fix selection hints
|
||||||
// TODO: revise for multi selection lists
|
// TODO: revise for multi selection lists
|
||||||
if (index < fFirstSelected) {
|
if (index < fFirstSelected) {
|
||||||
@@ -615,8 +631,9 @@ BOutlineListView::SortItemsUnder(BListItem* underItem, bool oneLevelOnly,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// only invalidate what may have changed
|
// only invalidate what may have changed
|
||||||
|
_RecalcItemTops(firstIndex);
|
||||||
BRect top = ItemFrame(firstIndex);
|
BRect top = ItemFrame(firstIndex);
|
||||||
BRect bottom = ItemFrame(lastIndex);
|
BRect bottom = ItemFrame(lastIndex - 1);
|
||||||
BRect update(top.left, top.top, bottom.right, bottom.bottom);
|
BRect update(top.left, top.top, bottom.right, bottom.bottom);
|
||||||
Invalidate(update);
|
Invalidate(update);
|
||||||
}
|
}
|
||||||
@@ -798,6 +815,12 @@ BOutlineListView::ItemUnderAt(BListItem* underItem,
|
|||||||
bool
|
bool
|
||||||
BOutlineListView::DoMiscellaneous(MiscCode code, MiscData* data)
|
BOutlineListView::DoMiscellaneous(MiscCode code, MiscData* data)
|
||||||
{
|
{
|
||||||
|
if (code == B_SWAP_OP) {
|
||||||
|
// todo: If we do a swap and the items in question have children, we need
|
||||||
|
// to move the child hierarchy together with the item if we want to correctly
|
||||||
|
// mimic R5 behavior.
|
||||||
|
}
|
||||||
|
|
||||||
return BListView::DoMiscellaneous(code, data);
|
return BListView::DoMiscellaneous(code, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -918,23 +941,18 @@ BOutlineListView::_RemoveItem(BListItem* item, int32 fullIndex)
|
|||||||
|
|
||||||
if (item->IsItemVisible()) {
|
if (item->IsItemVisible()) {
|
||||||
// remove children, too
|
// remove children, too
|
||||||
int32 max = FullListCountItems() - fullIndex - 1;
|
while (fullIndex + 1 < CountItems()) {
|
||||||
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
|
BListItem *subItem = ItemAt(fullIndex + 1);
|
||||||
|
|
||||||
while (max-- > 0) {
|
if (subItem->OutlineLevel() <= level)
|
||||||
BListItem* subItem = items[0];
|
|
||||||
if (subItem->fLevel <= level)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (subItem->IsItemVisible())
|
if (subItem->IsItemVisible())
|
||||||
BListView::RemoveItem(subItem);
|
BListView::RemoveItem(subItem);
|
||||||
|
|
||||||
fFullList.RemoveItem(fullIndex + 1);
|
fFullList.RemoveItem(fullIndex + 1);
|
||||||
|
|
||||||
// TODO: this might be problematic, see comment above
|
|
||||||
delete subItem;
|
delete subItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
BListView::RemoveItem(item);
|
BListView::RemoveItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -946,7 +964,6 @@ BOutlineListView::_RemoveItem(BListItem* item, int32 fullIndex)
|
|||||||
if (child == NULL || child->OutlineLevel() <= super->OutlineLevel())
|
if (child == NULL || child->OutlineLevel() <= super->OutlineLevel())
|
||||||
super->fHasSubitems = false;
|
super->fHasSubitems = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user