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
24using std::nothrow;
25
26
27IconView::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
38IconView::~IconView()
39{
40	delete fIconBitmap;
41	fIconBitmap = NULL;
42}
43
44
45status_t
46IconView::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
85status_t
86IconView::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
120status_t
121IconView::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
146void
147IconView::DrawIcon(bool draw)
148{
149	if (draw == fDrawIcon)
150		return;
151
152	fDrawIcon = draw;
153	Invalidate();
154}
155
156
157void
158IconView::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
170status_t
171IconView::InitCheck() const
172{
173	if (fIconBitmap == NULL)
174		return B_NO_MEMORY;
175
176	return fIconBitmap->InitCheck();
177}
178
179
180void
181IconView::_SetSize()
182{
183	SetExplicitMinSize(fIconBitmap->Bounds().Size());
184	SetExplicitMaxSize(fIconBitmap->Bounds().Size());
185	SetExplicitPreferredSize(fIconBitmap->Bounds().Size());
186}
187