1/*
2 * Copyright 2005, Jérôme Duval. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers
6 * and Producers)
7 */
8
9#include <stdio.h>
10
11#include "VolumeSlider.h"
12#include "icon_button.h"
13
14#define VOLUME_CHANGED 'vlcg'
15#define RATIO 2.0f
16
17VolumeSlider::VolumeSlider(BRect rect, const char *title, uint32 resizeFlags)
18	: BControl(rect, "slider", NULL, new BMessage(VOLUME_CHANGED),
19		resizeFlags, B_WILL_DRAW),
20	fLeftBitmap(BRect(0, 0, kLeftVolumeWidth - 1, kLeftVolumeHeight - 1),
21		B_CMAP8),
22	fRightBitmap(BRect(0, 0, kRightVolumeWidth - 1, kRightVolumeHeight - 1),
23		B_CMAP8),
24	fButtonBitmap(BRect(0, 0, kThumbWidth - 1, kThumbHeight - 1), B_CMAP8),
25	fSoundPlayer(NULL)
26{
27	fLeftBitmap.SetBits(kLeftVolumeBits, kLeftVolumeWidth * kLeftVolumeHeight,
28		0, B_CMAP8);
29	fRightBitmap.SetBits(kRightVolumeBits, kRightVolumeWidth * kRightVolumeHeight,
30		0, B_CMAP8);
31	fButtonBitmap.SetBits(kThumbBits, kThumbWidth * kThumbHeight, 0, B_CMAP8);
32
33	fRight = Bounds().right - 15;
34}
35
36
37VolumeSlider::~VolumeSlider()
38{
39
40}
41
42
43void
44VolumeSlider::Draw(BRect updateRect)
45{
46	SetHighColor(189, 186, 189);
47	StrokeLine(BPoint(11, 1), BPoint(fRight, 1));
48	SetHighColor(0, 0, 0);
49	StrokeLine(BPoint(11, 2), BPoint(fRight, 2));
50	SetHighColor(255, 255, 255);
51	StrokeLine(BPoint(11, 14), BPoint(fRight, 14));
52	SetHighColor(231, 227, 231);
53	StrokeLine(BPoint(11, 15), BPoint(fRight, 15));
54
55	SetLowColor(ViewColor());
56
57	SetDrawingMode(B_OP_OVER);
58
59	DrawBitmapAsync(&fLeftBitmap, BPoint(5, 1));
60	DrawBitmapAsync(&fRightBitmap, BPoint(fRight + 1, 1));
61
62	float position = 11 + (fRight - 11) * (fSoundPlayer
63		? fSoundPlayer->Volume() / RATIO : 0);
64	SetHighColor(102, 152, 102);
65	FillRect(BRect(11, 3, position, 4));
66	SetHighColor(152, 203, 152);
67	FillRect(BRect(11, 5, position, 13));
68
69	if (fSoundPlayer)
70		SetHighColor(152, 152, 152);
71	else
72		SetHighColor(200, 200, 200);
73	FillRect(BRect(position, 3, fRight, 13));
74
75	SetHighColor(102, 152, 102);
76	for (int i = 15; i <= fRight + 1; i += 5) {
77		if (i > position)
78			SetHighColor(128, 128, 128);
79		StrokeLine(BPoint(i, 8), BPoint(i, 9));
80	}
81
82	DrawBitmapAsync(&fButtonBitmap, BPoint(position - 5, 3));
83
84	Sync();
85
86	SetDrawingMode(B_OP_COPY);
87}
88
89
90void
91VolumeSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
92{
93	if (!IsTracking())
94		return;
95
96	uint32 mouseButtons;
97	BPoint where;
98	GetMouse(&where, &mouseButtons, true);
99
100	// button not pressed, exit
101	if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) {
102		Invoke();
103		SetTracking(false);
104	}
105
106	if (!fSoundPlayer || !Bounds().InsetBySelf(2, 2).Contains(point))
107		return;
108
109	_UpdateVolume(point);
110}
111
112
113void
114VolumeSlider::MouseDown(BPoint point)
115{
116	if (!fSoundPlayer || !Bounds().InsetBySelf(2, 2).Contains(point))
117		return;
118
119	_UpdateVolume(point);
120	SetTracking(true);
121	SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
122}
123
124
125void
126VolumeSlider::MouseUp(BPoint point)
127{
128	if (!IsTracking())
129		return;
130	if (fSoundPlayer && Bounds().InsetBySelf(2, 2).Contains(point)) {
131		_UpdateVolume(point);
132	}
133
134	Invoke();
135	SetTracking(false);
136	Draw(Bounds());
137	Flush();
138}
139
140
141void
142VolumeSlider::_UpdateVolume(BPoint point)
143{
144	fVolume = MIN(MAX(point.x, 11), fRight);
145	fVolume = (fVolume - 11) / (fRight - 11);
146	fVolume = MAX(MIN(fVolume,1), 0);
147	Draw(Bounds());
148	Flush();
149	if (fSoundPlayer)
150		fSoundPlayer->SetVolume(fVolume * RATIO);
151}
152
153void
154VolumeSlider::SetSoundPlayer(BSoundPlayer *player)
155{
156	fSoundPlayer = player;
157	Invalidate();
158}
159
160
161SpeakerView::SpeakerView(BRect rect, uint32 resizeFlags)
162	: BBox(rect, "speaker", resizeFlags, B_WILL_DRAW, B_NO_BORDER),
163	fSpeakerBitmap(BRect(0, 0, kSpeakerIconBitmapWidth - 1,
164		kSpeakerIconBitmapHeight - 1), B_CMAP8)
165{
166	fSpeakerBitmap.SetBits(kSpeakerIconBits, kSpeakerIconBitmapWidth
167		* kSpeakerIconBitmapHeight, 0, B_CMAP8);
168}
169
170
171SpeakerView::~SpeakerView()
172{
173
174}
175
176
177void
178SpeakerView::Draw(BRect updateRect)
179{
180	SetDrawingMode(B_OP_OVER);
181
182	DrawBitmap(&fSpeakerBitmap);
183
184	SetDrawingMode(B_OP_COPY);
185}
186