xref: /haiku/src/apps/haikudepot/ui_generic/BitmapView.cpp (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
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 
15 BitmapView::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 
24 BitmapView::~BitmapView()
25 {
26 }
27 
28 
29 void
30 BitmapView::AllAttached()
31 {
32 	AdoptParentColors();
33 }
34 
35 
36 void
37 BitmapView::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_OVER);
90 	DrawBitmap(fBitmap, bitmapBounds, bounds, B_FILTER_BITMAP_BILINEAR);
91 }
92 
93 
94 BSize
95 BitmapView::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 
109 BSize
110 BitmapView::PreferredSize()
111 {
112 	BSize size = MinSize();
113 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size);
114 }
115 
116 
117 BSize
118 BitmapView::MaxSize()
119 {
120 	BSize size = MinSize();
121 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
122 }
123 
124 
125 void
126 BitmapView::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 
145 void
146 BitmapView::UnsetBitmap()
147 {
148 	if (fReference.Get() == NULL)
149 		return;
150 
151 	fBitmap = NULL;
152 	fReference.Unset();
153 
154 	InvalidateLayout();
155 	Invalidate();
156 }
157 
158 
159 void
160 BitmapView::SetScaleBitmap(bool scaleBitmap)
161 {
162 	if (scaleBitmap == fScaleBitmap)
163 		return;
164 
165 	fScaleBitmap = scaleBitmap;
166 
167 	Invalidate();
168 }
169 
170 
171 void
172 BitmapView::DrawBackground(BRect& bounds, BRect updateRect)
173 {
174 	FillRect(updateRect, B_SOLID_LOW);
175 }
176