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 } else 47 FillRect(updateRect, B_SOLID_LOW); 48 49 if (fSymbol == NULL) 50 return; 51 52 if (IsEnabled()) { 53 if (Value() == B_CONTROL_ON) 54 base = tint_color(base, (B_DARKEN_4_TINT + B_DARKEN_MAX_TINT) / 2); 55 else 56 base = tint_color(base, B_DARKEN_4_TINT); 57 } else { 58 if (Value() == B_CONTROL_ON) 59 base = tint_color(base, B_DARKEN_2_TINT); 60 else 61 base = tint_color(base, B_DARKEN_1_TINT); 62 } 63 64 BPoint offset; 65 offset.x = (bounds.left + bounds.right) / 2; 66 offset.y = (bounds.top + bounds.bottom) / 2; 67 offset.x -= fSymbol->Bounds().Width() / 2; 68 offset.y -= fSymbol->Bounds().Height() / 2; 69 offset.x = floorf(offset.x - fSymbol->Bounds().left); 70 offset.y = ceilf(offset.y - fSymbol->Bounds().top); 71 72 MovePenTo(offset); 73 BGradientLinear gradient; 74 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0); 75 gradient.AddColor(base, 255); 76 gradient.SetStart(offset); 77 offset.y += fSymbol->Bounds().Height(); 78 gradient.SetEnd(offset); 79 FillShape(fSymbol, gradient); 80 } 81 82 83 BSize 84 SymbolButton::MinSize() 85 { 86 if (fSymbol == NULL) 87 return BButton::MinSize(); 88 89 float scale = fBorders != 0 ? 2.5f : 1.0f; 90 91 BSize size; 92 size.width = ceilf(fSymbol->Bounds().Width() * scale); 93 size.height = ceilf(fSymbol->Bounds().Height() * scale); 94 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); 95 } 96 97 98 BSize 99 SymbolButton::MaxSize() 100 { 101 BSize size(MinSize()); 102 if (fBorders != 0) 103 size.width = ceilf(size.width * 1.5f); 104 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size); 105 } 106 107 108 void 109 SymbolButton::SetSymbol(BShape* symbolShape) 110 { 111 BSize oldSize = MinSize(); 112 113 delete fSymbol; 114 fSymbol = symbolShape; 115 116 if (MinSize() != oldSize) 117 InvalidateLayout(); 118 119 Invalidate(); 120 } 121 122