1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/cocoa/table_row_nsimage_cache.h" 6 7#include "base/logging.h" 8#include "ui/gfx/image/image_skia.h" 9#include "ui/gfx/image/image_skia_util_mac.h" 10 11TableRowNSImageCache::TableRowNSImageCache(Table* model) 12 : model_(model), 13 icon_images_([[NSPointerArray alloc] initWithOptions: 14 NSPointerFunctionsStrongMemory | 15 NSPointerFunctionsObjectPersonality]) { 16 int count = model_->RowCount(); 17 [icon_images_ setCount:count]; 18} 19 20TableRowNSImageCache::~TableRowNSImageCache() {} 21 22void TableRowNSImageCache::OnModelChanged() { 23 int count = model_->RowCount(); 24 [icon_images_ setCount:0]; 25 [icon_images_ setCount:count]; 26} 27 28void TableRowNSImageCache::OnItemsChanged(int start, int length) { 29 DCHECK_LE(start + length, static_cast<int>([icon_images_ count])); 30 for (int i = start; i < (start + length); ++i) { 31 [icon_images_ replacePointerAtIndex:i withPointer:NULL]; 32 } 33 DCHECK_EQ(model_->RowCount(), 34 static_cast<int>([icon_images_ count])); 35} 36 37void TableRowNSImageCache::OnItemsAdded(int start, int length) { 38 DCHECK_LE(start, static_cast<int>([icon_images_ count])); 39 40 // -[NSPointerArray insertPointer:atIndex:] throws if index == count. 41 // Instead expand the array with NULLs. 42 if (start == static_cast<int>([icon_images_ count])) { 43 [icon_images_ setCount:start + length]; 44 } else { 45 for (int i = 0; i < length; ++i) { 46 [icon_images_ insertPointer:NULL atIndex:start]; // Values slide up. 47 } 48 } 49 DCHECK_EQ(model_->RowCount(), 50 static_cast<int>([icon_images_ count])); 51} 52 53void TableRowNSImageCache::OnItemsRemoved(int start, int length) { 54 DCHECK_LE(start + length, static_cast<int>([icon_images_ count])); 55 for (int i = 0; i < length; ++i) { 56 [icon_images_ removePointerAtIndex:start]; // Values slide down. 57 } 58 DCHECK_EQ(model_->RowCount(), 59 static_cast<int>([icon_images_ count])); 60} 61 62NSImage* TableRowNSImageCache::GetImageForRow(int row) { 63 DCHECK_EQ(model_->RowCount(), 64 static_cast<int>([icon_images_ count])); 65 DCHECK_GE(row, 0); 66 DCHECK_LT(row, static_cast<int>([icon_images_ count])); 67 NSImage* image = static_cast<NSImage*>([icon_images_ pointerAtIndex:row]); 68 if (!image) { 69 const gfx::ImageSkia image_skia_icon = 70 model_->GetIcon(row); 71 // This means GetIcon() will get called until it returns a non-empty image. 72 // Empty images are intentionally not cached. 73 if (!image_skia_icon.isNull()) { 74 image = gfx::NSImageFromImageSkia(image_skia_icon); 75 DCHECK(image); 76 [icon_images_ replacePointerAtIndex:row withPointer:image]; 77 } 78 } 79 return image; 80} 81 82