xref: /haiku/src/preferences/media/MediaViews.cpp (revision d2772fb43e804a2a9e9dea7ad82413e314f521be)
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 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
15a633251fSAlex Wilson #include "MediaViews.h"
16f8a1135cSAdrien Destugues 
170ee86c8dSAlex Wilson #include <Alert.h>
187afc7756SAlex Wilson #include <AutoDeleter.h>
19a10cf76eSAxel Dörfler #include <Box.h>
20a10cf76eSAxel Dörfler #include <Button.h>
21f8a1135cSAdrien Destugues #include <Catalog.h>
227afc7756SAlex Wilson #include <CheckBox.h>
23a10cf76eSAxel Dörfler #include <Deskbar.h>
24a10cf76eSAxel Dörfler #include <Entry.h>
257afc7756SAlex Wilson #include <LayoutBuilder.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>
31a10cf76eSAxel Dörfler #include <String.h>
327afc7756SAlex Wilson #include <StringView.h>
33b4a12470SJérôme Duval #include <TextView.h>
342af5f895SStephan Aßmus 
357afc7756SAlex Wilson #include <assert.h>
36a633251fSAlex Wilson #include <stdio.h>
37a10cf76eSAxel Dörfler 
387afc7756SAlex Wilson #include "MediaWindow.h"
397afc7756SAlex Wilson 
409cedafe6SWim van der Meer 
419cedafe6SWim van der Meer #undef B_TRANSLATE_CONTEXT
424eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Media views"
43f8a1135cSAdrien Destugues 
447afc7756SAlex Wilson #define MEDIA_DEFAULT_INPUT_CHANGE 'dich'
457afc7756SAlex Wilson #define MEDIA_DEFAULT_OUTPUT_CHANGE 'doch'
467afc7756SAlex Wilson #define MEDIA_SHOW_HIDE_VOLUME_CONTROL 'shvc'
479cedafe6SWim van der Meer 
487afc7756SAlex Wilson 
497afc7756SAlex Wilson SettingsView::SettingsView()
50a633251fSAlex Wilson 	:
517afc7756SAlex Wilson 	BGridView(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING),
527afc7756SAlex Wilson 	fRealtimeCheckBox(NULL),
537afc7756SAlex Wilson 	fInputMenu(NULL),
547afc7756SAlex Wilson 	fOutputMenu(NULL),
557afc7756SAlex Wilson 	fRestartView(NULL)
56a10cf76eSAxel Dörfler {
576e62e744SAlex Wilson 	// input menu
586e62e744SAlex Wilson 	fInputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
596e62e744SAlex Wilson 	fInputMenu->SetLabelFromMarked(true);
606e62e744SAlex Wilson 
617afc7756SAlex Wilson 	// input menu
626e62e744SAlex Wilson 	fOutputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
636e62e744SAlex Wilson 	fOutputMenu->SetLabelFromMarked(true);
646e62e744SAlex Wilson }
656e62e744SAlex Wilson 
662af5f895SStephan Aßmus 
677afc7756SAlex Wilson BBox*
687afc7756SAlex Wilson SettingsView::MakeRealtimeBox(const char* info, uint32 realtimeMask,
697afc7756SAlex Wilson 	const char* checkBoxLabel)
707afc7756SAlex Wilson {
712af5f895SStephan Aßmus 	// create the realtime box
72c8602bcdSRene Gollent 	BBox* realtimeBox = new BBox("realtime");
73176fb40fSMatt Madia 	realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
74a10cf76eSAxel Dörfler 
757afc7756SAlex Wilson 	BMessage* checkBoxMessage = new BMessage(ML_ENABLE_REAL_TIME);
767afc7756SAlex Wilson 	checkBoxMessage->AddUInt32("flags", realtimeMask);
777afc7756SAlex Wilson 	fRealtimeCheckBox = new BCheckBox("realtimeCheckBox", checkBoxLabel,
787afc7756SAlex Wilson 		checkBoxMessage);
79a10cf76eSAxel Dörfler 
807afc7756SAlex Wilson 	uint32 flags = 0;
81a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
827afc7756SAlex Wilson 	if (flags & realtimeMask)
83b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
84a10cf76eSAxel Dörfler 
85c8602bcdSRene Gollent 	BTextView* textView = new BTextView("stringView");
867afc7756SAlex Wilson 	textView->Insert(info);
87b4a12470SJérôme Duval 	textView->MakeEditable(false);
88b4a12470SJérôme Duval 	textView->MakeSelectable(false);
89a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
90a10cf76eSAxel Dörfler 
917afc7756SAlex Wilson 	BGroupView* realtimeGroup = new BGroupView(B_VERTICAL);
927afc7756SAlex Wilson 	BLayoutBuilder::Group<>(realtimeGroup)
937afc7756SAlex Wilson 		.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
947afc7756SAlex Wilson 			B_USE_DEFAULT_SPACING)
957afc7756SAlex Wilson 		.Add(fRealtimeCheckBox)
967afc7756SAlex Wilson 		.Add(textView);
972af5f895SStephan Aßmus 
987afc7756SAlex Wilson 	realtimeBox->AddChild(realtimeGroup);
997afc7756SAlex Wilson 	return realtimeBox;
1007afc7756SAlex Wilson }
1012af5f895SStephan Aßmus 
1027afc7756SAlex Wilson 
1037afc7756SAlex Wilson BStringView*
1047afc7756SAlex Wilson SettingsView::MakeRestartMessageView()
1057afc7756SAlex Wilson {
1067afc7756SAlex Wilson 	// note: this ought to display at the bottom of the default box...
1077afc7756SAlex Wilson 	fRestartView = new BStringView("restartStringView",
1087afc7756SAlex Wilson 		B_TRANSLATE("Restart the media server to apply changes."));
1097afc7756SAlex Wilson 	fRestartView->SetHighColor(ui_color(B_FAILURE_COLOR));
1107afc7756SAlex Wilson 		// not exactly failure, but sort of.
1117afc7756SAlex Wilson 	fRestartView->Hide();
1127afc7756SAlex Wilson 	fRestartView->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER,
1137afc7756SAlex Wilson 		B_ALIGN_VERTICAL_CENTER));
1147afc7756SAlex Wilson 	fRestartView->SetAlignment(B_ALIGN_HORIZONTAL_CENTER);
1157afc7756SAlex Wilson 	fRestartView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
1167afc7756SAlex Wilson 	return fRestartView;
1177afc7756SAlex Wilson }
1187afc7756SAlex Wilson 
1197afc7756SAlex Wilson 
1207afc7756SAlex Wilson BButton*
1217afc7756SAlex Wilson SettingsView::MakeRestartButton()
1227afc7756SAlex Wilson {
1237afc7756SAlex Wilson 	return new BButton("restartButton",
124176fb40fSMatt Madia 		B_TRANSLATE("Restart media services"),
125176fb40fSMatt Madia 		new BMessage(ML_RESTART_MEDIA_SERVER));
126a10cf76eSAxel Dörfler }
1272af5f895SStephan Aßmus 
1282af5f895SStephan Aßmus 
1297afc7756SAlex Wilson 
1307afc7756SAlex Wilson void
1317afc7756SAlex Wilson SettingsView::AddInputNodes(NodeList& list)
1327afc7756SAlex Wilson {
1337afc7756SAlex Wilson 	_EmptyMenu(fInputMenu);
1347afc7756SAlex Wilson 
1357afc7756SAlex Wilson 	BMessage message(MEDIA_DEFAULT_INPUT_CHANGE);
1367afc7756SAlex Wilson 	_PopulateMenu(fInputMenu, list, message);
137a10cf76eSAxel Dörfler }
138a10cf76eSAxel Dörfler 
139a633251fSAlex Wilson 
140a10cf76eSAxel Dörfler void
1417afc7756SAlex Wilson SettingsView::AddOutputNodes(NodeList& list)
142a10cf76eSAxel Dörfler {
1437afc7756SAlex Wilson 	_EmptyMenu(fOutputMenu);
1446e62e744SAlex Wilson 
1457afc7756SAlex Wilson 	BMessage message(MEDIA_DEFAULT_OUTPUT_CHANGE);
1467afc7756SAlex Wilson 	_PopulateMenu(fOutputMenu, list, message);
147a10cf76eSAxel Dörfler }
148a10cf76eSAxel Dörfler 
149a633251fSAlex Wilson 
150a10cf76eSAxel Dörfler void
1517afc7756SAlex Wilson SettingsView::SetDefaultInput(const dormant_node_info* info)
152a10cf76eSAxel Dörfler {
1537afc7756SAlex Wilson 	_ClearMenuSelection(fInputMenu);
1547afc7756SAlex Wilson 	NodeMenuItem* item = _FindNodeItem(fInputMenu, info);
1557afc7756SAlex Wilson 	if (item)
156a10cf76eSAxel Dörfler 		item->SetMarked(true);
1577afc7756SAlex Wilson }
1587afc7756SAlex Wilson 
1597afc7756SAlex Wilson 
1607afc7756SAlex Wilson void
1617afc7756SAlex Wilson SettingsView::SetDefaultOutput(const dormant_node_info* info)
1627afc7756SAlex Wilson {
1637afc7756SAlex Wilson 	_ClearMenuSelection(fOutputMenu);
1647afc7756SAlex Wilson 	NodeMenuItem* item = _FindNodeItem(fOutputMenu, info);
1657afc7756SAlex Wilson 	if (item)
1667afc7756SAlex Wilson 		item->SetMarked(true);
1677afc7756SAlex Wilson }
1687afc7756SAlex Wilson 
1697afc7756SAlex Wilson 
1707afc7756SAlex Wilson void
1717afc7756SAlex Wilson SettingsView::MessageReceived(BMessage* message)
1727afc7756SAlex Wilson {
1737afc7756SAlex Wilson 	switch (message->what) {
1747afc7756SAlex Wilson 		case MEDIA_DEFAULT_INPUT_CHANGE:
1757afc7756SAlex Wilson 		{
1767afc7756SAlex Wilson 			int32 index;
1777afc7756SAlex Wilson 			if (message->FindInt32("index", &index)!=B_OK)
1787afc7756SAlex Wilson 				break;
1797afc7756SAlex Wilson 			NodeMenuItem* item
1807afc7756SAlex Wilson 				= static_cast<NodeMenuItem*>(fInputMenu->ItemAt(index));
1817afc7756SAlex Wilson 			SetDefaultInput(item->NodeInfo());
1827afc7756SAlex Wilson 			RestartRequired(true);
183*d2772fb4SAlex Wilson 			break;
1847afc7756SAlex Wilson 		}
1857afc7756SAlex Wilson 		case MEDIA_DEFAULT_OUTPUT_CHANGE:
1867afc7756SAlex Wilson 		{
1877afc7756SAlex Wilson 			int32 index;
1887afc7756SAlex Wilson 			if (message->FindInt32("index", &index)!=B_OK)
1897afc7756SAlex Wilson 				break;
1907afc7756SAlex Wilson 			NodeMenuItem* item
1917afc7756SAlex Wilson 				= static_cast<NodeMenuItem*>(fOutputMenu->ItemAt(index));
1927afc7756SAlex Wilson 			SetDefaultOutput(item->NodeInfo());
1937afc7756SAlex Wilson 			RestartRequired(true);
194*d2772fb4SAlex Wilson 			break;
1957afc7756SAlex Wilson 		}
1967afc7756SAlex Wilson 		case ML_ENABLE_REAL_TIME:
1977afc7756SAlex Wilson 		{
1987afc7756SAlex Wilson 			uint32 flags = 0;
1997afc7756SAlex Wilson 			if (message->FindUInt32("flags", &flags) == B_OK)
2007afc7756SAlex Wilson 				_FlipRealtimeFlag(flags);
201a10cf76eSAxel Dörfler 			break;
202a10cf76eSAxel Dörfler 		}
203*d2772fb4SAlex Wilson 		default:
2047afc7756SAlex Wilson 			BGridView::MessageReceived(message);
2057afc7756SAlex Wilson 	}
206*d2772fb4SAlex Wilson }
207a10cf76eSAxel Dörfler 
208a633251fSAlex Wilson 
2097afc7756SAlex Wilson void
2107afc7756SAlex Wilson SettingsView::AttachedToWindow()
2117afc7756SAlex Wilson {
2127afc7756SAlex Wilson 	BMessenger thisMessenger(this);
2137afc7756SAlex Wilson 	fInputMenu->SetTargetForItems(thisMessenger);
2147afc7756SAlex Wilson 	fOutputMenu->SetTargetForItems(thisMessenger);
2157afc7756SAlex Wilson 	fRealtimeCheckBox->SetTarget(thisMessenger);
2167afc7756SAlex Wilson }
2177afc7756SAlex Wilson 
2187afc7756SAlex Wilson 
2197afc7756SAlex Wilson void
2207afc7756SAlex Wilson SettingsView::RestartRequired(bool required)
2217afc7756SAlex Wilson {
2227afc7756SAlex Wilson 	if (required)
2237afc7756SAlex Wilson 		fRestartView->Show();
2247afc7756SAlex Wilson 	else
2257afc7756SAlex Wilson 		fRestartView->Hide();
2267afc7756SAlex Wilson }
2277afc7756SAlex Wilson 
2287afc7756SAlex Wilson 
2297afc7756SAlex Wilson MediaWindow*
2307afc7756SAlex Wilson SettingsView::_MediaWindow() const
2317afc7756SAlex Wilson {
2327afc7756SAlex Wilson 	return static_cast<MediaWindow*>(Window());
2337afc7756SAlex Wilson }
2347afc7756SAlex Wilson 
2357afc7756SAlex Wilson 
2367afc7756SAlex Wilson void
2377afc7756SAlex Wilson SettingsView::_FlipRealtimeFlag(uint32 mask)
2387afc7756SAlex Wilson {
2390ee86c8dSAlex Wilson 	fRealtimeCheckBox->SetValue(B_CONTROL_OFF);
2400ee86c8dSAlex Wilson 	BAlert* alert = new BAlert("realtime alert", UnimplementedRealtimeError(),
2410ee86c8dSAlex Wilson 		B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
2420ee86c8dSAlex Wilson 	alert->Go();
2430ee86c8dSAlex Wilson 
2440ee86c8dSAlex Wilson #if 0
2457afc7756SAlex Wilson 	// TODO: error codes
2467afc7756SAlex Wilson 	uint32 flags = 0;
247a10cf76eSAxel Dörfler 	BMediaRoster* roster = BMediaRoster::Roster();
2487afc7756SAlex Wilson 	roster->GetRealtimeFlags(&flags);
2497afc7756SAlex Wilson 	if (flags & mask)
2507afc7756SAlex Wilson 		flags &= ~mask;
2517afc7756SAlex Wilson 	else
2527afc7756SAlex Wilson 		flags |= mask;
2537afc7756SAlex Wilson 	roster->SetRealtimeFlags(flags);
2540ee86c8dSAlex Wilson #endif
255a633251fSAlex Wilson }
256a10cf76eSAxel Dörfler 
257a10cf76eSAxel Dörfler 
2587afc7756SAlex Wilson void
2597afc7756SAlex Wilson SettingsView::_EmptyMenu(BMenu* menu)
2607afc7756SAlex Wilson {
2617afc7756SAlex Wilson 	while (menu->CountItems() > 0)
2627afc7756SAlex Wilson 		delete menu->RemoveItem((int32)0);
2637afc7756SAlex Wilson }
2647afc7756SAlex Wilson 
2657afc7756SAlex Wilson 
2667afc7756SAlex Wilson void
2677afc7756SAlex Wilson SettingsView::_PopulateMenu(BMenu* menu, NodeList& nodes,
2687afc7756SAlex Wilson 	const BMessage& message)
2697afc7756SAlex Wilson {
2707afc7756SAlex Wilson 	for (int32 i = 0; i < nodes.CountItems(); i++) {
2717afc7756SAlex Wilson 		dormant_node_info* info = nodes.ItemAt(i);
2727afc7756SAlex Wilson 		menu->AddItem(new NodeMenuItem(info, new BMessage(message)));
2737afc7756SAlex Wilson 	}
2747afc7756SAlex Wilson 
2757afc7756SAlex Wilson 	if (Window() != NULL)
2767afc7756SAlex Wilson 		menu->SetTargetForItems(BMessenger(this));
2777afc7756SAlex Wilson }
2787afc7756SAlex Wilson 
2797afc7756SAlex Wilson 
2807afc7756SAlex Wilson NodeMenuItem*
2817afc7756SAlex Wilson SettingsView::_FindNodeItem(BMenu* menu, const dormant_node_info* nodeInfo)
2827afc7756SAlex Wilson {
2837afc7756SAlex Wilson 	for (int32 i = 0; i < menu->CountItems(); i++) {
2847afc7756SAlex Wilson 		NodeMenuItem* item = static_cast<NodeMenuItem*>(menu->ItemAt(i));
2857afc7756SAlex Wilson 		const dormant_node_info* itemInfo = item->NodeInfo();
2867afc7756SAlex Wilson 		if (itemInfo && itemInfo->addon == nodeInfo->addon
2877afc7756SAlex Wilson 			&& itemInfo->flavor_id == nodeInfo->flavor_id) {
2887afc7756SAlex Wilson 			return item;
289a10cf76eSAxel Dörfler 		}
290a10cf76eSAxel Dörfler 	}
2917afc7756SAlex Wilson 	return NULL;
292a10cf76eSAxel Dörfler }
2937afc7756SAlex Wilson 
2947afc7756SAlex Wilson 
2957afc7756SAlex Wilson void
2967afc7756SAlex Wilson SettingsView::_ClearMenuSelection(BMenu* menu)
2977afc7756SAlex Wilson {
2987afc7756SAlex Wilson 	for (int32 i = 0; i < menu->CountItems(); i++) {
2997afc7756SAlex Wilson 		BMenuItem* item = menu->ItemAt(i);
3007afc7756SAlex Wilson 		item->SetMarked(false);
301a10cf76eSAxel Dörfler 	}
302a10cf76eSAxel Dörfler }
303a10cf76eSAxel Dörfler 
304a633251fSAlex Wilson 
3057afc7756SAlex Wilson NodeMenuItem::NodeMenuItem(const dormant_node_info* info, BMessage* message,
306a10cf76eSAxel Dörfler 	char shortcut, uint32 modifiers)
307a633251fSAlex Wilson 	:
308a633251fSAlex Wilson 	BMenuItem(info->name, message, shortcut, modifiers),
309b4a12470SJérôme Duval 	fInfo(info)
310a10cf76eSAxel Dörfler {
311a10cf76eSAxel Dörfler 
312a10cf76eSAxel Dörfler }
313a10cf76eSAxel Dörfler 
3146df0b2d5SJérôme Duval 
3156df0b2d5SJérôme Duval status_t
3167afc7756SAlex Wilson NodeMenuItem::Invoke(BMessage* message)
3176df0b2d5SJérôme Duval {
3186df0b2d5SJérôme Duval 	if (IsMarked())
3196df0b2d5SJérôme Duval 		return B_OK;
3206df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
3216df0b2d5SJérôme Duval }
3226df0b2d5SJérôme Duval 
3236df0b2d5SJérôme Duval 
3247afc7756SAlex Wilson ChannelMenuItem::ChannelMenuItem(media_input* input, BMessage* message,
3257afc7756SAlex Wilson 	char shortcut, uint32 modifiers)
326a633251fSAlex Wilson 	:
327a633251fSAlex Wilson 	BMenuItem(input->name, message, shortcut, modifiers),
328b4a12470SJérôme Duval 	fInput(input)
329a10cf76eSAxel Dörfler {
330a10cf76eSAxel Dörfler }
331a10cf76eSAxel Dörfler 
3326df0b2d5SJérôme Duval 
3337afc7756SAlex Wilson ChannelMenuItem::~ChannelMenuItem()
334a10cf76eSAxel Dörfler {
335b4a12470SJérôme Duval 	delete fInput;
336a10cf76eSAxel Dörfler }
337a10cf76eSAxel Dörfler 
3386df0b2d5SJérôme Duval 
3397afc7756SAlex Wilson int32
3407afc7756SAlex Wilson ChannelMenuItem::DestinationID()
3417afc7756SAlex Wilson {
3427afc7756SAlex Wilson 	return fInput->destination.id;
3437afc7756SAlex Wilson }
3447afc7756SAlex Wilson 
3457afc7756SAlex Wilson 
3467afc7756SAlex Wilson media_input*
3477afc7756SAlex Wilson ChannelMenuItem::Input()
3487afc7756SAlex Wilson {
3497afc7756SAlex Wilson 	return fInput;
3507afc7756SAlex Wilson }
3517afc7756SAlex Wilson 
3527afc7756SAlex Wilson 
3536df0b2d5SJérôme Duval status_t
3547afc7756SAlex Wilson ChannelMenuItem::Invoke(BMessage* message)
3556df0b2d5SJérôme Duval {
3566df0b2d5SJérôme Duval 	if (IsMarked())
3576df0b2d5SJérôme Duval 		return B_OK;
3586df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
3596df0b2d5SJérôme Duval }
3606df0b2d5SJérôme Duval 
3617afc7756SAlex Wilson 
3627afc7756SAlex Wilson AudioSettingsView::AudioSettingsView()
3637afc7756SAlex Wilson {
3647afc7756SAlex Wilson 	BBox* defaultsBox = new BBox("defaults");
3657afc7756SAlex Wilson 	defaultsBox->SetLabel(B_TRANSLATE("Defaults"));
3667afc7756SAlex Wilson 	BGridView* defaultsGridView = new BGridView();
3677afc7756SAlex Wilson 
3687afc7756SAlex Wilson 	BMenuField* inputMenuField = new BMenuField("inputMenuField",
3697afc7756SAlex Wilson 		B_TRANSLATE("Audio input:"), InputMenu(), NULL);
3707afc7756SAlex Wilson 
3717afc7756SAlex Wilson 	BMenuField* outputMenuField = new BMenuField("outputMenuField",
3727afc7756SAlex Wilson 		B_TRANSLATE("Audio output:"), OutputMenu(), NULL);
3737afc7756SAlex Wilson 
3747afc7756SAlex Wilson 	BLayoutBuilder::Grid<>(defaultsGridView)
3757afc7756SAlex Wilson 		.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0)
3767afc7756SAlex Wilson 		.AddMenuField(inputMenuField, 0, 0, B_ALIGN_HORIZONTAL_UNSET, 1, 3, 1)
3777afc7756SAlex Wilson 		.AddMenuField(outputMenuField, 0, 1)
3787afc7756SAlex Wilson 		.AddMenuField(_MakeChannelMenu(), 2, 1)
3797afc7756SAlex Wilson 		.Add(MakeRestartMessageView(), 0, 2, 4, 1);
3807afc7756SAlex Wilson 
3817afc7756SAlex Wilson 	defaultsBox->AddChild(defaultsGridView);
3827afc7756SAlex Wilson 
3837afc7756SAlex Wilson 	const char* realtimeLabel = B_TRANSLATE("Enable real-time audio");
3847afc7756SAlex Wilson 	const char* realtimeInfo = B_TRANSLATE(
3857afc7756SAlex Wilson 		"Enabling real-time audio allows system to record and play audio "
3867afc7756SAlex Wilson 		"as fast as possible.  It achieves this performance by using more"
3877afc7756SAlex Wilson 		" CPU and RAM.\n\nOnly enable this feature if you need the lowest"
3887afc7756SAlex Wilson 		" latency possible.");
3897afc7756SAlex Wilson 
3907afc7756SAlex Wilson 
3917afc7756SAlex Wilson 	BLayoutBuilder::Grid<>(this)
3927afc7756SAlex Wilson 		.SetInsets(0, 0, 0, 0)
3937afc7756SAlex Wilson 		.Add(defaultsBox, 0, 0, 2, 1)
3947afc7756SAlex Wilson 		.Add(MakeRealtimeBox(realtimeInfo, B_MEDIA_REALTIME_AUDIO,
3957afc7756SAlex Wilson 			realtimeLabel), 0, 1, 2, 1)
3967afc7756SAlex Wilson 		.Add(_MakeVolumeCheckBox(),0, 2, 1, 1)
3977afc7756SAlex Wilson 		.Add(MakeRestartButton(), 1, 2, 1, 1)
3987afc7756SAlex Wilson 		.SetRowWeight(1, 10);
3997afc7756SAlex Wilson }
4007afc7756SAlex Wilson 
4017afc7756SAlex Wilson 
4027afc7756SAlex Wilson void
4037afc7756SAlex Wilson AudioSettingsView::SetDefaultChannel(int32 channelID)
4047afc7756SAlex Wilson {
4057afc7756SAlex Wilson 	for (int32 i = 0; i < fChannelMenu->CountItems(); i++) {
4067afc7756SAlex Wilson 		ChannelMenuItem* item = _ChannelMenuItemAt(i);
4077afc7756SAlex Wilson 		item->SetMarked(item->DestinationID() == channelID);
4087afc7756SAlex Wilson 	}
4097afc7756SAlex Wilson }
4107afc7756SAlex Wilson 
4117afc7756SAlex Wilson 
4127afc7756SAlex Wilson void
4137afc7756SAlex Wilson AudioSettingsView::AttachedToWindow()
4147afc7756SAlex Wilson {
4157afc7756SAlex Wilson 	SettingsView::AttachedToWindow();
4167afc7756SAlex Wilson 
4177afc7756SAlex Wilson 	BMessenger thisMessenger(this);
4187afc7756SAlex Wilson 	fChannelMenu->SetTargetForItems(thisMessenger);
4197afc7756SAlex Wilson 	fVolumeCheckBox->SetTarget(thisMessenger);
4207afc7756SAlex Wilson }
4217afc7756SAlex Wilson 
4227afc7756SAlex Wilson 
4230ee86c8dSAlex Wilson BString
4240ee86c8dSAlex Wilson AudioSettingsView::UnimplementedRealtimeError()
4250ee86c8dSAlex Wilson {
4260ee86c8dSAlex Wilson 	return B_TRANSLATE("Real-time audio is currently unimplemented in Haiku.");
4270ee86c8dSAlex Wilson }
4280ee86c8dSAlex Wilson 
4290ee86c8dSAlex Wilson 
4307afc7756SAlex Wilson void
4317afc7756SAlex Wilson AudioSettingsView::MessageReceived(BMessage* message)
4327afc7756SAlex Wilson {
4337afc7756SAlex Wilson 	switch (message->what) {
4347afc7756SAlex Wilson 		case ML_DEFAULT_CHANNEL_CHANGED:
4357afc7756SAlex Wilson 			{
4367afc7756SAlex Wilson 				int32 index;
4377afc7756SAlex Wilson 				if (message->FindInt32("index", &index) != B_OK)
4387afc7756SAlex Wilson 					break;
4397afc7756SAlex Wilson 				ChannelMenuItem* item = _ChannelMenuItemAt(index);
4407afc7756SAlex Wilson 
4417afc7756SAlex Wilson 				if (item) {
4427afc7756SAlex Wilson 					BMediaRoster* roster = BMediaRoster::Roster();
4437afc7756SAlex Wilson 					roster->SetAudioOutput(*item->Input());
4447afc7756SAlex Wilson 					RestartRequired(true);
4457afc7756SAlex Wilson 				} else
4467afc7756SAlex Wilson 					fprintf(stderr, "ChannelMenuItem not found\n");
4477afc7756SAlex Wilson 			}
4487afc7756SAlex Wilson 			break;
4497afc7756SAlex Wilson 		case MEDIA_SHOW_HIDE_VOLUME_CONTROL:
4507afc7756SAlex Wilson 		{
4517afc7756SAlex Wilson 			if (fVolumeCheckBox->Value() == B_CONTROL_ON)
4527afc7756SAlex Wilson 				_ShowDeskbarVolumeControl();
4537afc7756SAlex Wilson 			else
4547afc7756SAlex Wilson 				_HideDeskbarVolumeControl();
4557afc7756SAlex Wilson 			break;
4567afc7756SAlex Wilson 		}
4577afc7756SAlex Wilson 
4587afc7756SAlex Wilson 		default:
4597afc7756SAlex Wilson 			SettingsView::MessageReceived(message);
4607afc7756SAlex Wilson 	}
4617afc7756SAlex Wilson }
4627afc7756SAlex Wilson 
4637afc7756SAlex Wilson 
4647afc7756SAlex Wilson void
4657afc7756SAlex Wilson AudioSettingsView::SetDefaultInput(const dormant_node_info* info)
4667afc7756SAlex Wilson {
4677afc7756SAlex Wilson 	SettingsView::SetDefaultInput(info);
4687afc7756SAlex Wilson 	_MediaWindow()->UpdateInputListItem(MediaListItem::AUDIO_TYPE, info);
4697afc7756SAlex Wilson 	BMediaRoster::Roster()->SetAudioInput(*info);
4707afc7756SAlex Wilson }
4717afc7756SAlex Wilson 
4727afc7756SAlex Wilson 
4737afc7756SAlex Wilson void
4747afc7756SAlex Wilson AudioSettingsView::SetDefaultOutput(const dormant_node_info* info)
4757afc7756SAlex Wilson {
4767afc7756SAlex Wilson 	SettingsView::SetDefaultOutput(info);
4777afc7756SAlex Wilson 	_MediaWindow()->UpdateOutputListItem(MediaListItem::AUDIO_TYPE, info);
4787afc7756SAlex Wilson 	_FillChannelMenu(info);
4797afc7756SAlex Wilson 	BMediaRoster::Roster()->SetAudioOutput(*info);
4807afc7756SAlex Wilson }
4817afc7756SAlex Wilson 
4827afc7756SAlex Wilson 
4837afc7756SAlex Wilson BMenuField*
4847afc7756SAlex Wilson AudioSettingsView::_MakeChannelMenu()
4857afc7756SAlex Wilson {
4867afc7756SAlex Wilson 	fChannelMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
4877afc7756SAlex Wilson 	fChannelMenu->SetLabelFromMarked(true);
4887afc7756SAlex Wilson 	BMenuField* channelMenuField = new BMenuField("channelMenuField",
4897afc7756SAlex Wilson 		B_TRANSLATE("Channel:"), fChannelMenu, NULL);
4907afc7756SAlex Wilson 	return channelMenuField;
4917afc7756SAlex Wilson }
4927afc7756SAlex Wilson 
4937afc7756SAlex Wilson 
4947afc7756SAlex Wilson BCheckBox*
4957afc7756SAlex Wilson AudioSettingsView::_MakeVolumeCheckBox()
4967afc7756SAlex Wilson {
4977afc7756SAlex Wilson 	fVolumeCheckBox = new BCheckBox("volumeCheckBox",
4987afc7756SAlex Wilson 		B_TRANSLATE("Show volume control on Deskbar"),
4997afc7756SAlex Wilson 		new BMessage(MEDIA_SHOW_HIDE_VOLUME_CONTROL));
5007afc7756SAlex Wilson 
5017afc7756SAlex Wilson 	if (BDeskbar().HasItem("MediaReplicant"))
5027afc7756SAlex Wilson 		fVolumeCheckBox->SetValue(B_CONTROL_ON);
5037afc7756SAlex Wilson 
5047afc7756SAlex Wilson 	return fVolumeCheckBox;
5057afc7756SAlex Wilson }
5067afc7756SAlex Wilson 
5077afc7756SAlex Wilson 
5087afc7756SAlex Wilson void
5097afc7756SAlex Wilson AudioSettingsView::_FillChannelMenu(const dormant_node_info* nodeInfo)
5107afc7756SAlex Wilson {
5117afc7756SAlex Wilson 	_EmptyMenu(fChannelMenu);
5127afc7756SAlex Wilson 
5137afc7756SAlex Wilson 	BMediaRoster* roster = BMediaRoster::Roster();
5147afc7756SAlex Wilson 	media_node node;
5157afc7756SAlex Wilson 	media_node_id node_id;
5167afc7756SAlex Wilson 
5177afc7756SAlex Wilson 	status_t err = roster->GetInstancesFor(nodeInfo->addon,
5187afc7756SAlex Wilson 		nodeInfo->flavor_id, &node_id);
5197afc7756SAlex Wilson 	if (err != B_OK) {
5207afc7756SAlex Wilson 		err = roster->InstantiateDormantNode(*nodeInfo, &node,
5217afc7756SAlex Wilson 			B_FLAVOR_IS_GLOBAL);
5227afc7756SAlex Wilson 	} else {
5237afc7756SAlex Wilson 		err = roster->GetNodeFor(node_id, &node);
5247afc7756SAlex Wilson 	}
5257afc7756SAlex Wilson 
5267afc7756SAlex Wilson 	if (err == B_OK) {
5277afc7756SAlex Wilson 		int32 inputCount = 4;
5287afc7756SAlex Wilson 		media_input* inputs = new media_input[inputCount];
5297afc7756SAlex Wilson 		BPrivate::ArrayDeleter<media_input> inputDeleter(inputs);
5307afc7756SAlex Wilson 
5317afc7756SAlex Wilson 		while (true) {
5327afc7756SAlex Wilson 			int32 realInputCount = 0;
5337afc7756SAlex Wilson 			err = roster->GetAllInputsFor(node, inputs,
5347afc7756SAlex Wilson 				inputCount, &realInputCount);
5357afc7756SAlex Wilson 			if (realInputCount > inputCount) {
5367afc7756SAlex Wilson 				inputCount *= 2;
5377afc7756SAlex Wilson 				inputs = new media_input[inputCount];
5387afc7756SAlex Wilson 				inputDeleter.SetTo(inputs);
5397afc7756SAlex Wilson 			} else {
5407afc7756SAlex Wilson 				inputCount = realInputCount;
5417afc7756SAlex Wilson 				break;
5427afc7756SAlex Wilson 			}
5437afc7756SAlex Wilson 		}
5447afc7756SAlex Wilson 
5457afc7756SAlex Wilson 		if (err == B_OK) {
5467afc7756SAlex Wilson 			BMessage message(ML_DEFAULT_CHANNEL_CHANGED);
5477afc7756SAlex Wilson 
5487afc7756SAlex Wilson 			for (int32 i = 0; i < inputCount; i++) {
5497afc7756SAlex Wilson 				media_input* input = new media_input();
5507afc7756SAlex Wilson 				memcpy(input, &inputs[i], sizeof(*input));
5517afc7756SAlex Wilson 				ChannelMenuItem* channelItem = new ChannelMenuItem(input,
5527afc7756SAlex Wilson 					new BMessage(message));
5537afc7756SAlex Wilson 				fChannelMenu->AddItem(channelItem);
5547afc7756SAlex Wilson 
5557afc7756SAlex Wilson 				if (channelItem->DestinationID() == 0)
5567afc7756SAlex Wilson 					channelItem->SetMarked(true);
5577afc7756SAlex Wilson 			}
5587afc7756SAlex Wilson 		}
5597afc7756SAlex Wilson 	}
5607afc7756SAlex Wilson 
5617afc7756SAlex Wilson 	if (Window())
5627afc7756SAlex Wilson 		fChannelMenu->SetTargetForItems(BMessenger(this));
5637afc7756SAlex Wilson }
5647afc7756SAlex Wilson 
5657afc7756SAlex Wilson 
5667afc7756SAlex Wilson void
5677afc7756SAlex Wilson AudioSettingsView::_ShowDeskbarVolumeControl()
5687afc7756SAlex Wilson {
5697afc7756SAlex Wilson 	BDeskbar deskbar;
5707afc7756SAlex Wilson 	BEntry entry("/bin/desklink", true);
5717afc7756SAlex Wilson 	int32 id;
5727afc7756SAlex Wilson 	entry_ref ref;
5737afc7756SAlex Wilson 	status_t status = entry.GetRef(&ref);
5747afc7756SAlex Wilson 	if (status == B_OK)
5757afc7756SAlex Wilson 		status = deskbar.AddItem(&ref, &id);
5767afc7756SAlex Wilson 
5777afc7756SAlex Wilson 	if (status != B_OK) {
5787afc7756SAlex Wilson 		fprintf(stderr, B_TRANSLATE(
5797afc7756SAlex Wilson 			"Couldn't add volume control in Deskbar: %s\n"),
5807afc7756SAlex Wilson 			strerror(status));
5817afc7756SAlex Wilson 	}
5827afc7756SAlex Wilson }
5837afc7756SAlex Wilson 
5847afc7756SAlex Wilson 
5857afc7756SAlex Wilson void
5867afc7756SAlex Wilson AudioSettingsView::_HideDeskbarVolumeControl()
5877afc7756SAlex Wilson {
5887afc7756SAlex Wilson 	BDeskbar deskbar;
5897afc7756SAlex Wilson 	status_t status = deskbar.RemoveItem("MediaReplicant");
5907afc7756SAlex Wilson 	if (status != B_OK) {
5917afc7756SAlex Wilson 		fprintf(stderr, B_TRANSLATE(
5927afc7756SAlex Wilson 			"Couldn't remove volume control in Deskbar: %s\n"),
5937afc7756SAlex Wilson 			strerror(status));
5947afc7756SAlex Wilson 	}
5957afc7756SAlex Wilson }
5967afc7756SAlex Wilson 
5977afc7756SAlex Wilson 
5987afc7756SAlex Wilson ChannelMenuItem*
5997afc7756SAlex Wilson AudioSettingsView::_ChannelMenuItemAt(int32 index)
6007afc7756SAlex Wilson {
6017afc7756SAlex Wilson 	return static_cast<ChannelMenuItem*>(fChannelMenu->ItemAt(index));
6027afc7756SAlex Wilson }
6037afc7756SAlex Wilson 
6047afc7756SAlex Wilson 
6057afc7756SAlex Wilson VideoSettingsView::VideoSettingsView()
6067afc7756SAlex Wilson {
6077afc7756SAlex Wilson 	BBox* defaultsBox = new BBox("defaults");
6087afc7756SAlex Wilson 	defaultsBox->SetLabel(B_TRANSLATE("Defaults"));
6097afc7756SAlex Wilson 	BGridView* defaultsGridView = new BGridView();
6107afc7756SAlex Wilson 
6117afc7756SAlex Wilson 	BMenuField* inputMenuField = new BMenuField("inputMenuField",
6127afc7756SAlex Wilson 		B_TRANSLATE("Video input:"), InputMenu(), NULL);
6137afc7756SAlex Wilson 
6147afc7756SAlex Wilson 	BMenuField* outputMenuField = new BMenuField("outputMenuField",
6157afc7756SAlex Wilson 		B_TRANSLATE("Video output:"), OutputMenu(), NULL);
6167afc7756SAlex Wilson 
6177afc7756SAlex Wilson 	BLayoutBuilder::Grid<>(defaultsGridView)
6187afc7756SAlex Wilson 		.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0)
6197afc7756SAlex Wilson 		.AddMenuField(inputMenuField, 0, 0)
6207afc7756SAlex Wilson 		.AddMenuField(outputMenuField, 0, 1)
6217afc7756SAlex Wilson 		.Add(MakeRestartMessageView(), 0, 2, 2, 1);
6227afc7756SAlex Wilson 
6237afc7756SAlex Wilson 	defaultsBox->AddChild(defaultsGridView);
6247afc7756SAlex Wilson 
6257afc7756SAlex Wilson 	const char* realtimeLabel = B_TRANSLATE("Enable real-time video");
6267afc7756SAlex Wilson 	const char*	realtimeInfo = B_TRANSLATE(
6277afc7756SAlex Wilson 		"Enabling real-time video allows system to "
6287afc7756SAlex Wilson 		"perform video operations as fast and smoothly as possible.  It "
6297afc7756SAlex Wilson 		"achieves optimum performance by using more RAM.\n\n"
6307afc7756SAlex Wilson 		"Only enable this feature if you need the lowest latency possible.");
6317afc7756SAlex Wilson 
6327afc7756SAlex Wilson 	BLayoutBuilder::Grid<>(this)
6337afc7756SAlex Wilson 		.SetInsets(0, 0, 0, 0)
6347afc7756SAlex Wilson 		.Add(defaultsBox, 0, 0, 2, 1)
6357afc7756SAlex Wilson 		.Add(MakeRealtimeBox(realtimeInfo, B_MEDIA_REALTIME_VIDEO,
6367afc7756SAlex Wilson 			realtimeLabel), 0, 1, 2, 1)
6377afc7756SAlex Wilson 		.Add(MakeRestartButton(), 1, 2, 1, 1)
6387afc7756SAlex Wilson 		.SetRowWeight(1, 10);
6397afc7756SAlex Wilson }
6407afc7756SAlex Wilson 
6417afc7756SAlex Wilson 
6427afc7756SAlex Wilson void
6437afc7756SAlex Wilson VideoSettingsView::SetDefaultInput(const dormant_node_info* info)
6447afc7756SAlex Wilson {
6457afc7756SAlex Wilson 	SettingsView::SetDefaultInput(info);
6467afc7756SAlex Wilson 	_MediaWindow()->UpdateInputListItem(MediaListItem::VIDEO_TYPE, info);
6477afc7756SAlex Wilson 	BMediaRoster::Roster()->SetVideoInput(*info);
6487afc7756SAlex Wilson }
6497afc7756SAlex Wilson 
6507afc7756SAlex Wilson 
6517afc7756SAlex Wilson void
6527afc7756SAlex Wilson VideoSettingsView::SetDefaultOutput(const dormant_node_info* info)
6537afc7756SAlex Wilson {
6547afc7756SAlex Wilson 	SettingsView::SetDefaultOutput(info);
6557afc7756SAlex Wilson 	_MediaWindow()->UpdateOutputListItem(MediaListItem::VIDEO_TYPE, info);
6567afc7756SAlex Wilson 	BMediaRoster::Roster()->SetVideoOutput(*info);
6577afc7756SAlex Wilson }
6580ee86c8dSAlex Wilson 
6590ee86c8dSAlex Wilson 
6600ee86c8dSAlex Wilson BString
6610ee86c8dSAlex Wilson VideoSettingsView::UnimplementedRealtimeError()
6620ee86c8dSAlex Wilson {
6630ee86c8dSAlex Wilson 	return B_TRANSLATE("Real-time video is currently unimplemented in Haiku.");
6640ee86c8dSAlex Wilson }
6650ee86c8dSAlex Wilson 
666