1/*
2 * Copyright 2013, Stephan A��mus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6
7#include "BitmapView.h"
8
9#include <algorithm>
10
11#include <Bitmap.h>
12#include <LayoutUtils.h>
13
14
15BitmapView::BitmapView(const char* name)
16	:
17	BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
18	fBitmap(NULL),
19	fScaleBitmap(true)
20{
21}
22
23
24BitmapView::~BitmapView()
25{
26}
27
28
29void
30BitmapView::AllAttached()
31{
32	AdoptParentColors();
33}
34
35
36void
37BitmapView::Draw(BRect updateRect)
38{
39	BRect bounds(Bounds());
40	DrawBackground(bounds, updateRect);
41
42	if (fBitmap == NULL)
43		return;
44
45	BRect bitmapBounds = fBitmap->Bounds();
46	if (bitmapBounds.Width() <= 0.0f || bitmapBounds.Height() <= 0.0f)
47		return;
48
49	float scale = 1.0f;
50
51	if (fScaleBitmap) {
52		float hScale = bounds.Width() / bitmapBounds.Width();
53		float vScale = bounds.Height() / bitmapBounds.Height();
54
55		scale = std::min(hScale, vScale);
56	}
57
58	float width = bitmapBounds.Width() * scale;
59	float height = bitmapBounds.Height() * scale;
60
61	switch (LayoutAlignment().horizontal) {
62		case B_ALIGN_LEFT:
63			break;
64		case B_ALIGN_RIGHT:
65			bounds.left = floorf(bounds.right - width);
66			break;
67		default:
68		case B_ALIGN_HORIZONTAL_CENTER:
69			bounds.left = floorf(bounds.left
70				+ (bounds.Width() - width) / 2.0f);
71			break;
72	}
73	switch (LayoutAlignment().vertical) {
74		case B_ALIGN_TOP:
75			break;
76		case B_ALIGN_BOTTOM:
77			bounds.top = floorf(bounds.bottom - height);
78			break;
79		default:
80		case B_ALIGN_VERTICAL_CENTER:
81			bounds.top = floorf(bounds.top
82				+ (bounds.Height() - height) / 2.0f);
83			break;
84	}
85
86	bounds.right = ceilf(bounds.left + width);
87	bounds.bottom = ceilf(bounds.top + height);
88
89	SetDrawingMode(B_OP_ALPHA);
90	DrawBitmap(fBitmap, bitmapBounds, bounds, B_FILTER_BITMAP_BILINEAR);
91}
92
93
94BSize
95BitmapView::MinSize()
96{
97	BSize size(0.0f, 0.0f);
98
99	if (fBitmap != NULL) {
100		BRect bounds = fBitmap->Bounds();
101		size.width = bounds.Width();
102		size.height = bounds.Height();
103	}
104
105	return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
106}
107
108
109BSize
110BitmapView::PreferredSize()
111{
112	BSize size = MinSize();
113	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size);
114}
115
116
117BSize
118BitmapView::MaxSize()
119{
120	BSize size = MinSize();
121	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
122}
123
124
125void
126BitmapView::SetBitmap(SharedBitmap* bitmap, SharedBitmap::Size bitmapSize)
127{
128	if (bitmap == fReference && bitmapSize == fBitmapSize)
129		return;
130
131	BSize size = MinSize();
132
133	fReference.SetTo(bitmap);
134	fBitmapSize = bitmapSize;
135	fBitmap = bitmap->Bitmap(bitmapSize);
136
137	BSize newSize = MinSize();
138	if (size != newSize)
139		InvalidateLayout();
140
141	Invalidate();
142}
143
144
145void
146BitmapView::UnsetBitmap()
147{
148	if (fReference.Get() == NULL)
149		return;
150
151	fBitmap = NULL;
152	fReference.Unset();
153
154	InvalidateLayout();
155	Invalidate();
156}
157
158
159void
160BitmapView::SetScaleBitmap(bool scaleBitmap)
161{
162	if (scaleBitmap == fScaleBitmap)
163		return;
164
165	fScaleBitmap = scaleBitmap;
166
167	Invalidate();
168}
169
170
171void
172BitmapView::DrawBackground(BRect& bounds, BRect updateRect)
173{
174	FillRect(updateRect, B_SOLID_LOW);
175}
176