xref: /haiku/src/kits/shared/IconView.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
1 /*
2  * Copyright 2004-2020, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Adrien Destugues, pulkomandy@pulkomandy.tk
7  *		Michael Wilber
8  */
9 
10 
11 #include "IconView.h"
12 
13 #include <new>
14 #include <stdio.h>
15 #include <string.h>
16 
17 #include <ControlLook.h>
18 #include <Entry.h>
19 #include <IconUtils.h>
20 #include <Node.h>
21 #include <NodeInfo.h>
22 
23 
24 using std::nothrow;
25 
26 
27 IconView::IconView(icon_size iconSize)
28 	:
29 	BView("IconView", B_WILL_DRAW),
30 	fIconSize(iconSize),
31 	fIconBitmap(NULL),
32 	fDrawIcon(false)
33 {
34 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
35 }
36 
37 
38 IconView::~IconView()
39 {
40 	delete fIconBitmap;
41 	fIconBitmap = NULL;
42 }
43 
44 
45 status_t
46 IconView::SetIcon(const BPath& path, icon_size iconSize)
47 {
48 	fDrawIcon = false;
49 
50 	if (iconSize != fIconSize || fIconBitmap == NULL) {
51 		BBitmap* bitmap = new BBitmap(BRect(BPoint(0, 0),
52 			be_control_look->ComposeIconSize(iconSize)), B_RGBA32);
53 		if (bitmap == NULL)
54 			return B_NO_MEMORY;
55 
56 		delete fIconBitmap;
57 		fIconBitmap = bitmap;
58 		fIconSize = iconSize;
59 	}
60 
61 	status_t status = fIconBitmap->InitCheck();
62 	if (status != B_OK)
63 		return status;
64 
65 	BEntry entry(path.Path());
66 	BNode node(&entry);
67 	BNodeInfo info(&node);
68 
69 	status = info.GetTrackerIcon(fIconBitmap,
70 		(icon_size)fIconBitmap->Bounds().IntegerWidth());
71 	if (status != B_OK)
72 		return status;
73 
74 	if (!fIconBitmap->IsValid())
75 		return fIconBitmap->InitCheck();
76 
77 	_SetSize();
78 
79 	fDrawIcon = true;
80 	Invalidate();
81 	return B_OK;
82 }
83 
84 
85 status_t
86 IconView::SetIcon(const uint8_t* data, size_t size, icon_size iconSize)
87 {
88 	fDrawIcon = false;
89 
90 	if (iconSize != fIconSize || fIconBitmap == NULL) {
91 		BBitmap* bitmap = new BBitmap(BRect(BPoint(0, 0),
92 			be_control_look->ComposeIconSize(iconSize)), B_RGBA32);
93 		if (bitmap == NULL)
94 			return B_NO_MEMORY;
95 
96 		delete fIconBitmap;
97 		fIconBitmap = bitmap;
98 		fIconSize = iconSize;
99 	}
100 
101 	status_t status = fIconBitmap->InitCheck();
102 	if (status != B_OK)
103 		return status;
104 
105 	status = BIconUtils::GetVectorIcon(data, size, fIconBitmap);
106 	if (status != B_OK)
107 		return status;
108 
109 	if (!fIconBitmap->IsValid())
110 		return fIconBitmap->InitCheck();
111 
112 	_SetSize();
113 
114 	fDrawIcon = true;
115 	Invalidate();
116 	return B_OK;
117 }
118 
119 
120 status_t
121 IconView::SetIcon(const BBitmap* icon)
122 {
123 	if (icon == NULL) {
124 		fDrawIcon = false;
125 		return B_OK;
126 	}
127 
128 	delete fIconBitmap;
129 	fIconBitmap = new BBitmap(icon);
130 	if (fIconBitmap == NULL)
131 		return B_NO_MEMORY;
132 
133 	status_t status = fIconBitmap->InitCheck();
134 	if (status != B_OK)
135 		return status;
136 
137 	fIconSize = (icon_size)-1;
138 	_SetSize();
139 
140 	fDrawIcon = true;
141 	Invalidate();
142 	return B_OK;
143 }
144 
145 
146 void
147 IconView::DrawIcon(bool draw)
148 {
149 	if (draw == fDrawIcon)
150 		return;
151 
152 	fDrawIcon = draw;
153 	Invalidate();
154 }
155 
156 
157 void
158 IconView::Draw(BRect area)
159 {
160 	if (fDrawIcon && fIconBitmap != NULL) {
161 		SetDrawingMode(B_OP_ALPHA);
162 		SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
163 		DrawBitmap(fIconBitmap);
164 		SetDrawingMode(B_OP_COPY);
165 	} else
166 		BView::Draw(area);
167 }
168 
169 
170 status_t
171 IconView::InitCheck() const
172 {
173 	if (fIconBitmap == NULL)
174 		return B_NO_MEMORY;
175 
176 	return fIconBitmap->InitCheck();
177 }
178 
179 
180 void
181 IconView::_SetSize()
182 {
183 	SetExplicitMinSize(fIconBitmap->Bounds().Size());
184 	SetExplicitMaxSize(fIconBitmap->Bounds().Size());
185 	SetExplicitPreferredSize(fIconBitmap->Bounds().Size());
186 }
187