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