xref: /haiku/src/apps/haikudepot/ui_generic/BitmapView.cpp (revision 83b1a68c52ba3e0e8796282759f694b7fdddf06d)
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 	SetViewColor(B_TRANSPARENT_COLOR);
22 	SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
23 }
24 
25 
26 BitmapView::~BitmapView()
27 {
28 }
29 
30 
31 void
32 BitmapView::AttachedToWindow()
33 {
34 	BView* parent = Parent();
35 	if (parent != NULL) {
36 		rgb_color color = parent->ViewColor();
37 		if (color == B_TRANSPARENT_COLOR)
38 			color = parent->LowColor();
39 		SetLowColor(color);
40 	}
41 }
42 
43 
44 void
45 BitmapView::Draw(BRect updateRect)
46 {
47 	BRect bounds(Bounds());
48 	DrawBackground(bounds, updateRect);
49 
50 	if (fBitmap == NULL)
51 		return;
52 
53 	BRect bitmapBounds = fBitmap->Bounds();
54 	if (bitmapBounds.Width() <= 0.0f || bitmapBounds.Height() <= 0.0f)
55 		return;
56 
57 	float scale = 1.0f;
58 
59 	if (fScaleBitmap) {
60 		float hScale = bounds.Width() / bitmapBounds.Width();
61 		float vScale = bounds.Height() / bitmapBounds.Height();
62 
63 		scale = std::min(hScale, vScale);
64 	}
65 
66 	float width = bitmapBounds.Width() * scale;
67 	float height = bitmapBounds.Height() * scale;
68 
69 	switch (LayoutAlignment().horizontal) {
70 		case B_ALIGN_LEFT:
71 			break;
72 		case B_ALIGN_RIGHT:
73 			bounds.left = floorf(bounds.right - width);
74 			break;
75 		default:
76 		case B_ALIGN_HORIZONTAL_CENTER:
77 			bounds.left = floorf(bounds.left
78 				+ (bounds.Width() - width) / 2.0f);
79 			break;
80 	}
81 	switch (LayoutAlignment().vertical) {
82 		case B_ALIGN_TOP:
83 			break;
84 		case B_ALIGN_BOTTOM:
85 			bounds.top = floorf(bounds.bottom - height);
86 			break;
87 		default:
88 		case B_ALIGN_VERTICAL_CENTER:
89 			bounds.top = floorf(bounds.top
90 				+ (bounds.Height() - height) / 2.0f);
91 			break;
92 	}
93 
94 	bounds.right = ceilf(bounds.left + width);
95 	bounds.bottom = ceilf(bounds.top + height);
96 
97 	SetDrawingMode(B_OP_OVER);
98 	DrawBitmap(fBitmap, bitmapBounds, bounds, B_FILTER_BITMAP_BILINEAR);
99 }
100 
101 
102 BSize
103 BitmapView::MinSize()
104 {
105 	BSize size(0.0f, 0.0f);
106 
107 	if (fBitmap != NULL) {
108 		BRect bounds = fBitmap->Bounds();
109 		size.width = bounds.Width();
110 		size.height = bounds.Height();
111 	}
112 
113 	return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
114 }
115 
116 
117 BSize
118 BitmapView::PreferredSize()
119 {
120 	BSize size = MinSize();
121 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size);
122 }
123 
124 
125 BSize
126 BitmapView::MaxSize()
127 {
128 	BSize size = MinSize();
129 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
130 }
131 
132 
133 void
134 BitmapView::SetBitmap(const BBitmap* bitmap)
135 {
136 	if (bitmap == fBitmap)
137 		return;
138 
139 	BSize size = MinSize();
140 
141 	fBitmap = bitmap;
142 
143 	BSize newSize = MinSize();
144 	if (size != newSize)
145 		InvalidateLayout();
146 
147 	Invalidate();
148 }
149 
150 
151 void
152 BitmapView::SetScaleBitmap(bool scaleBitmap)
153 {
154 	if (scaleBitmap == fScaleBitmap)
155 		return;
156 
157 	fScaleBitmap = scaleBitmap;
158 
159 	Invalidate();
160 }
161 
162 
163 void
164 BitmapView::DrawBackground(BRect& bounds, BRect updateRect)
165 {
166 	FillRect(updateRect, B_SOLID_LOW);
167 }
168