[haiku-commits] r34567 - haiku/trunk/src/apps/debuganalyzer/gui

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 8 Dec 2009 22:46:49 +0100 (CET)

Author: bonefish
Date: 2009-12-08 22:46:49 +0100 (Tue, 08 Dec 2009)
New Revision: 34567
Changeset: http://dev.haiku-os.org/changeset/34567/haiku

Added:
   haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.cpp
   haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.h
Modified:
   haiku/trunk/src/apps/debuganalyzer/gui/Jamfile
Log:
Added class ListSelectionModel, representing a selection of list (i.e. indexed)
elements.


Modified: haiku/trunk/src/apps/debuganalyzer/gui/Jamfile
===================================================================
--- haiku/trunk/src/apps/debuganalyzer/gui/Jamfile      2009-12-08 21:44:01 UTC 
(rev 34566)
+++ haiku/trunk/src/apps/debuganalyzer/gui/Jamfile      2009-12-08 21:46:49 UTC 
(rev 34567)
@@ -13,6 +13,7 @@
        AbstractGeneralPage.cpp
        ColorCheckBox.cpp
        HeaderView.cpp
+       ListSelectionModel.cpp
        SubWindow.cpp
        SubWindowManager.cpp
        :

Added: haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.cpp
===================================================================
--- haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.cpp               
                (rev 0)
+++ haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.cpp       
2009-12-08 21:46:49 UTC (rev 34567)
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ListSelectionModel.h"
+
+
+// #pragma mark - ListSelectionModel
+
+
+ListSelectionModel::ListSelectionModel()
+       :
+       fItemCount(0)
+{
+}
+
+
+ListSelectionModel::~ListSelectionModel()
+{
+}
+
+
+void
+ListSelectionModel::Clear()
+{
+       int32 selectedCount = fSelectedItems.Count();
+       if (selectedCount > 0) {
+               int32 firstSelected = fSelectedItems[0];
+               int32 lastSelected = fSelectedItems[selectedCount - 1];
+
+               fSelectedItems.Clear();
+
+               _NotifyItemsDeselected(firstSelected, lastSelected - 
firstSelected + 1);
+       }
+}
+
+
+bool
+ListSelectionModel::SelectItems(int32 itemIndex, int32 count,
+       bool extendSelection)
+{
+       int32 endItemIndex = itemIndex + count;
+
+       int32 index;
+       if (extendSelection) {
+               if (count <= 0)
+                       return true;
+
+               index = _FindItem(itemIndex);
+
+               // count already selected items
+               int32 alreadySelectedCount = _CountSelectedItemsInRange(index,
+                       endItemIndex);
+               if (alreadySelectedCount == count)
+                       return true;
+
+               // make room for the new items
+               if (!fSelectedItems.InsertUninitialized(index + 
alreadySelectedCount,
+                               count - alreadySelectedCount)) {
+                       return false;
+               }
+       } else {
+               // TODO: Don't clear -- just resize to the right size!
+               Clear();
+               if (count <= 0)
+                       return true;
+
+               index = 0;
+               if (!fSelectedItems.AddUninitialized(count))
+                       return false;
+       }
+
+       for (int32 i = 0; i < count; i++)
+               fSelectedItems[index + i] = itemIndex + i;
+
+       _NotifyItemsSelected(itemIndex, count);
+
+       return true;
+}
+
+
+void
+ListSelectionModel::DeselectItems(int32 itemIndex, int32 count)
+{
+       int32 endItemIndex = itemIndex + count;
+       int32 index = _FindItem(itemIndex);
+
+       // count actually selected items
+       int32 actuallySelectedCount = _CountSelectedItemsInRange(index,
+               endItemIndex);
+       if (actuallySelectedCount == 0)
+               return;
+
+       fSelectedItems.Remove(index, actuallySelectedCount);
+
+       _NotifyItemsDeselected(itemIndex, count);
+}
+
+
+void
+ListSelectionModel::ItemsAdded(int32 itemIndex, int32 count)
+{
+       if (count <= 0)
+               return;
+
+       // re-index following items
+       int32 index = _FindItem(itemIndex);
+       int32 selectedCount = fSelectedItems.Count();
+       for (int32 i = index; i < selectedCount; i++)
+               fSelectedItems[i] += count;
+}
+
+
+void
+ListSelectionModel::ItemsRemoved(int32 itemIndex, int32 count)
+{
+       if (count <= 0)
+               return;
+
+       int32 index = _FindItem(itemIndex);
+
+       // count selected items in the range
+       int32 actuallySelectedCount = _CountSelectedItemsInRange(index,
+               itemIndex + count);
+       if (actuallySelectedCount > 0)
+               fSelectedItems.Remove(index, actuallySelectedCount);
+
+       // re-index following items
+       int32 selectedCount = fSelectedItems.Count();
+       for (int32 i = index; i < selectedCount; i++)
+               fSelectedItems[i] -= count;
+}
+
+
+bool
+ListSelectionModel::AddListener(Listener* listener)
+{
+       return fListeners.AddItem(listener);
+}
+
+
+void
+ListSelectionModel::RemoveListener(Listener* listener)
+{
+       fListeners.RemoveItem(listener);
+}
+
+
+int32
+ListSelectionModel::_FindItem(int32 itemIndex) const
+{
+       // binary search the index of the first item >= itemIndex
+       int32 lower = 0;
+       int32 upper = fSelectedItems.Count();
+
+       while (lower < upper) {
+               int32 mid = (lower + upper) / 2;
+
+               if (fSelectedItems[mid] < itemIndex)
+                       lower = mid + 1;
+               else
+                       upper = mid;
+       }
+
+       return lower;
+}
+
+
+int32
+ListSelectionModel::_CountSelectedItemsInRange(int32 index,
+       int32 endItemIndex) const
+{
+       int32 count = 0;
+       int32 selectedCount = fSelectedItems.Count();
+       for (int32 i = index; i < selectedCount; i++) {
+               if (SelectedItemAt(i) >= endItemIndex)
+                       break;
+               count++;
+       }
+
+       return count;
+}
+
+
+void
+ListSelectionModel::_NotifyItemsSelected(int32 index, int32 count)
+{
+       int32 listenerCount = fListeners.CountItems();
+       for (int32 i = listenerCount - 1; i >= 0; i--)
+               fListeners.ItemAt(i)->ItemsSelected(this, index, count);
+}
+
+
+void
+ListSelectionModel::_NotifyItemsDeselected(int32 index, int32 count)
+{
+       int32 listenerCount = fListeners.CountItems();
+       for (int32 i = listenerCount - 1; i >= 0; i--)
+               fListeners.ItemAt(i)->ItemsDeselected(this, index, count);
+}
+
+
+// #pragma mark - Listener
+
+
+ListSelectionModel::Listener::~Listener()
+{
+}
+
+
+void
+ListSelectionModel::Listener::ItemsSelected(ListSelectionModel* model,
+       int32 index, int32 count)
+{
+}
+
+
+void
+ListSelectionModel::Listener::ItemsDeselected(ListSelectionModel* model,
+       int32 index, int32 count)
+{
+}

Added: haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.h
===================================================================
--- haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.h                 
        (rev 0)
+++ haiku/trunk/src/apps/debuganalyzer/gui/ListSelectionModel.h 2009-12-08 
21:46:49 UTC (rev 34567)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef LIST_SELECTION_MODEL_H
+#define LIST_SELECTION_MODEL_H
+
+
+#include <SupportDefs.h>
+
+#include <ObjectList.h>
+
+#include "../debugger/util/Array.h"
+
+
+class ListSelectionModel {
+public:
+                       class Listener;
+
+public:
+                                                               
ListSelectionModel();
+                                                               
~ListSelectionModel();
+
+                       int32                           CountSelectedItems() 
const
+                                                                       { 
return fSelectedItems.Count(); }
+                       int32                           SelectedItemAt(int32 
index) const;
+                       bool                            IsItemSelected(int32 
itemIndex) const;
+
+                       void                            Clear();
+                       bool                            SelectItem(int32 
itemIndex,
+                                                                       bool 
extendSelection);
+                       bool                            SelectItems(int32 
itemIndex, int32 count,
+                                                                       bool 
extendSelection);
+                       void                            DeselectItem(int32 
itemIndex);
+                       void                            DeselectItems(int32 
itemIndex, int32 count);
+
+                       void                            ItemsAdded(int32 
itemIndex, int32 count);
+                       void                            ItemsRemoved(int32 
itemIndex, int32 count);
+
+                       bool                            AddListener(Listener* 
listener);
+                       void                            
RemoveListener(Listener* listener);
+
+private:
+                       typedef BObjectList<Listener> ListenerList;
+
+private:
+                       int32                           _FindItem(int32 
itemIndex) const;
+                       int32                           
_CountSelectedItemsInRange(int32 index,
+                                                                       int32 
endItemIndex) const;
+
+                       void                            
_NotifyItemsSelected(int32 index, int32 count);
+                       void                            
_NotifyItemsDeselected(int32 index,
+                                                                       int32 
count);
+
+private:
+                       int32                           fItemCount;
+                       Array<int32>            fSelectedItems;
+                       ListenerList            fListeners;
+};
+
+
+class ListSelectionModel::Listener {
+public:
+       virtual                                         ~Listener();
+
+       virtual void                            
ItemsSelected(ListSelectionModel* model,
+                                                                       int32 
index, int32 count);
+       virtual void                            
ItemsDeselected(ListSelectionModel* model,
+                                                                       int32 
index, int32 count);
+};
+
+
+inline bool
+ListSelectionModel::IsItemSelected(int32 itemIndex) const
+{
+       int32 index = _FindItem(itemIndex);
+       return index < fSelectedItems.Count() && fSelectedItems[index] == 
itemIndex;
+}
+
+
+inline int32
+ListSelectionModel::SelectedItemAt(int32 index) const
+{
+       return index >= 0 && index < fSelectedItems.Count()
+               ? fSelectedItems[index] : -1;
+}
+
+
+inline bool
+ListSelectionModel::SelectItem(int32 itemIndex, bool extendSelection)
+{
+       return SelectItems(itemIndex, 1, extendSelection);
+}
+
+
+inline void
+ListSelectionModel::DeselectItem(int32 itemIndex)
+{
+       DeselectItems(itemIndex, 1);
+}
+
+
+#endif // LIST_SELECTION_MODEL_H


Other related posts:

  • » [haiku-commits] r34567 - haiku/trunk/src/apps/debuganalyzer/gui - ingo_weinhold