1 /* 2 * Copyright 2010, Stephan Aßmus <superstippi@gmx.de>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "SymbolButton.h" 8 9 #include <GradientLinear.h> 10 #include <LayoutUtils.h> 11 #include <Shape.h> 12 13 14 static const rgb_color kGreen = (rgb_color){ 116, 224, 0, 255 }; 15 16 17 // constructor 18 SymbolButton::SymbolButton(const char* name, BShape* symbolShape, 19 BMessage* message, uint32 borders) 20 : 21 BButton(name, NULL, message), 22 fSymbol(symbolShape), 23 fBorders(borders) 24 { 25 } 26 27 28 SymbolButton::~SymbolButton() 29 { 30 delete fSymbol; 31 } 32 33 34 void 35 SymbolButton::Draw(BRect updateRect) 36 { 37 uint32 flags = be_control_look->Flags(this); 38 rgb_color base = LowColor(); 39 BRect bounds(Bounds()); 40 41 if (fBorders != 0) { 42 be_control_look->DrawButtonFrame(this, bounds, updateRect, base, 43 base, flags & ~BControlLook::B_DISABLED, fBorders); 44 be_control_look->DrawButtonBackground(this, bounds, updateRect, base, 45 flags); 46 } 47 48 if (fSymbol == NULL) 49 return; 50 51 if (IsEnabled()) { 52 if (Value() == B_CONTROL_ON) 53 base = tint_color(base, (B_DARKEN_4_TINT + B_DARKEN_MAX_TINT) / 2); 54 else 55 base = tint_color(base, B_DARKEN_4_TINT); 56 } else { 57 if (Value() == B_CONTROL_ON) 58 base = tint_color(base, B_DARKEN_2_TINT); 59 else 60 base = tint_color(base, B_DARKEN_1_TINT); 61 } 62 63 BPoint offset; 64 offset.x = (bounds.left + bounds.right) / 2; 65 offset.y = (bounds.top + bounds.bottom) / 2; 66 offset.x -= fSymbol->Bounds().Width() / 2; 67 offset.y -= fSymbol->Bounds().Height() / 2; 68 offset.x = floorf(offset.x - fSymbol->Bounds().left); 69 offset.y = ceilf(offset.y - fSymbol->Bounds().top); 70 71 MovePenTo(offset); 72 BGradientLinear gradient; 73 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0); 74 gradient.AddColor(base, 255); 75 gradient.SetStart(offset); 76 offset.y += fSymbol->Bounds().Height(); 77 gradient.SetEnd(offset); 78 FillShape(fSymbol, gradient); 79 } 80 81 82 BSize 83 SymbolButton::MinSize() 84 { 85 if (fSymbol == NULL) 86 return BButton::MinSize(); 87 88 float scale = fBorders != 0 ? 2.5f : 1.0f; 89 90 BSize size; 91 size.width = ceilf(fSymbol->Bounds().Width() * scale); 92 size.height = ceilf(fSymbol->Bounds().Height() * scale); 93 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); 94 } 95 96 97 BSize 98 SymbolButton::MaxSize() 99 { 100 BSize size(MinSize()); 101 if (fBorders != 0) 102 size.width = ceilf(size.width * 1.5f); 103 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size); 104 } 105 106 107 void 108 SymbolButton::SetSymbol(BShape* symbolShape) 109 { 110 BSize oldSize = MinSize(); 111 112 delete fSymbol; 113 fSymbol = symbolShape; 114 115 if (MinSize() != oldSize) 116 InvalidateLayout(); 117 118 Invalidate(); 119 } 120 121