xref: /haiku/src/kits/tracker/IconCache.h (revision c6433b0b3cf69e9481b4bc46fec636879145d116)
102be5353SAxel Dörfler /*
202be5353SAxel Dörfler Open Tracker License
302be5353SAxel Dörfler 
402be5353SAxel Dörfler Terms and Conditions
502be5353SAxel Dörfler 
602be5353SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
702be5353SAxel Dörfler 
802be5353SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of
902be5353SAxel Dörfler this software and associated documentation files (the "Software"), to deal in
1002be5353SAxel Dörfler the Software without restriction, including without limitation the rights to
1102be5353SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1202be5353SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do
1302be5353SAxel Dörfler so, subject to the following conditions:
1402be5353SAxel Dörfler 
1502be5353SAxel Dörfler The above copyright notice and this permission notice applies to all licensees
1602be5353SAxel Dörfler and shall be included in all copies or substantial portions of the Software.
1702be5353SAxel Dörfler 
1802be5353SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1902be5353SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2002be5353SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2102be5353SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2202be5353SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2302be5353SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2402be5353SAxel Dörfler 
2502be5353SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be
2602be5353SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in
2702be5353SAxel Dörfler this Software without prior written authorization from Be Incorporated.
2802be5353SAxel Dörfler 
2902be5353SAxel Dörfler Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
3002be5353SAxel Dörfler of Be Incorporated in the United States and other countries. Other brand product
3102be5353SAxel Dörfler names are registered trademarks or trademarks of their respective holders.
3202be5353SAxel Dörfler All rights reserved.
3302be5353SAxel Dörfler */
34f2ed4761SJohn Scipione #ifndef _NU_ICON_CACHE_H
35f2ed4761SJohn Scipione #define _NU_ICON_CACHE_H
36b05aa8b5SJohn Scipione 
3702be5353SAxel Dörfler 
3802be5353SAxel Dörfler // Icon cache is used for drawing node icons; it caches icons
3902be5353SAxel Dörfler // and reuses them for successive draws
4002be5353SAxel Dörfler 
4102be5353SAxel Dörfler 
4202be5353SAxel Dörfler #include <Bitmap.h>
43f2ed4761SJohn Scipione #include <ObjectList.h>
4402be5353SAxel Dörfler #include <Mime.h>
4502be5353SAxel Dörfler #include <String.h>
4602be5353SAxel Dörfler 
4702be5353SAxel Dörfler #include "AutoLock.h"
4802be5353SAxel Dörfler #include "OpenHashTable.h"
4902be5353SAxel Dörfler #include "Utilities.h"
5002be5353SAxel Dörfler 
51b05aa8b5SJohn Scipione 
52a51764c5SJohn Scipione // Icon cache splits icons into two caches - the shared cache, likely to
53a51764c5SJohn Scipione // get the most hits and the node cache. Every icon that is found in a
54a51764c5SJohn Scipione // mime-based structure goes into the shared cache, only files that have
55a51764c5SJohn Scipione // their own private icon use the node cache;
56a51764c5SJohn Scipione // Entries are only deleted from the shared cache if an icon for a mime type
57a51764c5SJohn Scipione // changes, this makes async icon drawing easier. Node cache deletes it's
58a51764c5SJohn Scipione // entries whenever a file gets deleted.
5902be5353SAxel Dörfler 
6002be5353SAxel Dörfler // if a view ever uses the cache to draw in async mode, it needs to call
6102be5353SAxel Dörfler // it when it is being destroyed
6202be5353SAxel Dörfler 
6302be5353SAxel Dörfler namespace BPrivate {
6402be5353SAxel Dörfler 
6502be5353SAxel Dörfler class Model;
6602be5353SAxel Dörfler class ModelNodeLazyOpener;
6702be5353SAxel Dörfler class LazyBitmapAllocator;
6802be5353SAxel Dörfler class SharedIconCache;
6902be5353SAxel Dörfler class SharedCacheEntry;
7002be5353SAxel Dörfler 
7102be5353SAxel Dörfler enum IconDrawMode {
729ecf9d1cSIngo Weinhold 	// Different states of icon drawing
7302be5353SAxel Dörfler 	kSelected 					= 0x01,
7402be5353SAxel Dörfler 	kNotFocused					= 0x02,		// Tracker window
7502be5353SAxel Dörfler 	kOpen						= 0x04,		// open folder, trash
7602be5353SAxel Dörfler 	kNotEmpty					= 0x08,		// full trash
7702be5353SAxel Dörfler 	kDisabled					= 0x10,		// inactive nav menu entry
7802be5353SAxel Dörfler 	kActive						= 0x20,		// active home dir, boot volume
7902be5353SAxel Dörfler 	kLink						= 0x40,		// symbolic link
8002be5353SAxel Dörfler 	kTrackerSpecialized			= 0x80,
8102be5353SAxel Dörfler 
8202be5353SAxel Dörfler 	// some common combinations
8302be5353SAxel Dörfler 	kNormalIcon						= 0,
8402be5353SAxel Dörfler 	kSelectedIcon					= kSelected,
8502be5353SAxel Dörfler 	kSelectedInBackgroundIcon		= kSelected | kNotFocused,
8602be5353SAxel Dörfler 	kOpenIcon						= kOpen,
8702be5353SAxel Dörfler 	kOpenSelectedIcon				= kSelected | kOpen,
8802be5353SAxel Dörfler 	kOpenSelectedInBackgroundIcon	= kSelected | kNotFocused | kOpen,
8902be5353SAxel Dörfler 	kFullIcon						= kNotEmpty,
9002be5353SAxel Dörfler 	kFullSelectedIcon				= kNotEmpty | kOpen,
9102be5353SAxel Dörfler 	kDimmedIcon
9202be5353SAxel Dörfler };
9302be5353SAxel Dörfler 
94b05aa8b5SJohn Scipione 
9502be5353SAxel Dörfler #define NORMAL_ICON_ONLY kNormalIcon
9602be5353SAxel Dörfler 	// replace use of these defines with mode once the respective getters
9702be5353SAxel Dörfler 	// can get non-plain icons
9802be5353SAxel Dörfler 
9902be5353SAxel Dörfler 
10002be5353SAxel Dörfler // Where did an icon come from
10102be5353SAxel Dörfler enum IconSource {
10202be5353SAxel Dörfler 	kUnknownSource,
103a51764c5SJohn Scipione 	kUnknownNotFromNode,	// icon origin not known but determined not
104a51764c5SJohn Scipione 							// to be from the node itself
105a51764c5SJohn Scipione 	kTrackerDefault,		// file has no type, Tracker provides generic,
106a51764c5SJohn Scipione 							// folder, symlink or app
10702be5353SAxel Dörfler 	kTrackerSupplied,		// home directory, boot volume, trash, etc.
10802be5353SAxel Dörfler 	kMetaMime,				// from BMimeType
109a51764c5SJohn Scipione 	kPreferredAppForType,	// have a preferred application for a type,
110a51764c5SJohn Scipione 							// has an icon
11102be5353SAxel Dörfler 	kPreferredAppForNode,	// have a preferred application for this node,
11202be5353SAxel Dörfler 							// has an icon
11302be5353SAxel Dörfler 	kVolume,
11402be5353SAxel Dörfler 	kNode
11502be5353SAxel Dörfler };
11602be5353SAxel Dörfler 
117b05aa8b5SJohn Scipione 
11802be5353SAxel Dörfler class IconCacheEntry {
11902be5353SAxel Dörfler 	// aliased entries don't own their icons, just point
12002be5353SAxel Dörfler 	// to some other entry that does
12102be5353SAxel Dörfler 
12202be5353SAxel Dörfler 	// This is used for icons that are defined by a preferred app for
1239ecf9d1cSIngo Weinhold 	// a metamime, types that do not have an icon get to point to
12402be5353SAxel Dörfler 	// generic, etc.
12502be5353SAxel Dörfler 
12602be5353SAxel Dörfler public:
12702be5353SAxel Dörfler 	IconCacheEntry();
12802be5353SAxel Dörfler 	~IconCacheEntry();
12902be5353SAxel Dörfler 
130ae7d51b2SJohn Scipione 	void SetAliasFor(const SharedIconCache* sharedCache,
131ae7d51b2SJohn Scipione 		const SharedCacheEntry* entry);
132ae7d51b2SJohn Scipione 	static IconCacheEntry* ResolveIfAlias(const SharedIconCache* sharedCache,
133ae7d51b2SJohn Scipione 		IconCacheEntry* entry);
134ae7d51b2SJohn Scipione 	IconCacheEntry* ResolveIfAlias(const SharedIconCache* sharedCache);
13502be5353SAxel Dörfler 
13602be5353SAxel Dörfler 	void SetIcon(BBitmap* bitmap, IconDrawMode mode, icon_size size,
13702be5353SAxel Dörfler 		bool create = false);
13802be5353SAxel Dörfler 
13902be5353SAxel Dörfler 	bool HaveIconBitmap(IconDrawMode mode, icon_size size) const;
14002be5353SAxel Dörfler 	bool CanConstructBitmap(IconDrawMode mode, icon_size size) const;
14102be5353SAxel Dörfler 	static bool AlternateModeForIconConstructing(IconDrawMode requestedMode,
14202be5353SAxel Dörfler 		IconDrawMode &alternate, icon_size size);
143a51764c5SJohn Scipione 	BBitmap* ConstructBitmap(BBitmap* constructFrom,
144a51764c5SJohn Scipione 		IconDrawMode requestedMode, IconDrawMode constructFromMode,
145a51764c5SJohn Scipione 		icon_size size, LazyBitmapAllocator*);
14602be5353SAxel Dörfler 	BBitmap* ConstructBitmap(IconDrawMode requestedMode, icon_size size,
14702be5353SAxel Dörfler 		LazyBitmapAllocator*);
14802be5353SAxel Dörfler 		// same as above, always uses normal icon as source
14902be5353SAxel Dörfler 
15002be5353SAxel Dörfler 	bool IconHitTest(BPoint, IconDrawMode, icon_size) const;
15102be5353SAxel Dörfler 		// given a point, returns true if a non-transparent pixel was hit
15202be5353SAxel Dörfler 
15302be5353SAxel Dörfler 	void RetireIcons(BObjectList<BBitmap>* retiredBitmapList);
15402be5353SAxel Dörfler 		// can't just delete icons, they may be still drawing
15502be5353SAxel Dörfler 		// async; instead, put them on the retired list and
15602be5353SAxel Dörfler 		// only delete the list if it grows too much, way after
15702be5353SAxel Dörfler 		// the icon finishes drawing
15802be5353SAxel Dörfler 		//
15902be5353SAxel Dörfler 		// This could fail if we retire a lot of icons (10 * 1024)
16002be5353SAxel Dörfler 		// while we are drawing them, shouldn't be a practical problem
16102be5353SAxel Dörfler 
16202be5353SAxel Dörfler protected:
16302be5353SAxel Dörfler 	BBitmap* IconForMode(IconDrawMode mode, icon_size size) const;
16402be5353SAxel Dörfler 	void SetIconForMode(BBitmap* bitmap, IconDrawMode mode, icon_size size);
16502be5353SAxel Dörfler 
16602be5353SAxel Dörfler 	// list of most common icons
16702be5353SAxel Dörfler 	BBitmap* fLargeIcon;
168*c6433b0bSJohn Scipione 	BBitmap* fHighlightedLargeIcon;
16902be5353SAxel Dörfler 	BBitmap* fMiniIcon;
170*c6433b0bSJohn Scipione 	BBitmap* fHighlightedMiniIcon;
17102be5353SAxel Dörfler 	int32 fAliasForIndex;
17202be5353SAxel Dörfler 
17302be5353SAxel Dörfler 	// list of other icon kinds would be added here
17402be5353SAxel Dörfler 
17502be5353SAxel Dörfler 	friend class SharedIconCache;
17602be5353SAxel Dörfler 	friend class NodeIconCache;
17702be5353SAxel Dörfler };
17802be5353SAxel Dörfler 
179b05aa8b5SJohn Scipione 
18002be5353SAxel Dörfler class SimpleIconCache {
18102be5353SAxel Dörfler public:
18202be5353SAxel Dörfler 	SimpleIconCache(const char*);
18302be5353SAxel Dörfler 	virtual ~SimpleIconCache() {}
18402be5353SAxel Dörfler 
18502be5353SAxel Dörfler 	virtual void Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode mode,
18602be5353SAxel Dörfler 		icon_size size, bool async = false) = 0;
18702be5353SAxel Dörfler 	virtual void Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode,
188b05aa8b5SJohn Scipione 		icon_size, void (*)(BView*, BPoint, BBitmap*, void*),
189b05aa8b5SJohn Scipione 		void* = NULL) = 0;
19002be5353SAxel Dörfler 
19102be5353SAxel Dörfler 	bool Lock();
19202be5353SAxel Dörfler 	void Unlock();
19302be5353SAxel Dörfler 	bool IsLocked() const;
19402be5353SAxel Dörfler 
19502be5353SAxel Dörfler private:
19602be5353SAxel Dörfler 	Benaphore fLock;
19702be5353SAxel Dörfler };
19802be5353SAxel Dörfler 
199b05aa8b5SJohn Scipione 
20002be5353SAxel Dörfler class SharedCacheEntry : public IconCacheEntry {
20102be5353SAxel Dörfler public:
20202be5353SAxel Dörfler 	SharedCacheEntry();
20302be5353SAxel Dörfler 	SharedCacheEntry(const char* fileType, const char* appSignature = 0);
20402be5353SAxel Dörfler 
20502be5353SAxel Dörfler 	void Draw(BView*, BPoint, IconDrawMode mode, icon_size size,
20602be5353SAxel Dörfler 		bool async = false);
20702be5353SAxel Dörfler 
20802be5353SAxel Dörfler 	void Draw(BView*, BPoint, IconDrawMode, icon_size,
20902be5353SAxel Dörfler 		void (*)(BView*, BPoint, BBitmap*, void*), void* = NULL);
21002be5353SAxel Dörfler 
21102be5353SAxel Dörfler 	const char* FileType() const;
21202be5353SAxel Dörfler 	const char* AppSignature() const;
21302be5353SAxel Dörfler 
21402be5353SAxel Dörfler 	// hash table support
21502be5353SAxel Dörfler 	uint32 Hash() const;
21602be5353SAxel Dörfler 	static uint32 Hash(const char* fileType, const char* appSignature = 0);
21702be5353SAxel Dörfler 	bool operator==(const SharedCacheEntry &) const;
21802be5353SAxel Dörfler 	void SetTo(const char* fileType, const char* appSignature = 0);
21902be5353SAxel Dörfler 
22002be5353SAxel Dörfler 	int32 fNext;
22102be5353SAxel Dörfler private:
22202be5353SAxel Dörfler 	BString fFileType;
22302be5353SAxel Dörfler 	BString fAppSignature;
22402be5353SAxel Dörfler 
22502be5353SAxel Dörfler 	friend class SharedIconCache;
22602be5353SAxel Dörfler };
22702be5353SAxel Dörfler 
228b05aa8b5SJohn Scipione 
22902be5353SAxel Dörfler class SharedCacheEntryArray : public OpenHashElementArray<SharedCacheEntry> {
23002be5353SAxel Dörfler 	// SharedIconCache stores all it's elements in this array
23102be5353SAxel Dörfler public:
23202be5353SAxel Dörfler 	SharedCacheEntryArray(int32 initialSize);
23302be5353SAxel Dörfler 	SharedCacheEntry* Add();
23402be5353SAxel Dörfler };
23502be5353SAxel Dörfler 
236b05aa8b5SJohn Scipione 
23702be5353SAxel Dörfler class SharedIconCache : public SimpleIconCache {
23802be5353SAxel Dörfler 	// SharedIconCache is used for icons that come from the mime database
23902be5353SAxel Dörfler public:
24002be5353SAxel Dörfler 	SharedIconCache();
24102be5353SAxel Dörfler 
24202be5353SAxel Dörfler 	virtual void Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode mode,
24302be5353SAxel Dörfler 		icon_size size, bool async = false);
24402be5353SAxel Dörfler 	virtual void Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode,
24502be5353SAxel Dörfler 		icon_size, void (*)(BView*, BPoint, BBitmap*, void*), void* = NULL);
24602be5353SAxel Dörfler 
247a51764c5SJohn Scipione 	SharedCacheEntry* FindItem(const char* fileType,
248a51764c5SJohn Scipione 		const char* appSignature = 0) const;
249a51764c5SJohn Scipione 	SharedCacheEntry* AddItem(const char* fileType,
25002be5353SAxel Dörfler 		const char* appSignature = 0);
251a51764c5SJohn Scipione 	SharedCacheEntry* AddItem(SharedCacheEntry** outstandingEntry,
252a51764c5SJohn Scipione 		const char* fileType, const char* appSignature = 0);
253a51764c5SJohn Scipione 		// same as previous AddItem, updates the pointer to outstandingEntry,
254a51764c5SJohn Scipione 		// because adding to the hash table makes any pending pointer invalid
25502be5353SAxel Dörfler 	void IconChanged(SharedCacheEntry*);
25602be5353SAxel Dörfler 
257ae7d51b2SJohn Scipione 	void SetAliasFor(IconCacheEntry* entry,
258a51764c5SJohn Scipione 		const SharedCacheEntry* original) const;
25902be5353SAxel Dörfler 	IconCacheEntry* ResolveIfAlias(IconCacheEntry* entry) const;
26002be5353SAxel Dörfler 	int32 EntryIndex(const SharedCacheEntry* entry) const;
26102be5353SAxel Dörfler 
26202be5353SAxel Dörfler 	void RemoveAliasesTo(int32 index);
26302be5353SAxel Dörfler 
26402be5353SAxel Dörfler private:
26502be5353SAxel Dörfler 	OpenHashTable<SharedCacheEntry, SharedCacheEntryArray> fHashTable;
26602be5353SAxel Dörfler 	SharedCacheEntryArray fElementArray;
26702be5353SAxel Dörfler 	BObjectList<BBitmap> fRetiredBitmaps;
268a51764c5SJohn Scipione 		// icons are drawn asynchronously, can't just delete them right away,
269a51764c5SJohn Scipione 		// instead have to place them onto the retired bitmap list and wait
270a51764c5SJohn Scipione 		// for the next sync to delete them
27102be5353SAxel Dörfler };
27202be5353SAxel Dörfler 
273b05aa8b5SJohn Scipione 
27402be5353SAxel Dörfler class NodeCacheEntry : public IconCacheEntry {
27502be5353SAxel Dörfler public:
27602be5353SAxel Dörfler 	NodeCacheEntry(bool permanent = false);
27702be5353SAxel Dörfler 	NodeCacheEntry(const node_ref*, bool permanent = false);
27802be5353SAxel Dörfler 	void Draw(BView*, BPoint, IconDrawMode mode, icon_size size,
27902be5353SAxel Dörfler 		bool async = false);
28002be5353SAxel Dörfler 
28102be5353SAxel Dörfler 	void Draw(BView*, BPoint, IconDrawMode, icon_size,
28202be5353SAxel Dörfler 		void (*)(BView*, BPoint, BBitmap*, void*), void* = NULL);
28302be5353SAxel Dörfler 
28402be5353SAxel Dörfler 	const node_ref* Node() const;
28502be5353SAxel Dörfler 
28602be5353SAxel Dörfler 	uint32 Hash() const;
28702be5353SAxel Dörfler 	static uint32 Hash(const node_ref*);
28802be5353SAxel Dörfler 	bool operator==(const NodeCacheEntry&) const;
28902be5353SAxel Dörfler 	void SetTo(const node_ref*);
29002be5353SAxel Dörfler 	void MakePermanent();
29102be5353SAxel Dörfler 	bool Permanent() const;
29202be5353SAxel Dörfler 
29302be5353SAxel Dörfler 	int32 fNext;
29402be5353SAxel Dörfler private:
29502be5353SAxel Dörfler 	node_ref fRef;
29602be5353SAxel Dörfler 	bool fPermanent;
29702be5353SAxel Dörfler 		// special cache entry that has to be deleted explicitly
29802be5353SAxel Dörfler 
29902be5353SAxel Dörfler 	friend class NodeIconCache;
30002be5353SAxel Dörfler };
30102be5353SAxel Dörfler 
302b05aa8b5SJohn Scipione 
30302be5353SAxel Dörfler class NodeCacheEntryArray : public OpenHashElementArray<NodeCacheEntry> {
30402be5353SAxel Dörfler 	// NodeIconCache stores all it's elements in this array
30502be5353SAxel Dörfler public:
30602be5353SAxel Dörfler 	NodeCacheEntryArray(int32 initialSize);
30702be5353SAxel Dörfler 	NodeCacheEntry* Add();
30802be5353SAxel Dörfler };
30902be5353SAxel Dörfler 
310b05aa8b5SJohn Scipione 
31102be5353SAxel Dörfler class NodeIconCache : public SimpleIconCache {
3129ecf9d1cSIngo Weinhold 	// NodeIconCache is used for nodes that define their own icons
31302be5353SAxel Dörfler public:
31402be5353SAxel Dörfler 	NodeIconCache();
31502be5353SAxel Dörfler 
31602be5353SAxel Dörfler 	virtual void Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode,
31702be5353SAxel Dörfler 		icon_size, bool async = false);
31802be5353SAxel Dörfler 
31902be5353SAxel Dörfler 	virtual void Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode,
32002be5353SAxel Dörfler 		icon_size, void (*)(BView*, BPoint, BBitmap*, void*), void* = 0);
32102be5353SAxel Dörfler 
32202be5353SAxel Dörfler 	NodeCacheEntry* FindItem(const node_ref*) const;
32302be5353SAxel Dörfler 	NodeCacheEntry* AddItem(const node_ref*, bool permanent = false);
324a51764c5SJohn Scipione 	NodeCacheEntry* AddItem(NodeCacheEntry** outstandingEntry,
325a51764c5SJohn Scipione 		const node_ref*);
326a51764c5SJohn Scipione 		// same as previous AddItem, updates the pointer to outstandingEntry,
327a51764c5SJohn Scipione 		// because adding to the hash table makes any pending pointer invalid
32802be5353SAxel Dörfler 	void Deleting(const node_ref*);
329a51764c5SJohn Scipione 		// model for this node is getting deleted
330a51764c5SJohn Scipione 		// (not necessarily the node itself)
33102be5353SAxel Dörfler 	void Removing(const node_ref*);
3329ecf9d1cSIngo Weinhold 		// used by permanent NodeIconCache entries, when an entry gets deleted
33302be5353SAxel Dörfler 	void Deleting(const BView*);
33402be5353SAxel Dörfler 	void IconChanged(const Model*);
33502be5353SAxel Dörfler 
33602be5353SAxel Dörfler 	void RemoveAliasesTo(int32 index);
33702be5353SAxel Dörfler 
33802be5353SAxel Dörfler private:
33902be5353SAxel Dörfler 	OpenHashTable<NodeCacheEntry, NodeCacheEntryArray> fHashTable;
34002be5353SAxel Dörfler 	NodeCacheEntryArray fElementArray;
34102be5353SAxel Dörfler };
34202be5353SAxel Dörfler 
343b05aa8b5SJohn Scipione 
34402be5353SAxel Dörfler const int32 kColorTransformTableSize = 256;
34502be5353SAxel Dörfler 
346b05aa8b5SJohn Scipione 
34702be5353SAxel Dörfler class IconCache {
34802be5353SAxel Dörfler public:
34902be5353SAxel Dörfler 	IconCache();
35002be5353SAxel Dörfler 
35102be5353SAxel Dörfler 	void Draw(Model*, BView*, BPoint where, IconDrawMode mode,
35202be5353SAxel Dörfler 		icon_size size, bool async = false);
35302be5353SAxel Dörfler 		// draw an icon for a model, load the icon from the appropriate
35402be5353SAxel Dörfler 		// location if not cached already
35502be5353SAxel Dörfler 
35602be5353SAxel Dörfler 	void SyncDraw(Model*, BView*, BPoint, IconDrawMode,
35702be5353SAxel Dörfler 		icon_size, void (*)(BView*, BPoint, BBitmap*, void*),
35802be5353SAxel Dörfler 		void* passThruState = 0);
35902be5353SAxel Dörfler 		// draw an icon for a model, load the icon from the appropriate
36002be5353SAxel Dörfler 		// location if not cached already; only works for sync draws,
36102be5353SAxel Dörfler 		// once the call returns, the bitmap may be deleted
36202be5353SAxel Dörfler 
36302be5353SAxel Dörfler 	// preload calls used to ensure successive cache hit for the respective
36402be5353SAxel Dörfler 	// icon, used for common tracker types, etc; Not calling these should only
36502be5353SAxel Dörfler 	// cause a slowdown
366b05aa8b5SJohn Scipione 	void Preload(Model*, IconDrawMode mode, icon_size size,
367b05aa8b5SJohn Scipione 		bool permanent = false);
36802be5353SAxel Dörfler 	status_t Preload(const char* mimeType, IconDrawMode mode, icon_size size);
36902be5353SAxel Dörfler 
37002be5353SAxel Dörfler 	void Deleting(const Model*);
37102be5353SAxel Dörfler 		// hook to manage unloading icons for nodes that are going away
37202be5353SAxel Dörfler 	void Removing(const Model* model);
37302be5353SAxel Dörfler 		// used by permanent NodeIconCache entries, when an entry gets
37402be5353SAxel Dörfler 		// deleted
37502be5353SAxel Dörfler 	void Deleting(const BView*);
37602be5353SAxel Dörfler 		// hook to manage deleting draw view caches for views that are
37702be5353SAxel Dörfler 		// going away
37802be5353SAxel Dörfler 
37902be5353SAxel Dörfler 	// icon changed calls, used when a node or a file type has an icon changed
38002be5353SAxel Dörfler 	// the icons for the node/file type will be flushed and re-cached during
38102be5353SAxel Dörfler 	// the next draw
38202be5353SAxel Dörfler 	void IconChanged(Model*);
38302be5353SAxel Dörfler 	void IconChanged(const char* mimeType, const char* appSignature);
38402be5353SAxel Dörfler 
38502be5353SAxel Dörfler 	bool IsIconFrom(const Model*, const char* mimeType,
38602be5353SAxel Dörfler 		const char* appSignature) const;
38702be5353SAxel Dörfler 		// called when metamime database changed to figure out which models
38802be5353SAxel Dörfler 		// to redraw
38902be5353SAxel Dörfler 
39002be5353SAxel Dörfler 	bool IconHitTest(BPoint, const Model*, IconDrawMode, icon_size);
39102be5353SAxel Dörfler 
39202be5353SAxel Dörfler 	// utility calls for building specialized icons
39302be5353SAxel Dörfler 	BBitmap* MakeSelectedIcon(const BBitmap* normal, icon_size,
39402be5353SAxel Dörfler 		LazyBitmapAllocator*);
39502be5353SAxel Dörfler 
39602be5353SAxel Dörfler 	static bool NeedsDeletionNotification(IconSource);
39702be5353SAxel Dörfler 
39802be5353SAxel Dörfler 	static IconCache* sIconCache;
39902be5353SAxel Dörfler 
40002be5353SAxel Dörfler private:
40102be5353SAxel Dörfler 	// shared calls
40202be5353SAxel Dörfler 	IconCacheEntry* Preload(AutoLock<SimpleIconCache>* nodeCache,
40302be5353SAxel Dörfler 		AutoLock<SimpleIconCache>* sharedCache,
40402be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingLockedCache,
40502be5353SAxel Dörfler 		Model*, IconDrawMode mode, icon_size size, bool permanent);
40602be5353SAxel Dörfler 		// preload uses lazy locking, returning the cache we decided
40702be5353SAxel Dörfler 		// to use to get the icon
40802be5353SAxel Dörfler 		// <resultingLockedCache> may be null if we don't care
40902be5353SAxel Dörfler 
41002be5353SAxel Dörfler 	// shared mime-based icon retrieval calls
41102be5353SAxel Dörfler 	IconCacheEntry* GetIconForPreferredApp(const char* mimeTypeSignature,
41202be5353SAxel Dörfler 		const char* preferredApp, IconDrawMode mode, icon_size size,
41302be5353SAxel Dörfler 		 LazyBitmapAllocator*, IconCacheEntry*);
414a51764c5SJohn Scipione 	IconCacheEntry* GetIconFromFileTypes(ModelNodeLazyOpener*,
415a51764c5SJohn Scipione 		IconSource &source, IconDrawMode mode, icon_size size,
416a51764c5SJohn Scipione 		LazyBitmapAllocator*, IconCacheEntry*);
417a51764c5SJohn Scipione 	IconCacheEntry* GetIconFromMetaMime(const char* fileType,
41802be5353SAxel Dörfler 		IconDrawMode mode, icon_size size, LazyBitmapAllocator*,
41902be5353SAxel Dörfler 		IconCacheEntry*);
42002be5353SAxel Dörfler 	IconCacheEntry* GetVolumeIcon(AutoLock<SimpleIconCache>* nodeCache,
42102be5353SAxel Dörfler 		AutoLock<SimpleIconCache>* sharedCache,
42202be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingLockedCache,
42302be5353SAxel Dörfler 		Model*, IconSource&, IconDrawMode mode,
42402be5353SAxel Dörfler 		icon_size size, LazyBitmapAllocator*);
42502be5353SAxel Dörfler 	IconCacheEntry* GetRootIcon(AutoLock<SimpleIconCache>* nodeCache,
42602be5353SAxel Dörfler 		AutoLock<SimpleIconCache>* sharedCache,
42702be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingLockedCache,
42802be5353SAxel Dörfler 		Model*, IconSource&, IconDrawMode mode,
42902be5353SAxel Dörfler 		icon_size size, LazyBitmapAllocator*);
43002be5353SAxel Dörfler 	IconCacheEntry* GetWellKnownIcon(AutoLock<SimpleIconCache> *nodeCache,
43102be5353SAxel Dörfler 		AutoLock<SimpleIconCache>* sharedCache,
43202be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingLockedCache,
43302be5353SAxel Dörfler 		Model*, IconSource&, IconDrawMode mode,
43402be5353SAxel Dörfler 		icon_size size, LazyBitmapAllocator*);
43502be5353SAxel Dörfler 	IconCacheEntry* GetNodeIcon(ModelNodeLazyOpener *,
43602be5353SAxel Dörfler 		AutoLock<SimpleIconCache>* nodeCache,
43702be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingLockedCache,
43802be5353SAxel Dörfler 		Model*, IconSource&, IconDrawMode mode,
439a51764c5SJohn Scipione 		icon_size size, LazyBitmapAllocator*, IconCacheEntry*,
440a51764c5SJohn Scipione 		bool permanent);
44102be5353SAxel Dörfler 	IconCacheEntry* GetGenericIcon(AutoLock<SimpleIconCache>* sharedCache,
44202be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingLockedCache,
44302be5353SAxel Dörfler 		Model*, IconSource&, IconDrawMode mode,
44402be5353SAxel Dörfler 		icon_size size, LazyBitmapAllocator*, IconCacheEntry*);
445a51764c5SJohn Scipione 	IconCacheEntry* GetFallbackIcon(
446a51764c5SJohn Scipione 		AutoLock<SimpleIconCache>* sharedCacheLocker,
44702be5353SAxel Dörfler 		AutoLock<SimpleIconCache>** resultingOpenCache,
44802be5353SAxel Dörfler 		Model* model, IconDrawMode mode, icon_size size,
44902be5353SAxel Dörfler 		LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry);
45002be5353SAxel Dörfler 
45102be5353SAxel Dörfler 	BBitmap* MakeTransformedIcon(const BBitmap*, icon_size,
45202be5353SAxel Dörfler 		int32 colorTransformTable [], LazyBitmapAllocator*);
45302be5353SAxel Dörfler 
45402be5353SAxel Dörfler 	NodeIconCache fNodeCache;
45502be5353SAxel Dörfler 	SharedIconCache fSharedCache;
45602be5353SAxel Dörfler 
457ae7d51b2SJohn Scipione 	void InitHighlightTable();
45802be5353SAxel Dörfler 
459ae7d51b2SJohn Scipione 	int32 fHighlightTable[kColorTransformTableSize];
460ae7d51b2SJohn Scipione 	bool fInitHighlightTable;
461ae7d51b2SJohn Scipione 		// whether or not we need to initialize the highlight table
46202be5353SAxel Dörfler };
46302be5353SAxel Dörfler 
46402be5353SAxel Dörfler 
46502be5353SAxel Dörfler class LazyBitmapAllocator {
46602be5353SAxel Dörfler 	// Utility class used when we aren't sure that we will keep a bitmap,
46702be5353SAxel Dörfler 	// need a bitmap or be able to construct it properly
46802be5353SAxel Dörfler public:
4699ecf9d1cSIngo Weinhold 	LazyBitmapAllocator(icon_size size,
4709ecf9d1cSIngo Weinhold 		color_space colorSpace = kDefaultIconDepth,
47102be5353SAxel Dörfler 		bool preallocate = false);
47202be5353SAxel Dörfler 	~LazyBitmapAllocator();
47302be5353SAxel Dörfler 
47402be5353SAxel Dörfler 	BBitmap* Get();
47502be5353SAxel Dörfler 	BBitmap* Adopt();
47602be5353SAxel Dörfler 
47702be5353SAxel Dörfler private:
47802be5353SAxel Dörfler 	BBitmap* fBitmap;
47902be5353SAxel Dörfler 	icon_size fSize;
48002be5353SAxel Dörfler 	color_space fColorSpace;
48102be5353SAxel Dörfler };
48202be5353SAxel Dörfler 
483b05aa8b5SJohn Scipione 
484b05aa8b5SJohn Scipione // inlines follow
48502be5353SAxel Dörfler 
48602be5353SAxel Dörfler inline const char*
48702be5353SAxel Dörfler SharedCacheEntry::FileType() const
48802be5353SAxel Dörfler {
48902be5353SAxel Dörfler 	return fFileType.String();
49002be5353SAxel Dörfler }
49102be5353SAxel Dörfler 
492b05aa8b5SJohn Scipione 
49302be5353SAxel Dörfler inline const char*
49402be5353SAxel Dörfler SharedCacheEntry::AppSignature() const
49502be5353SAxel Dörfler {
49602be5353SAxel Dörfler 	return fAppSignature.String();
49702be5353SAxel Dörfler }
49802be5353SAxel Dörfler 
499b05aa8b5SJohn Scipione 
50002be5353SAxel Dörfler inline bool
50102be5353SAxel Dörfler IconCache::NeedsDeletionNotification(IconSource from)
50202be5353SAxel Dörfler {
50302be5353SAxel Dörfler 	return from == kNode;
50402be5353SAxel Dörfler }
50502be5353SAxel Dörfler 
506b05aa8b5SJohn Scipione 
50702be5353SAxel Dörfler inline IconCacheEntry*
50802be5353SAxel Dörfler SharedIconCache::ResolveIfAlias(IconCacheEntry* entry) const
50902be5353SAxel Dörfler {
51002be5353SAxel Dörfler 	if (entry->fAliasForIndex < 0)
51102be5353SAxel Dörfler 		return entry;
51202be5353SAxel Dörfler 
51302be5353SAxel Dörfler 	return fHashTable.ElementAt(entry->fAliasForIndex);
51402be5353SAxel Dörfler }
51502be5353SAxel Dörfler 
516b05aa8b5SJohn Scipione 
51702be5353SAxel Dörfler inline int32
51802be5353SAxel Dörfler SharedIconCache::EntryIndex(const SharedCacheEntry* entry) const
51902be5353SAxel Dörfler {
52002be5353SAxel Dörfler 	return fHashTable.ElementIndex(entry);
52102be5353SAxel Dörfler }
52202be5353SAxel Dörfler 
52302be5353SAxel Dörfler } // namespace BPrivate
52402be5353SAxel Dörfler 
52502be5353SAxel Dörfler using namespace BPrivate;
52602be5353SAxel Dörfler 
527f2ed4761SJohn Scipione 
528f2ed4761SJohn Scipione #endif	// _NU_ICON_CACHE_H
529