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