1 /* 2 * Copyright 2010, Stephan Aßmus <superstippi@gmx.de>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "PlayPauseButton.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 PlayPauseButton::PlayPauseButton(const char* name, 19 BShape* playSymbolShape, BShape* pauseSymbolShape, BMessage* message, 20 uint32 borders) 21 : 22 SymbolButton(name, NULL, message, borders), 23 fPlaySymbol(playSymbolShape), 24 fPauseSymbol(pauseSymbolShape), 25 fPlaybackState(kStopped) 26 { 27 } 28 29 30 PlayPauseButton::~PlayPauseButton() 31 { 32 delete fPlaySymbol; 33 delete fPauseSymbol; 34 } 35 36 37 void 38 PlayPauseButton::Draw(BRect updateRect) 39 { 40 SymbolButton::Draw(updateRect); 41 42 rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); 43 rgb_color active = (rgb_color){ 116, 224, 0, 255 }; 44 45 if (IsEnabled()) { 46 if (Value() == B_CONTROL_ON) 47 base = tint_color(base, (B_DARKEN_4_TINT + B_DARKEN_MAX_TINT) / 2); 48 else 49 base = tint_color(base, B_DARKEN_4_TINT); 50 } else { 51 if (Value() == B_CONTROL_ON) 52 base = tint_color(base, B_DARKEN_2_TINT); 53 else 54 base = tint_color(base, B_DARKEN_1_TINT); 55 } 56 BRect bounds(Bounds()); 57 BRect pauseBounds = fPauseSymbol->Bounds(); 58 BRect playBounds = fPlaySymbol->Bounds(); 59 60 BPoint offset; 61 float spacing = pauseBounds.Height() / 4; 62 offset.x = (bounds.left + bounds.right) / 2; 63 offset.y = (bounds.top + bounds.bottom) / 2; 64 offset.x -= (pauseBounds.Width() + playBounds.Width() + spacing) / 2; 65 offset.y -= pauseBounds.Height() / 2; 66 offset.x = floorf(offset.x - playBounds.left + 0.5); 67 offset.y = ceilf(offset.y - pauseBounds.top); 68 if (Value() == B_CONTROL_ON) { 69 offset.x += 1; 70 offset.y += 1; 71 } 72 73 bool playActive = IsEnabled() 74 && ((fPlaybackState == kPlaying && Value() == B_CONTROL_OFF) 75 || (fPlaybackState == kPaused && Value() == B_CONTROL_ON)); 76 bool pauseActive = IsEnabled() 77 && ((fPlaybackState == kPaused && Value() == B_CONTROL_OFF) 78 || (fPlaybackState == kPlaying && Value() == B_CONTROL_ON)); 79 80 MovePenTo(offset); 81 BGradientLinear gradient; 82 if (playActive) { 83 gradient.AddColor(active, 0); 84 gradient.AddColor(tint_color(active, B_LIGHTEN_1_TINT), 255); 85 } else { 86 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0); 87 gradient.AddColor(base, 255); 88 } 89 gradient.SetStart(offset); 90 offset.y += playBounds.Height(); 91 gradient.SetEnd(offset); 92 FillShape(fPlaySymbol, gradient); 93 if (playActive) { 94 SetHighColor(tint_color(active, B_DARKEN_3_TINT)); 95 MovePenBy(0.5, 0.5); 96 StrokeShape(fPlaySymbol); 97 } 98 99 offset.y -= playBounds.Height(); 100 offset.x += ceilf(playBounds.Width() + spacing); 101 MovePenTo(offset); 102 gradient.MakeEmpty(); 103 if (pauseActive) { 104 gradient.AddColor(active, 0); 105 gradient.AddColor(tint_color(active, B_LIGHTEN_1_TINT), 255); 106 } else { 107 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0); 108 gradient.AddColor(base, 255); 109 } 110 gradient.SetStart(offset); 111 offset.y += playBounds.Height(); 112 gradient.SetEnd(offset); 113 FillShape(fPauseSymbol, gradient); 114 if (pauseActive) { 115 SetHighColor(tint_color(active, B_DARKEN_3_TINT)); 116 MovePenBy(0.5, 0.5); 117 StrokeShape(fPauseSymbol); 118 } 119 } 120 121 122 BSize 123 PlayPauseButton::MinSize() 124 { 125 if (fPauseSymbol == NULL || fPlaySymbol == NULL) 126 return BButton::MinSize(); 127 128 BSize size; 129 size.width = ceilf( 130 (fPlaySymbol->Bounds().Width() + fPauseSymbol->Bounds().Width()) 131 * 2.5f); 132 size.height = ceilf(fPauseSymbol->Bounds().Height() * 2.5f); 133 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); 134 } 135 136 137 BSize 138 PlayPauseButton::MaxSize() 139 { 140 BSize size(MinSize()); 141 size.width = ceilf(size.width * 1.5f); 142 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size); 143 } 144 145 146 void 147 PlayPauseButton::SetPlaying() 148 { 149 _SetPlaybackState(kPlaying); 150 } 151 152 153 void 154 PlayPauseButton::SetPaused() 155 { 156 _SetPlaybackState(kPaused); 157 } 158 159 160 void 161 PlayPauseButton::SetStopped() 162 { 163 _SetPlaybackState(kStopped); 164 } 165 166 167 void 168 PlayPauseButton::SetSymbols(BShape* playSymbolShape, BShape* pauseSymbolShape) 169 { 170 BSize oldSize = MinSize(); 171 172 delete fPlaySymbol; 173 fPlaySymbol = playSymbolShape; 174 delete fPauseSymbol; 175 fPauseSymbol = pauseSymbolShape; 176 177 if (MinSize() != oldSize) 178 InvalidateLayout(); 179 180 Invalidate(); 181 } 182 183 184 void 185 PlayPauseButton::_SetPlaybackState(uint32 state) 186 { 187 if (fPlaybackState == state) 188 return; 189 fPlaybackState = state; 190 Invalidate(); 191 } 192