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