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