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