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 14static const rgb_color kGreen = (rgb_color){ 116, 224, 0, 255 }; 15 16 17// constructor 18SymbolButton::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 28SymbolButton::~SymbolButton() 29{ 30 delete fSymbol; 31} 32 33 34void 35SymbolButton::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 82BSize 83SymbolButton::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 97BSize 98SymbolButton::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 107void 108SymbolButton::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