diff --git a/src/kits/interface/ListItem.cpp b/src/kits/interface/ListItem.cpp index c2d30b7a1c..1fb4560ad6 100644 --- a/src/kits/interface/ListItem.cpp +++ b/src/kits/interface/ListItem.cpp @@ -26,6 +26,8 @@ //------------------------------------------------------------------------------ // Standard Includes ----------------------------------------------------------- +#include +#include // System Includes ------------------------------------------------------------- #include diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index 36ebe244e0..a8d8473231 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -152,7 +152,7 @@ status_t BListView::Archive(BMessage *archive, bool deep) const int32 i = 0; BListItem *item; - while (item = ItemAt(i++)) + while ((item = ItemAt(i++))) { BMessage subData; @@ -174,8 +174,6 @@ status_t BListView::Archive(BMessage *archive, bool deep) const //------------------------------------------------------------------------------ void BListView::Draw(BRect updateRect) { - int index = 0; - for (int i = 0; i < CountItems(); i++) { BRect item_frame = ItemFrame(i); @@ -242,8 +240,6 @@ void BListView::MessageReceived ( BMessage *msg ) { BMessage reply ( B_REPLY ); - int32 count = 0; - for ( int32 i = 0; i < CountItems (); i++ ) if ( ItemAt ( i )->IsSelected () ) reply.AddInt32 ( "result", i ); @@ -733,7 +729,7 @@ int32 BListView::CurrentSelection(int32 index) const if (fFirstSelected == -1) return -1; - if (index = 0) + if (index == 0) return fFirstSelected; for (int32 i = fFirstSelected; i <= fLastSelected; i++) @@ -812,8 +808,10 @@ void BListView::DeselectExcept(int32 start, int32 finish) { if (fFirstSelected == -1 || finish < start) return; + + int32 index; - for (int32 index = fFirstSelected; index < start; ++index) + for (index = fFirstSelected; index < start; ++index) { if (!ItemAt(index)->IsSelected()) { @@ -1297,9 +1295,9 @@ bool BListView::DoSwapItems(int32 a, int32 b) Invalidate(ItemFrame(a)); Invalidate(ItemFrame(b)); - if (fAnchorIndex = a) + if (fAnchorIndex == a) fAnchorIndex = b; - else if (fAnchorIndex = b) + else if (fAnchorIndex == b) fAnchorIndex = a; RescanSelection(a, b); @@ -1362,8 +1360,10 @@ void BListView::RescanSelection(int32 from, int32 to) if (to > fFirstSelected && to > fLastSelected) return;*/ + + int32 i; - for (int32 i = from; i <= to; i++) + for (i = from; i <= to; i++) { if (ItemAt(i)->IsSelected()) { diff --git a/src/kits/interface/OutlineListView.cpp b/src/kits/interface/OutlineListView.cpp new file mode 100644 index 0000000000..7faaa29122 --- /dev/null +++ b/src/kits/interface/OutlineListView.cpp @@ -0,0 +1,742 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: OutlineListView.cpp +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: BOutlineListView represents a "nestable" list view. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +BOutlineListView::BOutlineListView(BRect frame, const char * name, + list_view_type type, uint32 resizeMask, + uint32 flags) + : BListView(frame, name, type, resizeMask, flags) +{ +} +//------------------------------------------------------------------------------ +BOutlineListView::BOutlineListView(BMessage *archive) + : BListView(archive) +{ +} +//------------------------------------------------------------------------------ +BOutlineListView::~BOutlineListView() +{ + fullList.MakeEmpty(); +} +//------------------------------------------------------------------------------ +BArchivable *BOutlineListView::Instantiate(BMessage *archive) +{ + if (validate_instantiation(archive, "BOutlineListView")) + return new BOutlineListView(archive); + else + return NULL; +} +//------------------------------------------------------------------------------ +status_t BOutlineListView::Archive(BMessage *data, bool deep) const +{ + return BListView::Archive(data, deep); +} +//------------------------------------------------------------------------------ +void BOutlineListView::MouseDown(BPoint point) +{ + MakeFocus(); + + int32 index = IndexOf(point); + + if (index != -1) + { + BListItem *item = ItemAt(index); + + if (item->fHasSubitems && + LatchRect (ItemFrame(index ), item->fLevel).Contains(point)) + { + if (item->IsExpanded()) + Collapse(item); + else + Expand(item); + } + else BListView::MouseDown(point); + } +} +//------------------------------------------------------------------------------ +void BOutlineListView::KeyDown(const char *bytes, int32 numBytes) +{ + if (numBytes == 1) + { + switch (bytes[0]) + { + case '+': + { + BListItem *item = ItemAt(CurrentSelection()); + + if ( item && item->fHasSubitems) + Expand(item); + + break; + } + case '-': + { + BListItem *item = ItemAt(CurrentSelection()); + + if (item && item->fHasSubitems) + Collapse(item); + + break; + } + default: + BListView::KeyDown(bytes, numBytes); + } + } + else + BListView::KeyDown(bytes, numBytes); +} +//------------------------------------------------------------------------------ +void BOutlineListView::FrameMoved(BPoint new_position) +{ + BListView::FrameMoved(new_position); +} +//------------------------------------------------------------------------------ +void BOutlineListView::FrameResized(float new_width, float new_height) +{ + BListView::FrameResized(new_width, new_height); +} +//------------------------------------------------------------------------------ +void BOutlineListView::MouseUp(BPoint where) +{ + BListView::MouseUp(where); +} +//------------------------------------------------------------------------------ +bool BOutlineListView::AddUnder(BListItem *item, BListItem *superitem) +{ + fullList.AddItem(item, FullListIndexOf(superitem) + 1); + + item->fLevel = superitem->OutlineLevel() + 1; + superitem->fHasSubitems = true; + + if (superitem->IsItemVisible() && superitem->IsExpanded()) + { + item->SetItemVisible(true); + + int32 index = BListView::IndexOf(superitem); + + BListView::AddItem(item, index + 1); + Invalidate(LatchRect(ItemFrame(index), superitem->OutlineLevel())); + } + else + item->SetItemVisible(false); + + return true; +} +//------------------------------------------------------------------------------ +bool BOutlineListView::AddItem(BListItem *item) +{ + bool result = fullList.AddItem(item); + + if (!result) + return false; + + return BListView::AddItem(item); +} +//------------------------------------------------------------------------------ +bool BOutlineListView::AddItem(BListItem *item, int32 fullListIndex) +{ + if (fullListIndex < 0) + fullListIndex = 0; + else if (fullListIndex > CountItems()) + fullListIndex = CountItems(); + + fullList.AddItem(item, fullListIndex); + + if (item->fLevel > 0) + { + BListItem *super = SuperitemForIndex(fullListIndex, item->fLevel); + + if (!super->IsItemVisible() || !super->IsExpanded()) + return true; + } + + int32 list_index = FindPreviousVisibleIndex(fullListIndex); + + return BListView::AddItem(item, IndexOf(FullListItemAt(list_index)) + 1); +} +//------------------------------------------------------------------------------ +bool BOutlineListView::AddList(BList *newItems) +{ + printf("BOutlineListView::AddList Not implemented\n"); + return false; +} +//------------------------------------------------------------------------------ +bool BOutlineListView::AddList(BList *newItems, int32 fullListIndex) +{ + printf("BOutlineListView::AddList Not implemented\n"); + return false; +} +//------------------------------------------------------------------------------ +bool BOutlineListView::RemoveItem(BListItem *item) +{ + if (!FullListHasItem(item)) + return false; + + fullList.RemoveItem(item); + if (item->fVisible) + BListView::RemoveItem(item); + + // TODO: remove children + + return true; +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::RemoveItem(int32 fullListIndex) +{ + BListItem *item = FullListItemAt(fullListIndex); + + if (item == NULL) + return NULL; + + fullList.RemoveItem(fullListIndex); + if (item->fVisible) + BListView::RemoveItem(item); + + // TODO: remove children + + return item; +} +//------------------------------------------------------------------------------ +bool BOutlineListView::RemoveItems(int32 fullListIndex, int32 count) +{ + printf("BOutlineListView::RemoveItems Not implemented\n"); + + return false; +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::FullListItemAt(int32 fullListIndex) const +{ + return (BListItem*)fullList.ItemAt(fullListIndex); +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::FullListIndexOf(BPoint point) const +{ + return BListView::IndexOf(point); +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::FullListIndexOf(BListItem *item) const +{ + return fullList.IndexOf(item); +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::FullListFirstItem() const +{ + return (BListItem*)fullList.FirstItem(); +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::FullListLastItem() const +{ + return (BListItem*)fullList.LastItem(); +} +//------------------------------------------------------------------------------ +bool BOutlineListView::FullListHasItem(BListItem *item) const +{ + return fullList.HasItem(item); +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::FullListCountItems() const +{ + return fullList.CountItems(); +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::FullListCurrentSelection(int32 index) const +{ + int32 i = BListView::CurrentSelection(index); + BListItem *item = BListView::ItemAt(i); + + if (item) + return fullList.IndexOf(item); + else + return -1; +} +//------------------------------------------------------------------------------ +void BOutlineListView::MakeEmpty() +{ + fullList.MakeEmpty(); + BListView::MakeEmpty(); +} +//------------------------------------------------------------------------------ +bool BOutlineListView::FullListIsEmpty() const +{ + return fullList.IsEmpty(); +} +//------------------------------------------------------------------------------ +void BOutlineListView::FullListDoForEach(bool(*func)(BListItem *)) +{ + printf("BOutlineListView::fullListDoForEach Not implemented\n"); + //fullList.DoForEach(func); +} +//------------------------------------------------------------------------------ +void BOutlineListView::FullListDoForEach(bool (*func)(BListItem *, void *), + void *data) +{ + printf("BOutlineListView::fullListDoForEach Not implemented\n"); + //fullList.DoForEach(func, data); +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::Superitem(const BListItem *item) +{ + int32 index = FullListIndexOf((BListItem*)item); + + if (index == -1) + return NULL; + else + return SuperitemForIndex(index, item->OutlineLevel()); +} +//------------------------------------------------------------------------------ +void BOutlineListView::Expand(BListItem *item) +{ + if (!FullListHasItem(item)) + return; + + if (item->fExpanded) + return; + + item->fExpanded = true; + + uint32 level = item->fLevel, full_index = FullListIndexOf(item), + index = IndexOf(item) + 1, count = FullListCountItems() - full_index - 1; + BListItem **items = (BListItem**)fullList.Items() + full_index + 1; + + BFont font; + GetFont(&font); + + while (count-- > 0 && (*items)->fLevel > level) + { + if (!(*items)->IsItemVisible()) + { + //BListView::AddItem((*items), index++); + fList.AddItem((*items), index++); + (*items)->Update(this,&font); + (*items)->SetItemVisible(true); + } + + // Skip hidden children + if ((*items)->HasSubitems() && !(*items)->IsExpanded()) + { + uint32 level = (*items)->fLevel; + items++; + + while (--count > 0 && (*items)->fLevel > level) + items++; + } + else + items++; + } + + FixupScrollBar(); + Invalidate(); +} +//------------------------------------------------------------------------------ +void BOutlineListView::Collapse(BListItem *item) +{ + if (!FullListHasItem(item)) + return; + + if (!item->fExpanded) + return; + + item->fExpanded = false; + + uint32 level = item->fLevel, full_index = FullListIndexOf(item), + index = IndexOf(item) + 1, count = FullListCountItems() - full_index - 1; + BListItem **items = (BListItem**)fullList.Items() + full_index + 1; + + while (count-- > 0 && (*items)->fLevel > level) + { + if ((*items)->IsItemVisible()) + { + //BListView::RemoveItem ((*items)); + fList.RemoveItem((*items)); + (*items)->SetItemVisible(false); + } + + items++; + } + + FixupScrollBar(); + Invalidate(); +} +//------------------------------------------------------------------------------ +bool BOutlineListView::IsExpanded(int32 fullListIndex) +{ + BListItem *item = FullListItemAt(fullListIndex); + + if (!item) + return false; + + return item->IsExpanded(); +} +//------------------------------------------------------------------------------ +BHandler *BOutlineListView::ResolveSpecifier(BMessage *msg, int32 index, + BMessage *specifier, int32 form, + const char *property) +{ + return BListView::ResolveSpecifier(msg, index, specifier, form, property); +} +//------------------------------------------------------------------------------ +status_t BOutlineListView::GetSupportedSuites(BMessage *data) +{ + return BListView::GetSupportedSuites(data); +} +//------------------------------------------------------------------------------ +status_t BOutlineListView::Perform(perform_code d, void *arg) +{ + return BListView::Perform(d, arg); +} +//------------------------------------------------------------------------------ +void BOutlineListView::ResizeToPreferred() +{ + BListView::ResizeToPreferred(); +} +//------------------------------------------------------------------------------ +void BOutlineListView::GetPreferredSize(float *width, float *height) +{ + BListView::GetPreferredSize(width, height); +} +//------------------------------------------------------------------------------ +void BOutlineListView::MakeFocus(bool state) +{ + BListView::MakeFocus(state); +} +//------------------------------------------------------------------------------ +void BOutlineListView::AllAttached() +{ + BListView::AllAttached(); +} +//------------------------------------------------------------------------------ +void BOutlineListView::AllDetached() +{ + BListView::AllDetached(); +} +//------------------------------------------------------------------------------ +void BOutlineListView::DetachedFromWindow() +{ + BListView::DetachedFromWindow(); +} +//------------------------------------------------------------------------------ +void BOutlineListView::FullListSortItems(int (*compareFunc)(const BListItem *, + const BListItem *)) +{ + //fullList.SortItems(compareFunc); + printf("BOutlineListView::FullListSortItems not implemented\n"); +} +//------------------------------------------------------------------------------ +void BOutlineListView::SortItemsUnder(BListItem *underItem, bool oneLevelOnly, + int (*compareFunc)(const BListItem *, const BListItem*)) +{ + printf("BOutlineListView::SortItemsUnder not implemented\n"); +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::CountItemsUnder(BListItem *underItem, + bool oneLevelOnly) const +{ + int32 i = IndexOf(underItem); + + if (i == -1) + return 0; + + int32 count = 0; + + if (oneLevelOnly) + { + while (i < FullListCountItems()) + { + BListItem *item = FullListItemAt(i); + + // If we jump out of the subtree, return count + if (item->fLevel < underItem->OutlineLevel()) + return count; + + // If the level matches, increase count + if (item->fLevel == underItem->OutlineLevel() + 1) + count++; + + i++; + } + } + else + { + while (i < FullListCountItems()) + { + BListItem *item = FullListItemAt(i); + + // If we jump out of the subtree, return count + if (item->fLevel < underItem->OutlineLevel()) + return count; + + // Increase count + count++; + + i++; + } + } + + return count; +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::EachItemUnder(BListItem *underItem, + bool oneLevelOnly, + BListItem *(*eachFunc)(BListItem *, + void *), void *) +{ + printf("BOutlineListView::EachItemUnder Not implemented\n"); + + return NULL; +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::ItemUnderAt(BListItem *underItem, + bool oneLevelOnly, int32 index) const +{ + int32 i = IndexOf(underItem); + + if (i == -1) + return NULL; + + if (oneLevelOnly) + { + while (i < FullListCountItems()) + { + BListItem *item = FullListItemAt(i); + + // If we jump out of the subtree, return NULL + if (item->fLevel < underItem->OutlineLevel()) + return NULL; + + // If the level matches, check the index + if (item->fLevel == underItem->OutlineLevel() + 1) + { + if (index == 0) + return item; + else + index--; + } + + i++; + } + } + else + { + while (i < FullListCountItems()) + { + BListItem *item = FullListItemAt(i); + + // If we jump out of the subtree, return NULL + if (item->fLevel < underItem->OutlineLevel()) + return NULL; + + // Check the index + if (index == 0) + return item; + else + index--; + + i++; + } + } + + return NULL; +} +//------------------------------------------------------------------------------ +bool BOutlineListView::DoMiscellaneous(MiscCode code, MiscData * data) +{ + return BListView::DoMiscellaneous(code, data); +} +//------------------------------------------------------------------------------ +void BOutlineListView::MessageReceived(BMessage *msg) +{ + BListView::MessageReceived(msg); +} +//------------------------------------------------------------------------------ +void BOutlineListView::_ReservedOutlineListView1() {} +void BOutlineListView::_ReservedOutlineListView2() {} +void BOutlineListView::_ReservedOutlineListView3() {} +void BOutlineListView::_ReservedOutlineListView4() {} +//------------------------------------------------------------------------------ +int32 BOutlineListView::FullListIndex(int32 index) const +{ + BListItem *item = ItemAt(index); + + if (item == NULL) + return -1; + else + return FullListIndexOf(item); +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::ListViewIndex(int32 index) const +{ + BListItem *item = ItemAt(index); + + if (item == NULL) + return -1; + else + return BListView::IndexOf(item); +} +//------------------------------------------------------------------------------ +void BOutlineListView::ExpandOrCollapse(BListItem *underItem, bool expand) +{ +} +//------------------------------------------------------------------------------ +BRect BOutlineListView::LatchRect(BRect itemRect, int32 level) const +{ + return BRect(itemRect.left, itemRect.top, itemRect.left + + (level * 10.0f + 15.0f), itemRect.bottom); +} +//------------------------------------------------------------------------------ +void BOutlineListView::DrawLatch(BRect itemRect, int32 level, bool collapsed, + bool highlighted, bool misTracked) +{ + float left = level * 10.0f; + + if (collapsed) + { + SetHighColor(192, 192, 192); + + FillTriangle(itemRect.LeftTop() + BPoint(left + 4.0f, 2.0f), + itemRect.LeftTop() + BPoint(left + 4.0f, 10.0f), + itemRect.LeftTop() + BPoint(left + 8.0f, 6.0f)); + + SetHighColor(0, 0, 0); + + StrokeTriangle(itemRect.LeftTop() + BPoint(left + 4.0f, 2.0f), + itemRect.LeftTop() + BPoint(left + 4.0f, 10.0f), + itemRect.LeftTop() + BPoint(left + 8.0f, 6.0f)); + } + else + { + SetHighColor(192, 192, 192); + + FillTriangle(itemRect.LeftTop() + BPoint(left + 2.0f, 4.0f), + itemRect.LeftTop() + BPoint(left + 10.0f, 4.0f), + itemRect.LeftTop() + BPoint(left + 6.0f, 8.0f)); + + SetHighColor(0, 0, 0); + + StrokeTriangle(itemRect.LeftTop() + BPoint(left + 2.0f, 4.0f), + itemRect.LeftTop() + BPoint(left + 10.0f, 4.0f), + itemRect.LeftTop() + BPoint(left + 6.0f, 8.0f)); + } +} +//------------------------------------------------------------------------------ +void BOutlineListView::DrawItem(BListItem *item, BRect itemRect, bool complete) +{ + if (item->fHasSubitems) + DrawLatch(itemRect, item->fLevel, !item->IsExpanded(), false, false); + + itemRect.left += (item->fLevel) * 10.0f + 15.0f; + + item->DrawItem(this, itemRect, complete); +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::RemoveCommon(int32 fullListIndex) +{ + return NULL; +} +//------------------------------------------------------------------------------ +BListItem *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) +{ +} +//------------------------------------------------------------------------------ +BListItem *BOutlineListView::SuperitemForIndex(int32 fullListIndex, int32 level) +{ + BListItem *item; + fullListIndex--; + + while (fullListIndex >= 0) + { + if ((item = FullListItemAt(fullListIndex))->OutlineLevel() < + (uint32)level) + return item; + + fullListIndex--; + } + + return NULL; +} +//------------------------------------------------------------------------------ +int32 BOutlineListView::FindPreviousVisibleIndex(int32 fullListIndex) +{ + fullListIndex--; + + while (fullListIndex >= 0) + { + if (FullListItemAt(fullListIndex)->fVisible) + return fullListIndex; + + fullListIndex--; + } + + return -1; +} +//------------------------------------------------------------------------------ + +/* + * $Log $ + * + * $Id $ + * + */