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 and Producers)
6 */
7
8#ifndef __MEDIA_BUTTON__
9#define __MEDIA_BUTTON__
10
11#include <Control.h>
12#include <MessageRunner.h>
13#include "icon_button.h"
14
15class BMessage;
16class BBitmap;
17class PeriodicMessageSender;
18class BitmapStash;
19
20// TransportButton must be installed into a window with B_ASYNCHRONOUS_CONTROLS on
21// currently no button focus drawing
22
23class TransportButton : public BControl {
24public:
25
26	TransportButton(BRect frame, const char *name,
27		const unsigned char *normalBits,
28		const unsigned char *pressedBits,
29		const unsigned char *disabledBits,
30		BMessage *invokeMessage,			// done pressing over button
31		BMessage *startPressingMessage = 0, // just clicked button
32		BMessage *pressingMessage = 0, 		// periodical still pressing
33		BMessage *donePressing = 0, 		// tracked out of button/didn't invoke
34		bigtime_t period = 0,				// pressing message period
35		uint32 key = 0,						// optional shortcut key
36		uint32 modifiers = 0,				// optional shortcut key modifier
37		uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
38
39	virtual ~TransportButton();
40
41	void SetStartPressingMessage(BMessage *);
42	void SetPressingMessage(BMessage *);
43	void SetDonePressingMessage(BMessage *);
44	void SetPressingPeriod(bigtime_t);
45
46	virtual void SetEnabled(bool);
47
48protected:
49
50	enum {
51		kDisabledMask = 0x1,
52		kPressedMask = 0x2
53	};
54
55	virtual void AttachedToWindow();
56	virtual void DetachedFromWindow();
57	virtual void Draw(BRect);
58	virtual void MouseDown(BPoint);
59	virtual	void MouseMoved(BPoint, uint32 code, const BMessage *);
60	virtual	void MouseUp(BPoint);
61	virtual	void WindowActivated(bool);
62
63	virtual BBitmap *MakeBitmap(uint32);
64		// lazy bitmap builder
65
66	virtual uint32 ModeMask() const;
67		// mode mask corresponding to the current button state
68		// - determines which bitmap will be used
69	virtual const unsigned char *BitsForMask(uint32) const;
70		// pick the right bits based on a mode mask
71
72		// overriding class can add swapping between two pairs of bitmaps, etc.
73	virtual void StartPressing();
74	virtual void MouseCancelPressing();
75	virtual void DonePressing();
76
77private:
78	void ShortcutKeyDown();
79	void ShortcutKeyUp();
80
81	void MouseStartPressing();
82	void MouseDonePressing();
83
84	BitmapStash *bitmaps;
85		// using BitmapStash * here instead of a direct member so that the class can be private in
86		// the .cpp file
87
88	// bitmap bits used to build bitmaps for the different states
89	const unsigned char *normalBits;
90	const unsigned char *pressedBits;
91	const unsigned char *disabledBits;
92
93	BMessage *startPressingMessage;
94	BMessage *pressingMessage;
95	BMessage *donePressingMessage;
96	bigtime_t pressingPeriod;
97
98	bool mouseDown;
99	bool keyDown;
100	PeriodicMessageSender *messageSender;
101	BMessageFilter *keyPressFilter;
102
103	typedef BControl _inherited;
104
105	friend class SkipButtonKeypressFilter;
106	friend class BitmapStash;
107};
108
109class PlayPauseButton : public TransportButton {
110// Knows about playing and paused states, blinks
111// the pause LED during paused state
112public:
113	PlayPauseButton(BRect frame, const char *name,
114		BMessage *invokeMessage,			// done pressing over button
115		BMessage *blinkMessage = 0, 		// blinking
116		uint32 key = 0,						// optional shortcut key
117		uint32 modifiers = 0,				// optional shortcut key modifier
118		uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
119
120	// These need get called periodically to update the button state
121	// OK to call them over and over - once the state is correct, the call
122	// is very low overhead
123	void SetStopped();
124	void SetPlaying();
125	void SetPaused();
126
127protected:
128
129	virtual uint32 ModeMask() const;
130	virtual const unsigned char *BitsForMask(uint32) const;
131
132	virtual void StartPressing();
133	virtual void MouseCancelPressing();
134	virtual void DonePressing();
135
136private:
137	enum PlayState {
138		kStopped,
139		kAboutToPlay,
140		kPlayingLedOn,
141		kPlayingLedOff,
142		kAboutToPause,
143		kPausedLedOn,
144		kPausedLedOff
145	};
146
147	enum {
148		kPlayingMask = 0x4,
149		kPausedMask = 0x8
150	};
151
152	PlayState fState;
153	uint32 fLastModeMask;
154	BMessageRunner *fRunner;
155	BMessage *fBlinkMessage;
156
157	typedef TransportButton _inherited;
158};
159
160
161class RecordButton : public TransportButton {
162// Knows about recording states, blinks
163// the recording LED during recording state
164public:
165	RecordButton(BRect frame, const char *name,
166		BMessage *invokeMessage,			// done pressing over button
167		BMessage *blinkMessage = 0, 		// blinking
168		uint32 key = 0,						// optional shortcut key
169		uint32 modifiers = 0,				// optional shortcut key modifier
170		uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
171
172	// These need get called periodically to update the button state
173	// OK to call them over and over - once the state is correct, the call
174	// is very low overhead
175	void SetStopped();
176	void SetRecording();
177
178protected:
179
180	virtual uint32 ModeMask() const;
181	virtual const unsigned char *BitsForMask(uint32) const;
182
183	virtual void StartPressing();
184	virtual void MouseCancelPressing();
185	virtual void DonePressing();
186
187private:
188	enum RecordState {
189		kAboutToStop,
190		kStopped,
191		kAboutToRecord,
192		kRecordingLedOn,
193		kRecordingLedOff
194	};
195
196	enum {
197		kRecordingMask = 0x4
198	};
199
200	enum {
201		RECORD_PRESSING = 'crpr'
202	};
203
204	RecordState fState;
205	uint32 fLastModeMask;
206	BMessageRunner *fRunner;
207	BMessage *fBlinkMessage;
208
209	typedef TransportButton _inherited;
210};
211
212#endif
213