1 /* 2 * Copyright 2013, Stephan Aßmus <superstippi@gmx.de>. 3 * Copyright 2020-2024, 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 | B_TRANSPARENT_BACKGROUND), 19 fBitmapHolderRef(NULL), 20 fScaleBitmap(true) 21 { 22 SetViewColor(B_TRANSPARENT_COLOR); 23 } 24 25 26 BitmapView::~BitmapView() 27 { 28 } 29 30 31 void 32 BitmapView::Draw(BRect updateRect) 33 { 34 if (!fBitmapHolderRef.IsSet()) 35 return; 36 37 BRect bounds(Bounds()); 38 39 const BBitmap* bitmap = fBitmapHolderRef->Bitmap(); 40 41 BRect bitmapBounds = bitmap->Bounds(); 42 if (bitmapBounds.Width() <= 0.0f || bitmapBounds.Height() <= 0.0f) 43 return; 44 45 float scale = 1.0f; 46 47 if (fScaleBitmap) { 48 float hScale = bounds.Width() / bitmapBounds.Width(); 49 float vScale = bounds.Height() / bitmapBounds.Height(); 50 51 scale = std::min(hScale, vScale); 52 } 53 54 float width = bitmapBounds.Width() * scale; 55 float height = bitmapBounds.Height() * scale; 56 57 switch (LayoutAlignment().horizontal) { 58 case B_ALIGN_LEFT: 59 break; 60 case B_ALIGN_RIGHT: 61 bounds.left = floorf(bounds.right - width); 62 break; 63 default: 64 case B_ALIGN_HORIZONTAL_CENTER: 65 bounds.left = floorf(bounds.left 66 + (bounds.Width() - width) / 2.0f); 67 break; 68 } 69 switch (LayoutAlignment().vertical) { 70 case B_ALIGN_TOP: 71 break; 72 case B_ALIGN_BOTTOM: 73 bounds.top = floorf(bounds.bottom - height); 74 break; 75 default: 76 case B_ALIGN_VERTICAL_CENTER: 77 bounds.top = floorf(bounds.top 78 + (bounds.Height() - height) / 2.0f); 79 break; 80 } 81 82 bounds.right = ceilf(bounds.left + width); 83 bounds.bottom = ceilf(bounds.top + height); 84 85 SetDrawingMode(B_OP_ALPHA); 86 DrawBitmap(bitmap, bitmapBounds, bounds, B_FILTER_BITMAP_BILINEAR); 87 } 88 89 90 BSize 91 BitmapView::MinSize() 92 { 93 BSize size(0.0f, 0.0f); 94 95 if (fBitmapHolderRef.IsSet()) { 96 BRect bounds = fBitmapHolderRef->Bitmap()->Bounds(); 97 size.width = bounds.Width(); 98 size.height = bounds.Height(); 99 } 100 101 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); 102 } 103 104 105 BSize 106 BitmapView::PreferredSize() 107 { 108 BSize size = MinSize(); 109 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size); 110 } 111 112 113 BSize 114 BitmapView::MaxSize() 115 { 116 BSize size = MinSize(); 117 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size); 118 } 119 120 121 void 122 BitmapView::SetBitmap(BitmapHolderRef bitmapHolderRef) 123 { 124 if (bitmapHolderRef == fBitmapHolderRef) 125 return; 126 127 BSize size = MinSize(); 128 fBitmapHolderRef = bitmapHolderRef; 129 130 BSize newSize = MinSize(); 131 if (size != newSize) 132 InvalidateLayout(); 133 134 Invalidate(); 135 } 136 137 138 void 139 BitmapView::UnsetBitmap() 140 { 141 if (!fBitmapHolderRef.IsSet()) 142 return; 143 144 fBitmapHolderRef.Unset(); 145 146 InvalidateLayout(); 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