xref: /haiku/src/preferences/media/MediaViews.cpp (revision 6e62e7442344b160f07c3612c9e510a20dccc370)
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 
17a633251fSAlex 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>
24*6e62e744SAlex Wilson #include <GridView.h>
25f8a1135cSAdrien Destugues #include <GroupView.h>
26f8a1135cSAdrien Destugues #include <Locale.h>
27a10cf76eSAxel Dörfler #include <MediaAddOn.h>
28f8a1135cSAdrien Destugues #include <MediaRoster.h>
29f8a1135cSAdrien Destugues #include <MenuField.h>
30f8a1135cSAdrien Destugues #include <PopUpMenu.h>
31f8a1135cSAdrien Destugues #include <SpaceLayoutItem.h>
32a10cf76eSAxel Dörfler #include <String.h>
33b4a12470SJérôme Duval #include <TextView.h>
342af5f895SStephan Aßmus 
35a633251fSAlex Wilson #include <stdio.h>
36a10cf76eSAxel Dörfler 
379cedafe6SWim van der Meer 
389cedafe6SWim van der Meer #undef B_TRANSLATE_CONTEXT
394eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Media views"
40f8a1135cSAdrien Destugues 
419cedafe6SWim van der Meer 
42c8602bcdSRene Gollent SettingsView::SettingsView (bool isVideo)
43a633251fSAlex Wilson 	:
44a633251fSAlex Wilson 	BView("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
45b4a12470SJérôme Duval 	fIsVideo(isVideo)
46a10cf76eSAxel Dörfler {
47a10cf76eSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
482af5f895SStephan Aßmus 
49*6e62e744SAlex Wilson 	// create the default box
50*6e62e744SAlex Wilson 
51*6e62e744SAlex Wilson 	// input menu
52*6e62e744SAlex Wilson 	fInputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
53*6e62e744SAlex Wilson 	fInputMenu->SetLabelFromMarked(true);
54*6e62e744SAlex Wilson 	BMenuField* inputMenuField = new BMenuField("inputMenuField",
55*6e62e744SAlex Wilson 		fIsVideo ? B_TRANSLATE("Video input:")
56*6e62e744SAlex Wilson 			: B_TRANSLATE("Audio input:"), fInputMenu, NULL);
57*6e62e744SAlex Wilson 
58*6e62e744SAlex Wilson 	// output menu
59*6e62e744SAlex Wilson 	fOutputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
60*6e62e744SAlex Wilson 	fOutputMenu->SetLabelFromMarked(true);
61*6e62e744SAlex Wilson 	BMenuField* outputMenuField = new BMenuField("outputMenuField",
62*6e62e744SAlex Wilson 		fIsVideo ? B_TRANSLATE("Video output:")
63*6e62e744SAlex Wilson 			: B_TRANSLATE("Audio output:"), fOutputMenu, NULL);
64*6e62e744SAlex Wilson 
65*6e62e744SAlex Wilson 	// channel menu (audio only)
66*6e62e744SAlex Wilson 	BMenuField* channelMenuField = NULL;
67*6e62e744SAlex Wilson 	if (!fIsVideo) {
68*6e62e744SAlex Wilson 		fChannelMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
69*6e62e744SAlex Wilson 		fChannelMenu->SetLabelFromMarked(true);
70*6e62e744SAlex Wilson 		channelMenuField = new BMenuField("channelMenuField",
71*6e62e744SAlex Wilson 			B_TRANSLATE("Channel:"), fChannelMenu, NULL);
72*6e62e744SAlex Wilson 		channelMenuField->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5);
73*6e62e744SAlex Wilson 	}
74*6e62e744SAlex Wilson 
75c8602bcdSRene Gollent 	BBox* defaultsBox = new BBox("defaults");
76176fb40fSMatt Madia 	defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes")
77176fb40fSMatt Madia 		: B_TRANSLATE("Defaults"));
782af5f895SStephan Aßmus 
79*6e62e744SAlex Wilson 	// put our menus in a BGridView in our BBox, this way, the BBox makes sure
80*6e62e744SAlex Wilson 	// we have are not blocking the label.
81*6e62e744SAlex Wilson 	BGridView* defaultsGridView = new BGridView();
82*6e62e744SAlex Wilson 	defaultsBox->AddChild(defaultsGridView);
832af5f895SStephan Aßmus 
84*6e62e744SAlex Wilson 	BGridLayout* defaultsGrid = defaultsGridView->GridLayout();
85*6e62e744SAlex Wilson 	defaultsGrid->SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
86*6e62e744SAlex Wilson 		B_USE_DEFAULT_SPACING);
87a10cf76eSAxel Dörfler 
88*6e62e744SAlex Wilson 	BLayoutItem* labelItem = inputMenuField->CreateLabelLayoutItem();
89*6e62e744SAlex Wilson 	BLayoutItem* menuItem = inputMenuField->CreateMenuBarLayoutItem();
90*6e62e744SAlex Wilson 	defaultsGrid->AddItem(labelItem, 0, 0, 1, 1);
91*6e62e744SAlex Wilson 	defaultsGrid->AddItem(menuItem, 1, 0, 3, 1);
92a10cf76eSAxel Dörfler 
93*6e62e744SAlex Wilson 	int32 outputMenuWidth = 3;
94*6e62e744SAlex Wilson 	if (channelMenuField) {
95*6e62e744SAlex Wilson 		outputMenuWidth = 1;
96*6e62e744SAlex Wilson 		labelItem = channelMenuField->CreateLabelLayoutItem();
97*6e62e744SAlex Wilson 		menuItem = channelMenuField->CreateMenuBarLayoutItem();
98*6e62e744SAlex Wilson 		defaultsGrid->AddItem(labelItem, 2, 1, 1, 1);
99*6e62e744SAlex Wilson 		defaultsGrid->AddItem(menuItem, 3, 1, 1, 1);
100a10cf76eSAxel Dörfler 	}
101a10cf76eSAxel Dörfler 
102*6e62e744SAlex Wilson 	labelItem = outputMenuField->CreateLabelLayoutItem();
103*6e62e744SAlex Wilson 	menuItem = outputMenuField->CreateMenuBarLayoutItem();
104*6e62e744SAlex Wilson 	defaultsGrid->AddItem(labelItem, 0, 1, 1, 1);
105*6e62e744SAlex Wilson 	defaultsGrid->AddItem(menuItem, 1, 1, outputMenuWidth, 1);
106*6e62e744SAlex Wilson 
107*6e62e744SAlex Wilson 
108a10cf76eSAxel Dörfler 	rgb_color red_color = {222, 32, 33};
109c8602bcdSRene Gollent 	fRestartView = new BStringView("restartStringView",
110176fb40fSMatt Madia 		B_TRANSLATE("Restart the media server to apply changes."));
111b4a12470SJérôme Duval 	fRestartView->SetHighColor(red_color);
112b4a12470SJérôme Duval 	defaultsBox->AddChild(fRestartView);
113b4a12470SJérôme Duval 	fRestartView->Hide();
114a10cf76eSAxel Dörfler 
1152af5f895SStephan Aßmus 	// create the realtime box
116c8602bcdSRene Gollent 	BBox* realtimeBox = new BBox("realtime");
117176fb40fSMatt Madia 	realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
118a10cf76eSAxel Dörfler 
119a10cf76eSAxel Dörfler 	BMessage* message = new BMessage(ML_ENABLE_REAL_TIME);
120b4a12470SJérôme Duval 	message->AddBool("isVideo", fIsVideo);
121c8602bcdSRene Gollent 	fRealtimeCheckBox = new BCheckBox("realtimeCheckBox",
122176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Enable real-time video")
123176fb40fSMatt Madia 			: B_TRANSLATE("Enable real-time audio"),
124c8602bcdSRene Gollent 		message);
125a10cf76eSAxel Dörfler 
126a10cf76eSAxel Dörfler 	uint32 flags;
127a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
128b4a12470SJérôme Duval 	if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
129b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
130a10cf76eSAxel Dörfler 
131c8602bcdSRene Gollent 	BTextView* textView = new BTextView("stringView");
132176fb40fSMatt Madia 	textView->Insert(fIsVideo ? B_TRANSLATE(
133176fb40fSMatt Madia 		"Enabling real-time video allows system to "
134f8a1135cSAdrien Destugues 		"perform video operations as fast and smoothly as possible.  It "
135f8a1135cSAdrien Destugues 		"achieves optimum performance by using more RAM."
136f8a1135cSAdrien Destugues 		"\n\nOnly enable this feature if you need the lowest latency possible.")
137176fb40fSMatt Madia 		: B_TRANSLATE(
138176fb40fSMatt Madia 		"Enabling real-time audio allows system to record and play audio "
139a633251fSAlex Wilson 		"as fast as possible.  It achieves this performance by using more"
140a633251fSAlex Wilson 		" CPU and RAM.\n\nOnly enable this feature if you need the lowest"
141a633251fSAlex Wilson 		" latency possible."));
142a633251fSAlex Wilson 
143b4a12470SJérôme Duval 	textView->MakeEditable(false);
144b4a12470SJérôme Duval 	textView->MakeSelectable(false);
145a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
146a10cf76eSAxel Dörfler 
1472af5f895SStephan Aßmus 	BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
148c8602bcdSRene Gollent 	realtimeBoxLayout->SetInsets(10,10,10,10);
1492af5f895SStephan Aßmus 	realtimeBox->SetLayout(realtimeBoxLayout);
1502af5f895SStephan Aßmus 
1512af5f895SStephan Aßmus 	realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
1522af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(fRealtimeCheckBox);
1532af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(textView);
1542af5f895SStephan Aßmus 
155*6e62e744SAlex Wilson 	// create the bottom line: volume in deskbar checkbox and restart button
1562af5f895SStephan Aßmus 	BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
157c8602bcdSRene Gollent 	BButton* restartButton = new BButton("restartButton",
158176fb40fSMatt Madia 		B_TRANSLATE("Restart media services"),
159176fb40fSMatt Madia 		new BMessage(ML_RESTART_MEDIA_SERVER));
160a10cf76eSAxel Dörfler 
161b4a12470SJérôme Duval 	if (!fIsVideo) {
162c8602bcdSRene Gollent 		fVolumeCheckBox = new BCheckBox("volumeCheckBox",
163176fb40fSMatt Madia 			B_TRANSLATE("Show volume control on Deskbar"),
164176fb40fSMatt Madia 			new BMessage(ML_SHOW_VOLUME_CONTROL));
1652af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddView(fVolumeCheckBox);
166a10cf76eSAxel Dörfler 		if (BDeskbar().HasItem("MediaReplicant"))
167b4a12470SJérôme Duval 			fVolumeCheckBox->SetValue(B_CONTROL_ON);
168a10cf76eSAxel Dörfler 	}
1692af5f895SStephan Aßmus 	else{
1702af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
1712af5f895SStephan Aßmus 	}
1722af5f895SStephan Aßmus 	bottomView->GroupLayout()->AddView(restartButton);
1732af5f895SStephan Aßmus 
1742af5f895SStephan Aßmus 	// compose all stuff
1752af5f895SStephan Aßmus 	BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5);
1762af5f895SStephan Aßmus 	SetLayout(rootlayout);
1772af5f895SStephan Aßmus 
1782af5f895SStephan Aßmus 	rootlayout->AddView(defaultsBox);
1792af5f895SStephan Aßmus 	rootlayout->AddView(realtimeBox);
1802af5f895SStephan Aßmus 	rootlayout->AddView(bottomView);
181a10cf76eSAxel Dörfler }
182a10cf76eSAxel Dörfler 
183a633251fSAlex Wilson 
184a10cf76eSAxel Dörfler void
1856b0cdfbcSAlex Wilson SettingsView::AddNodes(NodeList& list, bool isInput)
186a10cf76eSAxel Dörfler {
187*6e62e744SAlex Wilson 	BMenu* menu = isInput ? fInputMenu : fOutputMenu;
188*6e62e744SAlex Wilson 
189*6e62e744SAlex Wilson 	for (BMenuItem* item; (item = menu->RemoveItem((int32)0)) != NULL;)
190*6e62e744SAlex Wilson 		delete item;
191a10cf76eSAxel Dörfler 
192a10cf76eSAxel Dörfler 	BMessage message(ML_DEFAULT_CHANGE);
193b4a12470SJérôme Duval 	message.AddBool("isVideo", fIsVideo);
194a10cf76eSAxel Dörfler 	message.AddBool("isInput", isInput);
195a10cf76eSAxel Dörfler 
196a10cf76eSAxel Dörfler 	for (int32 i = 0; i < list.CountItems(); i++) {
1976b0cdfbcSAlex Wilson 		dormant_node_info* info = list.ItemAt(i);
198a10cf76eSAxel Dörfler 		menu->AddItem(new SettingsItem(info, new BMessage(message)));
199a10cf76eSAxel Dörfler 	}
200a10cf76eSAxel Dörfler }
201a10cf76eSAxel Dörfler 
202a633251fSAlex Wilson 
203a10cf76eSAxel Dörfler void
204a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
205a10cf76eSAxel Dörfler {
206*6e62e744SAlex Wilson 	BMenu* menu = isInput ? fInputMenu : fOutputMenu;
207a10cf76eSAxel Dörfler 
208a10cf76eSAxel Dörfler 	for (int32 i = 0; i < menu->CountItems(); i++) {
209a10cf76eSAxel Dörfler 		SettingsItem* item = static_cast<SettingsItem*>(menu->ItemAt(i));
210a633251fSAlex Wilson 		if (item->fInfo && item->fInfo->addon == info.addon
211a633251fSAlex Wilson 			&& item->fInfo->flavor_id == info.flavor_id) {
212a10cf76eSAxel Dörfler 			item->SetMarked(true);
213a10cf76eSAxel Dörfler 			break;
214a10cf76eSAxel Dörfler 		}
215a10cf76eSAxel Dörfler 	}
216a10cf76eSAxel Dörfler 
217a633251fSAlex Wilson 	if (!fIsVideo && !isInput && outputID >= 0) {
218a10cf76eSAxel Dörfler 		BMenuItem* item;
219*6e62e744SAlex Wilson 		while ((item = fChannelMenu->RemoveItem((int32)0)) != NULL)
220a10cf76eSAxel Dörfler 			delete item;
221a633251fSAlex Wilson 
222a10cf76eSAxel Dörfler 		BMediaRoster* roster = BMediaRoster::Roster();
223a10cf76eSAxel Dörfler 		media_node node;
224a10cf76eSAxel Dörfler 		media_node_id node_id;
225a10cf76eSAxel Dörfler 		status_t err;
226a633251fSAlex Wilson 		if (roster->GetInstancesFor(info.addon, info.flavor_id,
227a633251fSAlex Wilson 			&node_id) != B_OK) {
228a633251fSAlex Wilson 			err = roster->InstantiateDormantNode(info, &node,
229a633251fSAlex Wilson 				B_FLAVOR_IS_GLOBAL);
230a633251fSAlex Wilson 		} else {
231a10cf76eSAxel Dörfler 			err = roster->GetNodeFor(node_id, &node);
232a633251fSAlex Wilson 		}
233a10cf76eSAxel Dörfler 
234a10cf76eSAxel Dörfler 		if (err == B_OK) {
235a10cf76eSAxel Dörfler 			media_input inputs[16];
236a10cf76eSAxel Dörfler 			int32 inputCount = 16;
237a10cf76eSAxel Dörfler 			if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
238a10cf76eSAxel Dörfler 				BMessage message(ML_DEFAULTOUTPUT_CHANGE);
239a10cf76eSAxel Dörfler 
240a10cf76eSAxel Dörfler 				for (int32 i = 0; i < inputCount; i++) {
241a10cf76eSAxel Dörfler 					media_input* input = new media_input();
242a10cf76eSAxel Dörfler 					memcpy(input, &inputs[i], sizeof(*input));
243a633251fSAlex Wilson 					item = new Settings2Item(&info, input,
244a633251fSAlex Wilson 						new BMessage(message));
245*6e62e744SAlex Wilson 					fChannelMenu->AddItem(item);
246a10cf76eSAxel Dörfler 					if (inputs[i].destination.id == outputID)
247a10cf76eSAxel Dörfler 						item->SetMarked(true);
248a10cf76eSAxel Dörfler 				}
249a10cf76eSAxel Dörfler 			}
250a10cf76eSAxel Dörfler 		}
251a10cf76eSAxel Dörfler 	}
252a10cf76eSAxel Dörfler }
253a10cf76eSAxel Dörfler 
254a633251fSAlex Wilson 
255a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message,
256a10cf76eSAxel Dörfler 		char shortcut, uint32 modifiers)
257a633251fSAlex Wilson 	:
258a633251fSAlex Wilson 	BMenuItem(info->name, message, shortcut, modifiers),
259b4a12470SJérôme Duval 	fInfo(info)
260a10cf76eSAxel Dörfler {
261a10cf76eSAxel Dörfler 
262a10cf76eSAxel Dörfler }
263a10cf76eSAxel Dörfler 
2646df0b2d5SJérôme Duval 
2656df0b2d5SJérôme Duval status_t
2666df0b2d5SJérôme Duval SettingsItem::Invoke(BMessage* message)
2676df0b2d5SJérôme Duval {
2686df0b2d5SJérôme Duval 	if (IsMarked())
2696df0b2d5SJérôme Duval 		return B_OK;
2706df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2716df0b2d5SJérôme Duval }
2726df0b2d5SJérôme Duval 
2736df0b2d5SJérôme Duval 
274a633251fSAlex Wilson Settings2Item::Settings2Item(dormant_node_info* info, media_input* input,
275a633251fSAlex Wilson 		BMessage* message, char shortcut, uint32 modifiers)
276a633251fSAlex Wilson 	:
277a633251fSAlex Wilson 	BMenuItem(input->name, message, shortcut, modifiers),
278b4a12470SJérôme Duval 	fInfo(info),
279b4a12470SJérôme Duval 	fInput(input)
280a10cf76eSAxel Dörfler {
281a10cf76eSAxel Dörfler }
282a10cf76eSAxel Dörfler 
2836df0b2d5SJérôme Duval 
284a10cf76eSAxel Dörfler Settings2Item::~Settings2Item()
285a10cf76eSAxel Dörfler {
286b4a12470SJérôme Duval 	delete fInput;
287a10cf76eSAxel Dörfler }
288a10cf76eSAxel Dörfler 
2896df0b2d5SJérôme Duval 
2906df0b2d5SJérôme Duval status_t
2916df0b2d5SJérôme Duval Settings2Item::Invoke(BMessage* message)
2926df0b2d5SJérôme Duval {
2936df0b2d5SJérôme Duval 	if (IsMarked())
2946df0b2d5SJérôme Duval 		return B_OK;
2956df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2966df0b2d5SJérôme Duval }
2976df0b2d5SJérôme Duval 
298