xref: /haiku/src/preferences/media/MediaViews.cpp (revision a633251fba4685fcce5faba216eb5ee69fcc947f)
1a10cf76eSAxel Dörfler // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2a10cf76eSAxel Dörfler //
3a10cf76eSAxel Dörfler //	Copyright (c) 2003, OpenBeOS
4a10cf76eSAxel Dörfler //
5a10cf76eSAxel Dörfler //  This software is part of the OpenBeOS distribution and is covered
6a10cf76eSAxel Dörfler //  by the OpenBeOS license.
7a10cf76eSAxel Dörfler //
8a10cf76eSAxel Dörfler //
9a10cf76eSAxel Dörfler //  File:        MediaViews.cpp
10a10cf76eSAxel Dörfler //  Author:      Sikosis, Jérôme Duval
11a10cf76eSAxel Dörfler //  Description: Media Preferences
12a10cf76eSAxel Dörfler //  Created :    June 25, 2003
13a10cf76eSAxel Dörfler //
14a10cf76eSAxel Dörfler // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
15a10cf76eSAxel Dörfler 
16a10cf76eSAxel Dörfler 
17*a633251fSAlex Wilson #include "MediaViews.h"
18f8a1135cSAdrien Destugues 
19a10cf76eSAxel Dörfler #include <Box.h>
20a10cf76eSAxel Dörfler #include <Button.h>
21f8a1135cSAdrien Destugues #include <Catalog.h>
22a10cf76eSAxel Dörfler #include <Deskbar.h>
23a10cf76eSAxel Dörfler #include <Entry.h>
24f8a1135cSAdrien Destugues #include <GroupView.h>
25f8a1135cSAdrien Destugues #include <Locale.h>
26a10cf76eSAxel Dörfler #include <MediaAddOn.h>
27f8a1135cSAdrien Destugues #include <MediaRoster.h>
28f8a1135cSAdrien Destugues #include <MenuField.h>
29f8a1135cSAdrien Destugues #include <PopUpMenu.h>
30f8a1135cSAdrien Destugues #include <SpaceLayoutItem.h>
31a10cf76eSAxel Dörfler #include <String.h>
32b4a12470SJérôme Duval #include <TextView.h>
332af5f895SStephan Aßmus 
34*a633251fSAlex Wilson #include <stdio.h>
35a10cf76eSAxel Dörfler 
369cedafe6SWim van der Meer 
379cedafe6SWim van der Meer #undef B_TRANSLATE_CONTEXT
384eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Media views"
39f8a1135cSAdrien Destugues 
409cedafe6SWim van der Meer 
41c8602bcdSRene Gollent BarView::BarView()
42*a633251fSAlex Wilson 	:
43*a633251fSAlex Wilson 	BView("barView", B_WILL_DRAW ),
44b4a12470SJérôme Duval  	fDisplay(true)
45a10cf76eSAxel Dörfler {
46a10cf76eSAxel Dörfler }
47a10cf76eSAxel Dörfler 
48*a633251fSAlex Wilson 
49a10cf76eSAxel Dörfler void
50a10cf76eSAxel Dörfler BarView::Draw(BRect updateRect)
51a10cf76eSAxel Dörfler {
52a10cf76eSAxel Dörfler 	BRect r = Bounds();
53a10cf76eSAxel Dörfler 
54b4a12470SJérôme Duval 	if (fDisplay) {
55a10cf76eSAxel Dörfler 		// Display the 3D Look Divider Bar
56a10cf76eSAxel Dörfler 		SetHighColor(140,140,140,0);
57a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
58a10cf76eSAxel Dörfler 		SetHighColor(255,255,255,0);
59a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
60a10cf76eSAxel Dörfler 	} else {
61a10cf76eSAxel Dörfler 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
62a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
63a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
64a10cf76eSAxel Dörfler 	}
65a10cf76eSAxel Dörfler }
66a10cf76eSAxel Dörfler 
67a10cf76eSAxel Dörfler 
68c8602bcdSRene Gollent SettingsView::SettingsView (bool isVideo)
69*a633251fSAlex Wilson 	:
70*a633251fSAlex Wilson 	BView("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
71b4a12470SJérôme Duval 	fIsVideo(isVideo)
72a10cf76eSAxel Dörfler {
73a10cf76eSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
742af5f895SStephan Aßmus 
75c8602bcdSRene Gollent 	BBox* defaultsBox = new BBox("defaults");
76176fb40fSMatt Madia 	defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes")
77176fb40fSMatt Madia 		: B_TRANSLATE("Defaults"));
782af5f895SStephan Aßmus 
792af5f895SStephan Aßmus 	// create the default box
802af5f895SStephan Aßmus 	BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5);
81c8602bcdSRene Gollent 	defaultBoxLayout->SetInsets(10,10,10,10);
822af5f895SStephan Aßmus 	defaultsBox->SetLayout(defaultBoxLayout);
832af5f895SStephan Aßmus 	defaultBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
842af5f895SStephan Aßmus 
852af5f895SStephan Aßmus 	BGroupView* inputField = new BGroupView(B_HORIZONTAL);
862af5f895SStephan Aßmus 	BGroupView* outputField = new BGroupView(B_HORIZONTAL);
872af5f895SStephan Aßmus 	defaultsBox->GetLayout()->AddView(inputField);
882af5f895SStephan Aßmus 	defaultsBox->GetLayout()->AddView(outputField);
89a10cf76eSAxel Dörfler 
90176fb40fSMatt Madia 	float divider = StringWidth(fIsVideo ? B_TRANSLATE("Video output:")
91176fb40fSMatt Madia 		: B_TRANSLATE("Audio output:")) + 5;
9291debc87SStephan Aßmus 	fMenu1 = new BPopUpMenu(B_TRANSLATE("<none>"));
93b4a12470SJérôme Duval 	fMenu1->SetLabelFromMarked(true);
94c8602bcdSRene Gollent 	BMenuField* menuField1 = new BMenuField("menuField1",
95176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Video input:")
96176fb40fSMatt Madia 			: B_TRANSLATE("Audio input:"), fMenu1, NULL);
97aaa9b739SJérôme Duval 	menuField1->SetDivider(divider);
98a10cf76eSAxel Dörfler 
9991debc87SStephan Aßmus 	fMenu2 = new BPopUpMenu(B_TRANSLATE("<none>"));
100b4a12470SJérôme Duval 	fMenu2->SetLabelFromMarked(true);
101c8602bcdSRene Gollent 	BMenuField* menuField2 = new BMenuField("menuField2",
102176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Video output:")
103176fb40fSMatt Madia 			: B_TRANSLATE("Audio output:"), fMenu2, NULL);
104aaa9b739SJérôme Duval 	menuField2->SetDivider(divider);
105a10cf76eSAxel Dörfler 
1062af5f895SStephan Aßmus 	inputField->GroupLayout()->AddView(menuField1);
1072af5f895SStephan Aßmus 	outputField->GroupLayout()->AddView(menuField2);
1082af5f895SStephan Aßmus 
1092af5f895SStephan Aßmus 	BMenuField* menuField3 = NULL;
110b4a12470SJérôme Duval 	if (!fIsVideo) {
11191debc87SStephan Aßmus 		fMenu3 = new BPopUpMenu(B_TRANSLATE("<none>"));
112b4a12470SJérôme Duval 		fMenu3->SetLabelFromMarked(true);
113c8602bcdSRene Gollent 		menuField3 = new BMenuField("menuField3",
114176fb40fSMatt Madia 			B_TRANSLATE("Channel:"), fMenu3, NULL);
1152af5f895SStephan Aßmus 		outputField->GroupLayout()->AddView(menuField3);
116176fb40fSMatt Madia 		menuField3->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5);
117a10cf76eSAxel Dörfler 	}
118a10cf76eSAxel Dörfler 
119a10cf76eSAxel Dörfler 	rgb_color red_color = {222, 32, 33};
120c8602bcdSRene Gollent 	fRestartView = new BStringView("restartStringView",
121176fb40fSMatt Madia 		B_TRANSLATE("Restart the media server to apply changes."));
122b4a12470SJérôme Duval 	fRestartView->SetHighColor(red_color);
123b4a12470SJérôme Duval 	defaultsBox->AddChild(fRestartView);
124b4a12470SJérôme Duval 	fRestartView->Hide();
125a10cf76eSAxel Dörfler 
1262af5f895SStephan Aßmus 	// create the realtime box
127c8602bcdSRene Gollent 	BBox* realtimeBox = new BBox("realtime");
128176fb40fSMatt Madia 	realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
129a10cf76eSAxel Dörfler 
130a10cf76eSAxel Dörfler 	BMessage* message = new BMessage(ML_ENABLE_REAL_TIME);
131b4a12470SJérôme Duval 	message->AddBool("isVideo", fIsVideo);
132c8602bcdSRene Gollent 	fRealtimeCheckBox = new BCheckBox("realtimeCheckBox",
133176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Enable real-time video")
134176fb40fSMatt Madia 			: B_TRANSLATE("Enable real-time audio"),
135c8602bcdSRene Gollent 		message);
136a10cf76eSAxel Dörfler 
137a10cf76eSAxel Dörfler 	uint32 flags;
138a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
139b4a12470SJérôme Duval 	if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
140b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
141a10cf76eSAxel Dörfler 
142c8602bcdSRene Gollent 	BTextView* textView = new BTextView("stringView");
143176fb40fSMatt Madia 	textView->Insert(fIsVideo ? B_TRANSLATE(
144176fb40fSMatt Madia 		"Enabling real-time video allows system to "
145f8a1135cSAdrien Destugues 		"perform video operations as fast and smoothly as possible.  It "
146f8a1135cSAdrien Destugues 		"achieves optimum performance by using more RAM."
147f8a1135cSAdrien Destugues 		"\n\nOnly enable this feature if you need the lowest latency possible.")
148176fb40fSMatt Madia 		: B_TRANSLATE(
149176fb40fSMatt Madia 		"Enabling real-time audio allows system to record and play audio "
150*a633251fSAlex Wilson 		"as fast as possible.  It achieves this performance by using more"
151*a633251fSAlex Wilson 		" CPU and RAM.\n\nOnly enable this feature if you need the lowest"
152*a633251fSAlex Wilson 		" latency possible."));
153*a633251fSAlex Wilson 
154b4a12470SJérôme Duval 	textView->MakeEditable(false);
155b4a12470SJérôme Duval 	textView->MakeSelectable(false);
156a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
157a10cf76eSAxel Dörfler 
1582af5f895SStephan Aßmus 	BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
159c8602bcdSRene Gollent 	realtimeBoxLayout->SetInsets(10,10,10,10);
1602af5f895SStephan Aßmus 	realtimeBox->SetLayout(realtimeBoxLayout);
1612af5f895SStephan Aßmus 
1622af5f895SStephan Aßmus 	realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
1632af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(fRealtimeCheckBox);
1642af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(textView);
1652af5f895SStephan Aßmus 
1662af5f895SStephan Aßmus 	// create the bottom line: volumen in deskbar checkbox and restart button
1672af5f895SStephan Aßmus 	BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
168c8602bcdSRene Gollent 	BButton* restartButton = new BButton("restartButton",
169176fb40fSMatt Madia 		B_TRANSLATE("Restart media services"),
170176fb40fSMatt Madia 		new BMessage(ML_RESTART_MEDIA_SERVER));
171a10cf76eSAxel Dörfler 
172b4a12470SJérôme Duval 	if (!fIsVideo) {
173c8602bcdSRene Gollent 		fVolumeCheckBox = new BCheckBox("volumeCheckBox",
174176fb40fSMatt Madia 			B_TRANSLATE("Show volume control on Deskbar"),
175176fb40fSMatt Madia 			new BMessage(ML_SHOW_VOLUME_CONTROL));
1762af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddView(fVolumeCheckBox);
177a10cf76eSAxel Dörfler 		if (BDeskbar().HasItem("MediaReplicant"))
178b4a12470SJérôme Duval 			fVolumeCheckBox->SetValue(B_CONTROL_ON);
179a10cf76eSAxel Dörfler 	}
1802af5f895SStephan Aßmus 	else{
1812af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
1822af5f895SStephan Aßmus 	}
1832af5f895SStephan Aßmus 	bottomView->GroupLayout()->AddView(restartButton);
1842af5f895SStephan Aßmus 
1852af5f895SStephan Aßmus 	// compose all stuff
1862af5f895SStephan Aßmus 	BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5);
1872af5f895SStephan Aßmus 	SetLayout(rootlayout);
1882af5f895SStephan Aßmus 
1892af5f895SStephan Aßmus 	rootlayout->AddView(defaultsBox);
1902af5f895SStephan Aßmus 	rootlayout->AddView(realtimeBox);
1912af5f895SStephan Aßmus 	rootlayout->AddView(bottomView);
192a10cf76eSAxel Dörfler }
193a10cf76eSAxel Dörfler 
194*a633251fSAlex Wilson 
195a10cf76eSAxel Dörfler void
196a10cf76eSAxel Dörfler SettingsView::AddNodes(BList& list, bool isInput)
197a10cf76eSAxel Dörfler {
198b4a12470SJérôme Duval 	BMenu* menu = isInput ? fMenu1 : fMenu2;
199a10cf76eSAxel Dörfler 	void* item;
200a10cf76eSAxel Dörfler 	while ((item = menu->RemoveItem((int32)0)) != NULL)
201a10cf76eSAxel Dörfler 		delete static_cast<dormant_node_info*>(item);
202a10cf76eSAxel Dörfler 
203a10cf76eSAxel Dörfler 	BMessage message(ML_DEFAULT_CHANGE);
204b4a12470SJérôme Duval 	message.AddBool("isVideo", fIsVideo);
205a10cf76eSAxel Dörfler 	message.AddBool("isInput", isInput);
206a10cf76eSAxel Dörfler 
207a10cf76eSAxel Dörfler 	for (int32 i = 0; i < list.CountItems(); i++) {
208*a633251fSAlex Wilson 		dormant_node_info* info
209*a633251fSAlex Wilson 			= static_cast<dormant_node_info*>(list.ItemAt(i));
210a10cf76eSAxel Dörfler 		menu->AddItem(new SettingsItem(info, new BMessage(message)));
211a10cf76eSAxel Dörfler 	}
212a10cf76eSAxel Dörfler }
213a10cf76eSAxel Dörfler 
214*a633251fSAlex Wilson 
215a10cf76eSAxel Dörfler void
216a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
217a10cf76eSAxel Dörfler {
218b4a12470SJérôme Duval 	BMenu* menu = isInput ? fMenu1 : fMenu2;
219a10cf76eSAxel Dörfler 
220a10cf76eSAxel Dörfler 	for (int32 i = 0; i < menu->CountItems(); i++) {
221a10cf76eSAxel Dörfler 		SettingsItem* item = static_cast<SettingsItem*>(menu->ItemAt(i));
222*a633251fSAlex Wilson 		if (item->fInfo && item->fInfo->addon == info.addon
223*a633251fSAlex Wilson 			&& item->fInfo->flavor_id == info.flavor_id) {
224a10cf76eSAxel Dörfler 			item->SetMarked(true);
225a10cf76eSAxel Dörfler 			break;
226a10cf76eSAxel Dörfler 		}
227a10cf76eSAxel Dörfler 	}
228a10cf76eSAxel Dörfler 
229*a633251fSAlex Wilson 	if (!fIsVideo && !isInput && outputID >= 0) {
230a10cf76eSAxel Dörfler 		BMenuItem* item;
231b4a12470SJérôme Duval 		while ((item = fMenu3->RemoveItem((int32)0)) != NULL)
232a10cf76eSAxel Dörfler 			delete item;
233*a633251fSAlex Wilson 
234a10cf76eSAxel Dörfler 		BMediaRoster* roster = BMediaRoster::Roster();
235a10cf76eSAxel Dörfler 		media_node node;
236a10cf76eSAxel Dörfler 		media_node_id node_id;
237a10cf76eSAxel Dörfler 		status_t err;
238*a633251fSAlex Wilson 		if (roster->GetInstancesFor(info.addon, info.flavor_id,
239*a633251fSAlex Wilson 			&node_id) != B_OK) {
240*a633251fSAlex Wilson 			err = roster->InstantiateDormantNode(info, &node,
241*a633251fSAlex Wilson 				B_FLAVOR_IS_GLOBAL);
242*a633251fSAlex Wilson 		} else {
243a10cf76eSAxel Dörfler 			err = roster->GetNodeFor(node_id, &node);
244*a633251fSAlex Wilson 		}
245a10cf76eSAxel Dörfler 
246a10cf76eSAxel Dörfler 		if (err == B_OK) {
247a10cf76eSAxel Dörfler 			media_input inputs[16];
248a10cf76eSAxel Dörfler 			int32 inputCount = 16;
249a10cf76eSAxel Dörfler 			if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
250a10cf76eSAxel Dörfler 				BMessage message(ML_DEFAULTOUTPUT_CHANGE);
251a10cf76eSAxel Dörfler 
252a10cf76eSAxel Dörfler 				for (int32 i = 0; i < inputCount; i++) {
253a10cf76eSAxel Dörfler 					media_input* input = new media_input();
254a10cf76eSAxel Dörfler 					memcpy(input, &inputs[i], sizeof(*input));
255*a633251fSAlex Wilson 					item = new Settings2Item(&info, input,
256*a633251fSAlex Wilson 						new BMessage(message));
257*a633251fSAlex Wilson 					fMenu3->AddItem(item);
258a10cf76eSAxel Dörfler 					if (inputs[i].destination.id == outputID)
259a10cf76eSAxel Dörfler 						item->SetMarked(true);
260a10cf76eSAxel Dörfler 				}
261a10cf76eSAxel Dörfler 			}
262a10cf76eSAxel Dörfler 		}
263a10cf76eSAxel Dörfler 	}
264a10cf76eSAxel Dörfler }
265a10cf76eSAxel Dörfler 
266*a633251fSAlex Wilson 
267a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message,
268a10cf76eSAxel Dörfler 		char shortcut, uint32 modifiers)
269*a633251fSAlex Wilson 	:
270*a633251fSAlex Wilson 	BMenuItem(info->name, message, shortcut, modifiers),
271b4a12470SJérôme Duval 	fInfo(info)
272a10cf76eSAxel Dörfler {
273a10cf76eSAxel Dörfler 
274a10cf76eSAxel Dörfler }
275a10cf76eSAxel Dörfler 
2766df0b2d5SJérôme Duval 
2776df0b2d5SJérôme Duval status_t
2786df0b2d5SJérôme Duval SettingsItem::Invoke(BMessage* message)
2796df0b2d5SJérôme Duval {
2806df0b2d5SJérôme Duval 	if (IsMarked())
2816df0b2d5SJérôme Duval 		return B_OK;
2826df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2836df0b2d5SJérôme Duval }
2846df0b2d5SJérôme Duval 
2856df0b2d5SJérôme Duval 
286*a633251fSAlex Wilson Settings2Item::Settings2Item(dormant_node_info* info, media_input* input,
287*a633251fSAlex Wilson 		BMessage* message, char shortcut, uint32 modifiers)
288*a633251fSAlex Wilson 	:
289*a633251fSAlex Wilson 	BMenuItem(input->name, message, shortcut, modifiers),
290b4a12470SJérôme Duval 	fInfo(info),
291b4a12470SJérôme Duval 	fInput(input)
292a10cf76eSAxel Dörfler {
293a10cf76eSAxel Dörfler }
294a10cf76eSAxel Dörfler 
2956df0b2d5SJérôme Duval 
296a10cf76eSAxel Dörfler Settings2Item::~Settings2Item()
297a10cf76eSAxel Dörfler {
298b4a12470SJérôme Duval 	delete fInput;
299a10cf76eSAxel Dörfler }
300a10cf76eSAxel Dörfler 
3016df0b2d5SJérôme Duval 
3026df0b2d5SJérôme Duval status_t
3036df0b2d5SJérôme Duval Settings2Item::Invoke(BMessage* message)
3046df0b2d5SJérôme Duval {
3056df0b2d5SJérôme Duval 	if (IsMarked())
3066df0b2d5SJérôme Duval 		return B_OK;
3076df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
3086df0b2d5SJérôme Duval }
3096df0b2d5SJérôme Duval 
310