2 * Copyright (c) 1999-2000, Eric Moon.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // DormantNodeView.cpp
34 #include "DormantNodeView.h"
36 #include "DormantNodeWindow.h"
37 #include "DormantNodeListItem.h"
39 #include "InfoWindowManager.h"
45 #include <ScrollBar.h>
47 #include <MediaRoster.h>
51 __USE_CORTEX_NAMESPACE
54 #define D_ALLOC(x) //PRINT (x) // ctor/dtor
55 #define D_HOOK(x) //PRINT (x) // BListView impl.
56 #define D_MESSAGE(x) //PRINT (x) // MessageReceived()
57 #define D_INTERNAL(x) //PRINT (x) // internal operations
59 // -------------------------------------------------------- //
61 // -------------------------------------------------------- //
63 DormantNodeView::DormantNodeView(
67 : BListView(frame
, name
, B_SINGLE_SELECTION_LIST
, resizeMode
),
69 D_ALLOC(("DormantNodeView::DormantNodeView()\n"));
73 DormantNodeView::~DormantNodeView() {
74 D_ALLOC(("DormantNodeView::~DormantNodeView()\n"));
78 // -------------------------------------------------------- //
79 // BListView impl. (public)
80 // -------------------------------------------------------- //
82 void DormantNodeView::AttachedToWindow() {
83 D_HOOK(("DormantNodeView::AttachedToWindow()\n"));
88 // Start watching the MediaRoster for flavor changes
89 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
91 BMessenger
messenger(this, Window());
92 roster
->StartWatching(messenger
, B_MEDIA_FLAVORS_CHANGED
);
96 void DormantNodeView::DetachedFromWindow() {
97 D_HOOK(("DormantNodeView::DetachedFromWindow()\n"));
99 // delete the lists contents
102 // Stop watching the MediaRoster for flavor changes
103 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
105 BMessenger
messenger(this, Window());
106 roster
->StopWatching(messenger
, B_MEDIA_FLAVORS_CHANGED
);
110 void DormantNodeView::GetPreferredSize(
113 D_HOOK(("DormantNodeView::GetPreferredSize()\n"));
115 // calculate the accumulated size of all list items
118 for (int32 i
= 0; i
< CountItems(); i
++) {
119 DormantNodeListItem
*item
;
120 item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(i
));
122 BRect r
= item
->getRealFrame(be_plain_font
);
123 if (r
.Width() > *width
) {
126 *height
+= r
.Height() + 1.0;
131 void DormantNodeView::MessageReceived(
133 D_MESSAGE(("DormantNodeView::MessageReceived()\n"));
135 switch (message
->what
) {
136 case B_MEDIA_FLAVORS_CHANGED
: {
137 D_MESSAGE((" -> B_MEDIA_FLAVORS_CHANGED\n"));
139 // init & re-populate the list
141 if (message
->FindInt32("be:addon_id", &addOnID
) != B_OK
) {
142 D_MESSAGE((" -> messages doesn't contain 'be:addon_id'!\n"));
145 _updateList(addOnID
);
148 case InfoWindowManager::M_INFO_WINDOW_REQUESTED
: {
149 D_MESSAGE((" -> InfoWindowManager::M_INFO_WINDOW_REQUESTED)\n"));
151 DormantNodeListItem
*item
;
152 item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(CurrentSelection()));
154 InfoWindowManager
*manager
= InfoWindowManager::Instance();
155 if (manager
&& manager
->Lock()) {
156 manager
->openWindowFor(item
->info());
163 _inherited::MessageReceived(message
);
168 void DormantNodeView::MouseDown(
170 D_HOOK(("DormantNodeView::MouseDown()\n"));
172 BMessage
* message
= Window()->CurrentMessage();
173 int32 buttons
= message
->FindInt32("buttons");
174 if (buttons
== B_SECONDARY_MOUSE_BUTTON
) {
176 if ((index
= IndexOf(point
)) >= 0) {
177 DormantNodeListItem
*item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(index
));
180 BRect r
= item
->getRealFrame(be_plain_font
);
181 if (r
.Contains(point
)) {
182 item
->showContextMenu(point
, this);
188 _inherited::MouseDown(point
);
191 void DormantNodeView::MouseMoved(
194 const BMessage
*message
) {
195 D_HOOK(("DormantNodeView::MouseMoved()\n"));
198 if (!message
&& ((index
= IndexOf(point
)) >= 0)) {
199 DormantNodeListItem
*item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(index
));
200 DormantNodeListItem
*last
= dynamic_cast<DormantNodeListItem
*>(m_lastItemUnder
);
201 BRect r
= item
->getRealFrame(be_plain_font
);
202 if (item
&& r
.Contains(point
)) {
205 last
->MouseOver(this, point
, B_EXITED_VIEW
);
206 item
->MouseOver(this, point
, B_ENTERED_VIEW
);
207 m_lastItemUnder
= item
;
210 item
->MouseOver(this, point
, B_INSIDE_VIEW
);
214 last
->MouseOver(this, point
, B_EXITED_VIEW
);
218 _inherited::MouseMoved(point
, transit
, message
);
221 bool DormantNodeView::InitiateDrag(
225 D_HOOK(("DormantNodeView::InitiateDrag()\n"));
227 DormantNodeListItem
*item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(CurrentSelection()));
229 BMessage
dragMsg(M_INSTANTIATE_NODE
);
230 dragMsg
.AddData("which", B_RAW_TYPE
,
231 reinterpret_cast<const void *>(&item
->info()),
232 sizeof(item
->info()));
233 point
-= ItemFrame(index
).LeftTop();
234 DragMessage(&dragMsg
, item
->getDragBitmap(), B_OP_ALPHA
, point
);
240 // -------------------------------------------------------- //
241 // internal operations (private)
242 // -------------------------------------------------------- //
244 void DormantNodeView::_populateList() {
245 D_INTERNAL(("DormantNodeView::_populateList()\n"));
247 // init the resizable node-info buffer
248 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
249 const int32 bufferInc
= 64;
250 int32 bufferSize
= bufferInc
;
251 dormant_node_info
*infoBuffer
= new dormant_node_info
[bufferSize
];
256 numNodes
= bufferSize
;
257 status_t error
= roster
->GetDormantNodes(infoBuffer
, &numNodes
);
261 if (numNodes
< bufferSize
) {
265 // reallocate buffer & try again
266 delete [] infoBuffer
;
267 bufferSize
+= bufferInc
;
268 infoBuffer
= new dormant_node_info
[bufferSize
];
272 for (int32 i
= 0; i
< numNodes
; i
++) {
273 DormantNodeListItem
*item
= new DormantNodeListItem(infoBuffer
[i
]);
276 SortItems(compareName
);
279 void DormantNodeView::_freeList() {
280 D_HOOK(("DormantNodeView::_freeList()\n"));
282 // remove and delete all items in the list
283 while (CountItems() > 0) {
284 BListItem
*item
= ItemAt(0);
285 if (RemoveItem(item
)) {
291 void DormantNodeView::_updateList(
293 D_INTERNAL(("DormantNodeView::_updateList(%ld)\n", addOnID
));
295 // init the resizable node-info buffer
296 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
297 const int32 bufferInc
= 64;
298 int32 bufferSize
= bufferInc
;
299 dormant_node_info
*infoBuffer
= new dormant_node_info
[bufferSize
];
304 numNodes
= bufferSize
;
305 status_t error
= roster
->GetDormantNodes(infoBuffer
, &numNodes
);
309 if (numNodes
< bufferSize
) {
313 // reallocate buffer & try again
314 delete [] infoBuffer
;
315 bufferSize
+= bufferInc
;
316 infoBuffer
= new dormant_node_info
[bufferSize
];
319 // sort the list by add-on id to avoid multiple searches through
321 SortItems(compareAddOnID
);
323 // Remove all nodes managed by this add-on
325 for (start
= 0; start
< CountItems(); start
++) {
326 DormantNodeListItem
*item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(start
));
327 if (item
&& (item
->info().addon
== addOnID
)) {
332 for (int32 i
= start
; start
< CountItems(); i
++) {
333 DormantNodeListItem
*item
= dynamic_cast<DormantNodeListItem
*>(ItemAt(i
));
334 if (!item
|| (item
->info().addon
!= addOnID
)) {
339 RemoveItems(start
, count
);
342 for (int32 i
= 0; i
< numNodes
; i
++) {
343 if (infoBuffer
[i
].addon
!= addOnID
) {
346 AddItem(new DormantNodeListItem(infoBuffer
[i
]));
349 SortItems(compareName
);
352 // END -- DormantNodeView.cpp --