1/* 2 * Copyright (c) 1999-2000, Eric Moon. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions, and the following disclaimer. 11 * 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. 15 * 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. 18 * 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. 29 */ 30 31 32// DormantNodeListItem.cpp 33 34#include "DormantNodeListItem.h" 35// InfoWindow 36#include "InfoWindowManager.h" 37// Support 38#include "MediaIcon.h" 39// TipManager 40#include "TipManager.h" 41 42// Application Kit 43#include <Application.h> 44// Interface Kit 45#include <PopUpMenu.h> 46#include <MenuItem.h> 47// Media Kit 48#include <MediaRoster.h> 49#include <MediaAddOn.h> 50 51__USE_CORTEX_NAMESPACE 52 53#include <Debug.h> 54#define D_ALLOC(x) //PRINT (x) // ctor/dtor 55#define D_HOOK(x) //PRINT (x) // BListItem impl. 56#define D_OPERATION(x) //PRINT (x) // operations 57#define D_COMPARE(x) //PRINT (x) // compare functions 58 59// -------------------------------------------------------- // 60// constants 61// -------------------------------------------------------- // 62 63const float DormantNodeListItem::M_ICON_H_MARGIN = 3.0; 64const float DormantNodeListItem::M_ICON_V_MARGIN = 1.0; 65 66// -------------------------------------------------------- // 67// ctor/dtor 68// -------------------------------------------------------- // 69 70DormantNodeListItem::DormantNodeListItem( 71 const dormant_node_info &nodeInfo) 72 : m_info(nodeInfo), 73 m_icon(0) { 74 D_ALLOC(("DormantNodeListItem::DormantNodeListItem()\n")); 75 76 m_icon = new MediaIcon(nodeInfo, B_MINI_ICON); 77} 78 79DormantNodeListItem::~DormantNodeListItem() { 80 D_ALLOC(("DormantNodeListItem::~DormantNodeListItem()\n")); 81 82 delete m_icon; 83} 84 85// -------------------------------------------------------- // 86// BListItem impl. 87// -------------------------------------------------------- // 88 89void DormantNodeListItem::DrawItem( 90 BView *owner, 91 BRect frame, 92 bool drawEverything) { 93 D_HOOK(("DormantNodeListItem::DrawItem()\n")); 94 95 // Draw icon 96 if (m_icon) { 97 BRect r = frame; 98 r.left += M_ICON_H_MARGIN; 99 r.top += (frame.Height() / 2.0) - (B_MINI_ICON / 2.0); 100 r.right = r.left + B_MINI_ICON - 1.0; 101 r.bottom = r.top + B_MINI_ICON - 1.0; 102 if (IsSelected()) { 103 owner->SetHighColor(255, 255, 255, 255); 104 owner->FillRect(r); 105 owner->SetDrawingMode(B_OP_INVERT); 106 owner->DrawBitmap(m_icon, r.LeftTop()); 107 owner->SetDrawingMode(B_OP_ALPHA); 108 owner->SetHighColor(0, 0, 0, 180); 109 owner->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); 110 owner->DrawBitmap(m_icon, r.LeftTop()); 111 owner->SetDrawingMode(B_OP_OVER); 112 } 113 else { 114 owner->SetDrawingMode(B_OP_OVER); 115 owner->DrawBitmap(m_icon, r.LeftTop()); 116 } 117 } 118 119 // Draw label 120 BRect r = frame; 121 r.left += 2 * M_ICON_H_MARGIN + B_MINI_ICON; 122 r.top += (frame.Height() / 2.0) - (m_fontHeight.ascent / 2.0); 123 r.right = r.left + Width(); 124 r.bottom = r.top + m_fontHeight.ascent + m_fontHeight.descent; 125 if (IsSelected() || drawEverything) { 126 if (IsSelected()) { 127 owner->SetHighColor(16, 64, 96, 255); 128 } 129 else { 130 owner->SetHighColor(owner->ViewColor()); 131 } 132 owner->FillRect(r); 133 } 134 if (IsSelected()) { 135 owner->SetHighColor(255, 255, 255, 255); 136 } 137 else { 138 owner->SetHighColor(0, 0, 0, 0); 139 } 140 BPoint labelOffset(r.left + 1.0, r.bottom - m_fontHeight.descent); 141 owner->DrawString(m_info.name, labelOffset); 142 143 // cache the frame rect 144 m_frame = frame; 145} 146 147void DormantNodeListItem::Update( 148 BView *owner, 149 const BFont *font) { 150 D_HOOK(("DormantNodeListItem::Update()\n")); 151 BListItem::Update(owner, font); 152 153 SetWidth(font->StringWidth(m_info.name)); 154 owner->GetFontHeight(&m_fontHeight); 155 float newHeight = m_fontHeight.ascent + m_fontHeight.descent + m_fontHeight.leading; 156 if (newHeight < B_MINI_ICON) { 157 newHeight = B_MINI_ICON; 158 } 159 newHeight += 2 * M_ICON_V_MARGIN; 160 if (Height() < newHeight) { 161 SetHeight(newHeight); 162 } 163} 164 165// -------------------------------------------------------- // 166// BListItem impl. 167// -------------------------------------------------------- // 168 169void DormantNodeListItem::MouseOver( 170 BView *owner, 171 BPoint point, 172 uint32 transit) { 173 D_OPERATION(("DormantNodeListItem::MouseOver()\n")); 174 175 switch (transit) { 176 case B_ENTERED_VIEW: { 177 TipManager *tips = TipManager::Instance(); 178 dormant_flavor_info flavorInfo; 179 BMediaRoster *roster = BMediaRoster::CurrentRoster(); 180 if (roster && roster->GetDormantFlavorInfoFor(info(), &flavorInfo) == B_OK) { 181 BString tip = flavorInfo.info; 182 if (tip == "") { 183 tip = m_info.name; 184 } 185 tips->showTip(tip.String(), owner->ConvertToScreen(m_frame)); 186 } 187 break; 188 } 189 case B_EXITED_VIEW: { 190 TipManager *tips = TipManager::Instance(); 191 tips->hideTip(owner->ConvertToScreen(m_frame)); 192 break; 193 } 194 } 195} 196 197BRect DormantNodeListItem::getRealFrame( 198 const BFont *font) const { 199 D_OPERATION(("DormantNodeListItem::getRealFrame()\n")); 200 201 BRect r(0.0, 0.0, -1.0, -1.0); 202 if (m_frame.IsValid()) { 203 r = m_frame; 204 r.right = r.left + B_MINI_ICON + 2 * M_ICON_H_MARGIN; 205 r.right += font->StringWidth(m_info.name); 206 } 207 else { 208 r.right = font->StringWidth(m_info.name); 209 r.right += B_MINI_ICON + 2 * M_ICON_H_MARGIN + 5.0; 210 font_height fh; 211 font->GetHeight(&fh); 212 r.bottom = fh.ascent + fh.descent + fh.leading; 213 if (r.bottom < B_MINI_ICON) { 214 r.bottom = B_MINI_ICON; 215 } 216 r.bottom += 2 * M_ICON_V_MARGIN; 217 if (Height() > r.bottom) { 218 r.bottom = Height(); 219 } 220 } 221 return r; 222} 223 224BBitmap *DormantNodeListItem::getDragBitmap() { 225 D_OPERATION(("DormantNodeListItem::getDragBitmap()\n")); 226 227 // Prepare Bitmap for Drag & Drop 228 BBitmap *dragBitmap = new BBitmap(m_frame.OffsetToCopy(BPoint(0.0, 0.0)), B_RGBA32, true); 229 dragBitmap->Lock(); { 230 BView *dragView = new BView(dragBitmap->Bounds(), "", B_FOLLOW_NONE, 0); 231 dragBitmap->AddChild(dragView); 232 dragView->SetOrigin(0.0, 0.0); 233 dragView->SetHighColor(0, 0, 0, 0); 234 dragView->FillRect(dragView->Bounds()); 235 dragView->SetDrawingMode(B_OP_ALPHA); 236 dragView->SetHighColor(0, 0, 0, 128); 237 dragView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); 238 // Drawing code back again 239 if (m_icon) { 240 BRect r = dragView->Bounds(); 241 r.left += M_ICON_H_MARGIN; 242 r.top += (m_frame.Height() / 2.0) - (B_MINI_ICON / 2.0); 243 r.right = r.left + B_MINI_ICON - 1.0; 244 r.bottom = r.top + B_MINI_ICON - 1.0; 245 dragView->DrawBitmap(m_icon, r.LeftTop()); 246 } 247 BRect r = dragView->Bounds(); 248 r.left += 2 * M_ICON_H_MARGIN + B_MINI_ICON; 249 r.top += (m_frame.Height() / 2.0) - (m_fontHeight.ascent / 2.0); 250 r.right = r.left + Width(); 251 r.bottom = r.top + m_fontHeight.ascent + m_fontHeight.descent; 252 BPoint labelOffset(r.left + 1.0, r.bottom - m_fontHeight.descent); 253 dragView->DrawString(m_info.name, labelOffset); 254 dragView->Sync(); 255 } 256 dragBitmap->Unlock(); 257 return dragBitmap; 258} 259 260void DormantNodeListItem::showContextMenu( 261 BPoint point, 262 BView *owner) { 263 D_OPERATION(("DormantNodeListItem::showContextMenu()\n")); 264 265 BPopUpMenu *menu = new BPopUpMenu("DormantNodeListItem PopUp", false, false, B_ITEMS_IN_COLUMN); 266 menu->SetFont(be_plain_font); 267 268 // Add the "Get Info" item 269 BMessage *message = new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED); 270 menu->AddItem(new BMenuItem("Get info", message)); 271 272 menu->SetTargetForItems(owner); 273 owner->ConvertToScreen(&point); 274 point -= BPoint(1.0, 1.0); 275 menu->Go(point, true, true, true); 276} 277 278// -------------------------------------------------------- // 279// *** compare functions (friend) 280// -------------------------------------------------------- // 281 282int __CORTEX_NAMESPACE__ compareName( 283 const void *lValue, 284 const void *rValue) { 285 D_COMPARE(("compareSelectionTime()\n")); 286 287 int returnValue = 0; 288 const DormantNodeListItem *lItem = *(reinterpret_cast<const DormantNodeListItem* const*> 289 (reinterpret_cast<const void* const*>(lValue))); 290 const DormantNodeListItem *rItem = *(reinterpret_cast<const DormantNodeListItem* const*> 291 (reinterpret_cast<const void* const*>(rValue))); 292 BString lString = lItem->info().name; 293 lString.ToUpper(); 294 BString rString = rItem->info().name; 295 rString.ToUpper(); 296 if (lString < rString) { 297 returnValue = -1; 298 } 299 else if (lString > rString) { 300 returnValue = 1; 301 } 302 return returnValue; 303} 304 305int __CORTEX_NAMESPACE__ compareAddOnID( 306 const void *lValue, 307 const void *rValue) { 308 D_COMPARE(("compareAddOnID()\n")); 309 310 int returnValue = 0; 311 const DormantNodeListItem *lItem = *(reinterpret_cast<const DormantNodeListItem* const*> 312 (reinterpret_cast<const void* const*>(lValue))); 313 const DormantNodeListItem *rItem = *(reinterpret_cast<const DormantNodeListItem* const*> 314 (reinterpret_cast<const void* const*>(rValue))); 315 if (lItem->info().addon < rItem->info().addon) { 316 returnValue = -1; 317 } 318 else if (lItem->info().addon > rItem->info().addon) { 319 returnValue = 1; 320 } 321 return returnValue; 322} 323 324// END -- DormantNodeListItem.cpp -- 325