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 17*7afc7756SAlex Wilson #include <AutoDeleter.h> 18a10cf76eSAxel Dörfler #include <Box.h> 19a10cf76eSAxel Dörfler #include <Button.h> 20f8a1135cSAdrien Destugues #include <Catalog.h> 21*7afc7756SAlex Wilson #include <CheckBox.h> 22a10cf76eSAxel Dörfler #include <Deskbar.h> 23a10cf76eSAxel Dörfler #include <Entry.h> 24*7afc7756SAlex Wilson #include <LayoutBuilder.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> 30a10cf76eSAxel Dörfler #include <String.h> 31*7afc7756SAlex Wilson #include <StringView.h> 32b4a12470SJérôme Duval #include <TextView.h> 332af5f895SStephan Aßmus 34*7afc7756SAlex Wilson #include <assert.h> 35a633251fSAlex Wilson #include <stdio.h> 36a10cf76eSAxel Dörfler 37*7afc7756SAlex Wilson #include "MediaWindow.h" 38*7afc7756SAlex Wilson 399cedafe6SWim van der Meer 409cedafe6SWim van der Meer #undef B_TRANSLATE_CONTEXT 414eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Media views" 42f8a1135cSAdrien Destugues 43*7afc7756SAlex Wilson #define MEDIA_DEFAULT_INPUT_CHANGE 'dich' 44*7afc7756SAlex Wilson #define MEDIA_DEFAULT_OUTPUT_CHANGE 'doch' 45*7afc7756SAlex Wilson #define MEDIA_SHOW_HIDE_VOLUME_CONTROL 'shvc' 469cedafe6SWim van der Meer 47*7afc7756SAlex Wilson 48*7afc7756SAlex Wilson SettingsView::SettingsView() 49a633251fSAlex Wilson : 50*7afc7756SAlex Wilson BGridView(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING), 51*7afc7756SAlex Wilson fRealtimeCheckBox(NULL), 52*7afc7756SAlex Wilson fInputMenu(NULL), 53*7afc7756SAlex Wilson fOutputMenu(NULL), 54*7afc7756SAlex Wilson fRestartView(NULL) 55a10cf76eSAxel Dörfler { 566e62e744SAlex Wilson // input menu 576e62e744SAlex Wilson fInputMenu = new BPopUpMenu(B_TRANSLATE("<none>")); 586e62e744SAlex Wilson fInputMenu->SetLabelFromMarked(true); 596e62e744SAlex Wilson 60*7afc7756SAlex Wilson // input menu 616e62e744SAlex Wilson fOutputMenu = new BPopUpMenu(B_TRANSLATE("<none>")); 626e62e744SAlex Wilson fOutputMenu->SetLabelFromMarked(true); 636e62e744SAlex Wilson } 646e62e744SAlex Wilson 652af5f895SStephan Aßmus 66*7afc7756SAlex Wilson BBox* 67*7afc7756SAlex Wilson SettingsView::MakeRealtimeBox(const char* info, uint32 realtimeMask, 68*7afc7756SAlex Wilson const char* checkBoxLabel) 69*7afc7756SAlex Wilson { 702af5f895SStephan Aßmus // create the realtime box 71c8602bcdSRene Gollent BBox* realtimeBox = new BBox("realtime"); 72176fb40fSMatt Madia realtimeBox->SetLabel(B_TRANSLATE("Real-time")); 73a10cf76eSAxel Dörfler 74*7afc7756SAlex Wilson BMessage* checkBoxMessage = new BMessage(ML_ENABLE_REAL_TIME); 75*7afc7756SAlex Wilson checkBoxMessage->AddUInt32("flags", realtimeMask); 76*7afc7756SAlex Wilson fRealtimeCheckBox = new BCheckBox("realtimeCheckBox", checkBoxLabel, 77*7afc7756SAlex Wilson checkBoxMessage); 78a10cf76eSAxel Dörfler 79*7afc7756SAlex Wilson uint32 flags = 0; 80a10cf76eSAxel Dörfler BMediaRoster::Roster()->GetRealtimeFlags(&flags); 81*7afc7756SAlex Wilson if (flags & realtimeMask) 82b4a12470SJérôme Duval fRealtimeCheckBox->SetValue(B_CONTROL_ON); 83a10cf76eSAxel Dörfler 84c8602bcdSRene Gollent BTextView* textView = new BTextView("stringView"); 85*7afc7756SAlex Wilson textView->Insert(info); 86b4a12470SJérôme Duval textView->MakeEditable(false); 87b4a12470SJérôme Duval textView->MakeSelectable(false); 88a10cf76eSAxel Dörfler textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 89a10cf76eSAxel Dörfler 90*7afc7756SAlex Wilson BGroupView* realtimeGroup = new BGroupView(B_VERTICAL); 91*7afc7756SAlex Wilson BLayoutBuilder::Group<>(realtimeGroup) 92*7afc7756SAlex Wilson .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 93*7afc7756SAlex Wilson B_USE_DEFAULT_SPACING) 94*7afc7756SAlex Wilson .Add(fRealtimeCheckBox) 95*7afc7756SAlex Wilson .Add(textView); 962af5f895SStephan Aßmus 97*7afc7756SAlex Wilson realtimeBox->AddChild(realtimeGroup); 98*7afc7756SAlex Wilson return realtimeBox; 99*7afc7756SAlex Wilson } 1002af5f895SStephan Aßmus 101*7afc7756SAlex Wilson 102*7afc7756SAlex Wilson BStringView* 103*7afc7756SAlex Wilson SettingsView::MakeRestartMessageView() 104*7afc7756SAlex Wilson { 105*7afc7756SAlex Wilson // note: this ought to display at the bottom of the default box... 106*7afc7756SAlex Wilson fRestartView = new BStringView("restartStringView", 107*7afc7756SAlex Wilson B_TRANSLATE("Restart the media server to apply changes.")); 108*7afc7756SAlex Wilson fRestartView->SetHighColor(ui_color(B_FAILURE_COLOR)); 109*7afc7756SAlex Wilson // not exactly failure, but sort of. 110*7afc7756SAlex Wilson fRestartView->Hide(); 111*7afc7756SAlex Wilson fRestartView->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER, 112*7afc7756SAlex Wilson B_ALIGN_VERTICAL_CENTER)); 113*7afc7756SAlex Wilson fRestartView->SetAlignment(B_ALIGN_HORIZONTAL_CENTER); 114*7afc7756SAlex Wilson fRestartView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); 115*7afc7756SAlex Wilson return fRestartView; 116*7afc7756SAlex Wilson } 117*7afc7756SAlex Wilson 118*7afc7756SAlex Wilson 119*7afc7756SAlex Wilson BButton* 120*7afc7756SAlex Wilson SettingsView::MakeRestartButton() 121*7afc7756SAlex Wilson { 122*7afc7756SAlex Wilson return new BButton("restartButton", 123176fb40fSMatt Madia B_TRANSLATE("Restart media services"), 124176fb40fSMatt Madia new BMessage(ML_RESTART_MEDIA_SERVER)); 125a10cf76eSAxel Dörfler } 1262af5f895SStephan Aßmus 1272af5f895SStephan Aßmus 128*7afc7756SAlex Wilson 129*7afc7756SAlex Wilson void 130*7afc7756SAlex Wilson SettingsView::AddInputNodes(NodeList& list) 131*7afc7756SAlex Wilson { 132*7afc7756SAlex Wilson _EmptyMenu(fInputMenu); 133*7afc7756SAlex Wilson 134*7afc7756SAlex Wilson BMessage message(MEDIA_DEFAULT_INPUT_CHANGE); 135*7afc7756SAlex Wilson _PopulateMenu(fInputMenu, list, message); 136a10cf76eSAxel Dörfler } 137a10cf76eSAxel Dörfler 138a633251fSAlex Wilson 139a10cf76eSAxel Dörfler void 140*7afc7756SAlex Wilson SettingsView::AddOutputNodes(NodeList& list) 141a10cf76eSAxel Dörfler { 142*7afc7756SAlex Wilson _EmptyMenu(fOutputMenu); 1436e62e744SAlex Wilson 144*7afc7756SAlex Wilson BMessage message(MEDIA_DEFAULT_OUTPUT_CHANGE); 145*7afc7756SAlex Wilson _PopulateMenu(fOutputMenu, list, message); 146a10cf76eSAxel Dörfler } 147a10cf76eSAxel Dörfler 148a633251fSAlex Wilson 149a10cf76eSAxel Dörfler void 150*7afc7756SAlex Wilson SettingsView::SetDefaultInput(const dormant_node_info* info) 151a10cf76eSAxel Dörfler { 152*7afc7756SAlex Wilson _ClearMenuSelection(fInputMenu); 153*7afc7756SAlex Wilson NodeMenuItem* item = _FindNodeItem(fInputMenu, info); 154*7afc7756SAlex Wilson if (item) 155a10cf76eSAxel Dörfler item->SetMarked(true); 156*7afc7756SAlex Wilson } 157*7afc7756SAlex Wilson 158*7afc7756SAlex Wilson 159*7afc7756SAlex Wilson void 160*7afc7756SAlex Wilson SettingsView::SetDefaultOutput(const dormant_node_info* info) 161*7afc7756SAlex Wilson { 162*7afc7756SAlex Wilson _ClearMenuSelection(fOutputMenu); 163*7afc7756SAlex Wilson NodeMenuItem* item = _FindNodeItem(fOutputMenu, info); 164*7afc7756SAlex Wilson if (item) 165*7afc7756SAlex Wilson item->SetMarked(true); 166*7afc7756SAlex Wilson } 167*7afc7756SAlex Wilson 168*7afc7756SAlex Wilson 169*7afc7756SAlex Wilson void 170*7afc7756SAlex Wilson SettingsView::MessageReceived(BMessage* message) 171*7afc7756SAlex Wilson { 172*7afc7756SAlex Wilson switch (message->what) { 173*7afc7756SAlex Wilson case MEDIA_DEFAULT_INPUT_CHANGE: 174*7afc7756SAlex Wilson { 175*7afc7756SAlex Wilson int32 index; 176*7afc7756SAlex Wilson if (message->FindInt32("index", &index)!=B_OK) 177*7afc7756SAlex Wilson break; 178*7afc7756SAlex Wilson NodeMenuItem* item 179*7afc7756SAlex Wilson = static_cast<NodeMenuItem*>(fInputMenu->ItemAt(index)); 180*7afc7756SAlex Wilson SetDefaultInput(item->NodeInfo()); 181*7afc7756SAlex Wilson RestartRequired(true); 182*7afc7756SAlex Wilson } 183*7afc7756SAlex Wilson case MEDIA_DEFAULT_OUTPUT_CHANGE: 184*7afc7756SAlex Wilson { 185*7afc7756SAlex Wilson int32 index; 186*7afc7756SAlex Wilson if (message->FindInt32("index", &index)!=B_OK) 187*7afc7756SAlex Wilson break; 188*7afc7756SAlex Wilson NodeMenuItem* item 189*7afc7756SAlex Wilson = static_cast<NodeMenuItem*>(fOutputMenu->ItemAt(index)); 190*7afc7756SAlex Wilson SetDefaultOutput(item->NodeInfo()); 191*7afc7756SAlex Wilson RestartRequired(true); 192*7afc7756SAlex Wilson } 193*7afc7756SAlex Wilson case ML_ENABLE_REAL_TIME: 194*7afc7756SAlex Wilson { 195*7afc7756SAlex Wilson uint32 flags = 0; 196*7afc7756SAlex Wilson if (message->FindUInt32("flags", &flags) == B_OK) 197*7afc7756SAlex Wilson _FlipRealtimeFlag(flags); 198a10cf76eSAxel Dörfler break; 199a10cf76eSAxel Dörfler } 200a10cf76eSAxel Dörfler } 201*7afc7756SAlex Wilson BGridView::MessageReceived(message); 202*7afc7756SAlex Wilson } 203a10cf76eSAxel Dörfler 204a633251fSAlex Wilson 205*7afc7756SAlex Wilson void 206*7afc7756SAlex Wilson SettingsView::AttachedToWindow() 207*7afc7756SAlex Wilson { 208*7afc7756SAlex Wilson BMessenger thisMessenger(this); 209*7afc7756SAlex Wilson fInputMenu->SetTargetForItems(thisMessenger); 210*7afc7756SAlex Wilson fOutputMenu->SetTargetForItems(thisMessenger); 211*7afc7756SAlex Wilson fRealtimeCheckBox->SetTarget(thisMessenger); 212*7afc7756SAlex Wilson } 213*7afc7756SAlex Wilson 214*7afc7756SAlex Wilson 215*7afc7756SAlex Wilson void 216*7afc7756SAlex Wilson SettingsView::RestartRequired(bool required) 217*7afc7756SAlex Wilson { 218*7afc7756SAlex Wilson if (required) 219*7afc7756SAlex Wilson fRestartView->Show(); 220*7afc7756SAlex Wilson else 221*7afc7756SAlex Wilson fRestartView->Hide(); 222*7afc7756SAlex Wilson } 223*7afc7756SAlex Wilson 224*7afc7756SAlex Wilson 225*7afc7756SAlex Wilson MediaWindow* 226*7afc7756SAlex Wilson SettingsView::_MediaWindow() const 227*7afc7756SAlex Wilson { 228*7afc7756SAlex Wilson return static_cast<MediaWindow*>(Window()); 229*7afc7756SAlex Wilson } 230*7afc7756SAlex Wilson 231*7afc7756SAlex Wilson 232*7afc7756SAlex Wilson void 233*7afc7756SAlex Wilson SettingsView::_FlipRealtimeFlag(uint32 mask) 234*7afc7756SAlex Wilson { 235*7afc7756SAlex Wilson // TODO: error codes 236*7afc7756SAlex Wilson uint32 flags = 0; 237a10cf76eSAxel Dörfler BMediaRoster* roster = BMediaRoster::Roster(); 238*7afc7756SAlex Wilson roster->GetRealtimeFlags(&flags); 239*7afc7756SAlex Wilson if (flags & mask) 240*7afc7756SAlex Wilson flags &= ~mask; 241*7afc7756SAlex Wilson else 242*7afc7756SAlex Wilson flags |= mask; 243*7afc7756SAlex Wilson roster->SetRealtimeFlags(flags); 244a633251fSAlex Wilson } 245a10cf76eSAxel Dörfler 246a10cf76eSAxel Dörfler 247*7afc7756SAlex Wilson void 248*7afc7756SAlex Wilson SettingsView::_EmptyMenu(BMenu* menu) 249*7afc7756SAlex Wilson { 250*7afc7756SAlex Wilson while (menu->CountItems() > 0) 251*7afc7756SAlex Wilson delete menu->RemoveItem((int32)0); 252*7afc7756SAlex Wilson } 253*7afc7756SAlex Wilson 254*7afc7756SAlex Wilson 255*7afc7756SAlex Wilson void 256*7afc7756SAlex Wilson SettingsView::_PopulateMenu(BMenu* menu, NodeList& nodes, 257*7afc7756SAlex Wilson const BMessage& message) 258*7afc7756SAlex Wilson { 259*7afc7756SAlex Wilson for (int32 i = 0; i < nodes.CountItems(); i++) { 260*7afc7756SAlex Wilson dormant_node_info* info = nodes.ItemAt(i); 261*7afc7756SAlex Wilson menu->AddItem(new NodeMenuItem(info, new BMessage(message))); 262*7afc7756SAlex Wilson } 263*7afc7756SAlex Wilson 264*7afc7756SAlex Wilson if (Window() != NULL) 265*7afc7756SAlex Wilson menu->SetTargetForItems(BMessenger(this)); 266*7afc7756SAlex Wilson } 267*7afc7756SAlex Wilson 268*7afc7756SAlex Wilson 269*7afc7756SAlex Wilson NodeMenuItem* 270*7afc7756SAlex Wilson SettingsView::_FindNodeItem(BMenu* menu, const dormant_node_info* nodeInfo) 271*7afc7756SAlex Wilson { 272*7afc7756SAlex Wilson for (int32 i = 0; i < menu->CountItems(); i++) { 273*7afc7756SAlex Wilson NodeMenuItem* item = static_cast<NodeMenuItem*>(menu->ItemAt(i)); 274*7afc7756SAlex Wilson const dormant_node_info* itemInfo = item->NodeInfo(); 275*7afc7756SAlex Wilson if (itemInfo && itemInfo->addon == nodeInfo->addon 276*7afc7756SAlex Wilson && itemInfo->flavor_id == nodeInfo->flavor_id) { 277*7afc7756SAlex Wilson return item; 278a10cf76eSAxel Dörfler } 279a10cf76eSAxel Dörfler } 280*7afc7756SAlex Wilson return NULL; 281a10cf76eSAxel Dörfler } 282*7afc7756SAlex Wilson 283*7afc7756SAlex Wilson 284*7afc7756SAlex Wilson void 285*7afc7756SAlex Wilson SettingsView::_ClearMenuSelection(BMenu* menu) 286*7afc7756SAlex Wilson { 287*7afc7756SAlex Wilson for (int32 i = 0; i < menu->CountItems(); i++) { 288*7afc7756SAlex Wilson BMenuItem* item = menu->ItemAt(i); 289*7afc7756SAlex Wilson item->SetMarked(false); 290a10cf76eSAxel Dörfler } 291a10cf76eSAxel Dörfler } 292a10cf76eSAxel Dörfler 293a633251fSAlex Wilson 294*7afc7756SAlex Wilson NodeMenuItem::NodeMenuItem(const dormant_node_info* info, BMessage* message, 295a10cf76eSAxel Dörfler char shortcut, uint32 modifiers) 296a633251fSAlex Wilson : 297a633251fSAlex Wilson BMenuItem(info->name, message, shortcut, modifiers), 298b4a12470SJérôme Duval fInfo(info) 299a10cf76eSAxel Dörfler { 300a10cf76eSAxel Dörfler 301a10cf76eSAxel Dörfler } 302a10cf76eSAxel Dörfler 3036df0b2d5SJérôme Duval 3046df0b2d5SJérôme Duval status_t 305*7afc7756SAlex Wilson NodeMenuItem::Invoke(BMessage* message) 3066df0b2d5SJérôme Duval { 3076df0b2d5SJérôme Duval if (IsMarked()) 3086df0b2d5SJérôme Duval return B_OK; 3096df0b2d5SJérôme Duval return BMenuItem::Invoke(message); 3106df0b2d5SJérôme Duval } 3116df0b2d5SJérôme Duval 3126df0b2d5SJérôme Duval 313*7afc7756SAlex Wilson ChannelMenuItem::ChannelMenuItem(media_input* input, BMessage* message, 314*7afc7756SAlex Wilson char shortcut, uint32 modifiers) 315a633251fSAlex Wilson : 316a633251fSAlex Wilson BMenuItem(input->name, message, shortcut, modifiers), 317b4a12470SJérôme Duval fInput(input) 318a10cf76eSAxel Dörfler { 319a10cf76eSAxel Dörfler } 320a10cf76eSAxel Dörfler 3216df0b2d5SJérôme Duval 322*7afc7756SAlex Wilson ChannelMenuItem::~ChannelMenuItem() 323a10cf76eSAxel Dörfler { 324b4a12470SJérôme Duval delete fInput; 325a10cf76eSAxel Dörfler } 326a10cf76eSAxel Dörfler 3276df0b2d5SJérôme Duval 328*7afc7756SAlex Wilson int32 329*7afc7756SAlex Wilson ChannelMenuItem::DestinationID() 330*7afc7756SAlex Wilson { 331*7afc7756SAlex Wilson return fInput->destination.id; 332*7afc7756SAlex Wilson } 333*7afc7756SAlex Wilson 334*7afc7756SAlex Wilson 335*7afc7756SAlex Wilson media_input* 336*7afc7756SAlex Wilson ChannelMenuItem::Input() 337*7afc7756SAlex Wilson { 338*7afc7756SAlex Wilson return fInput; 339*7afc7756SAlex Wilson } 340*7afc7756SAlex Wilson 341*7afc7756SAlex Wilson 3426df0b2d5SJérôme Duval status_t 343*7afc7756SAlex Wilson ChannelMenuItem::Invoke(BMessage* message) 3446df0b2d5SJérôme Duval { 3456df0b2d5SJérôme Duval if (IsMarked()) 3466df0b2d5SJérôme Duval return B_OK; 3476df0b2d5SJérôme Duval return BMenuItem::Invoke(message); 3486df0b2d5SJérôme Duval } 3496df0b2d5SJérôme Duval 350*7afc7756SAlex Wilson 351*7afc7756SAlex Wilson AudioSettingsView::AudioSettingsView() 352*7afc7756SAlex Wilson { 353*7afc7756SAlex Wilson BBox* defaultsBox = new BBox("defaults"); 354*7afc7756SAlex Wilson defaultsBox->SetLabel(B_TRANSLATE("Defaults")); 355*7afc7756SAlex Wilson BGridView* defaultsGridView = new BGridView(); 356*7afc7756SAlex Wilson 357*7afc7756SAlex Wilson BMenuField* inputMenuField = new BMenuField("inputMenuField", 358*7afc7756SAlex Wilson B_TRANSLATE("Audio input:"), InputMenu(), NULL); 359*7afc7756SAlex Wilson 360*7afc7756SAlex Wilson BMenuField* outputMenuField = new BMenuField("outputMenuField", 361*7afc7756SAlex Wilson B_TRANSLATE("Audio output:"), OutputMenu(), NULL); 362*7afc7756SAlex Wilson 363*7afc7756SAlex Wilson BLayoutBuilder::Grid<>(defaultsGridView) 364*7afc7756SAlex Wilson .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0) 365*7afc7756SAlex Wilson .AddMenuField(inputMenuField, 0, 0, B_ALIGN_HORIZONTAL_UNSET, 1, 3, 1) 366*7afc7756SAlex Wilson .AddMenuField(outputMenuField, 0, 1) 367*7afc7756SAlex Wilson .AddMenuField(_MakeChannelMenu(), 2, 1) 368*7afc7756SAlex Wilson .Add(MakeRestartMessageView(), 0, 2, 4, 1); 369*7afc7756SAlex Wilson 370*7afc7756SAlex Wilson defaultsBox->AddChild(defaultsGridView); 371*7afc7756SAlex Wilson 372*7afc7756SAlex Wilson const char* realtimeLabel = B_TRANSLATE("Enable real-time audio"); 373*7afc7756SAlex Wilson const char* realtimeInfo = B_TRANSLATE( 374*7afc7756SAlex Wilson "Enabling real-time audio allows system to record and play audio " 375*7afc7756SAlex Wilson "as fast as possible. It achieves this performance by using more" 376*7afc7756SAlex Wilson " CPU and RAM.\n\nOnly enable this feature if you need the lowest" 377*7afc7756SAlex Wilson " latency possible."); 378*7afc7756SAlex Wilson 379*7afc7756SAlex Wilson 380*7afc7756SAlex Wilson BLayoutBuilder::Grid<>(this) 381*7afc7756SAlex Wilson .SetInsets(0, 0, 0, 0) 382*7afc7756SAlex Wilson .Add(defaultsBox, 0, 0, 2, 1) 383*7afc7756SAlex Wilson .Add(MakeRealtimeBox(realtimeInfo, B_MEDIA_REALTIME_AUDIO, 384*7afc7756SAlex Wilson realtimeLabel), 0, 1, 2, 1) 385*7afc7756SAlex Wilson .Add(_MakeVolumeCheckBox(),0, 2, 1, 1) 386*7afc7756SAlex Wilson .Add(MakeRestartButton(), 1, 2, 1, 1) 387*7afc7756SAlex Wilson .SetRowWeight(1, 10); 388*7afc7756SAlex Wilson } 389*7afc7756SAlex Wilson 390*7afc7756SAlex Wilson 391*7afc7756SAlex Wilson void 392*7afc7756SAlex Wilson AudioSettingsView::SetDefaultChannel(int32 channelID) 393*7afc7756SAlex Wilson { 394*7afc7756SAlex Wilson for (int32 i = 0; i < fChannelMenu->CountItems(); i++) { 395*7afc7756SAlex Wilson ChannelMenuItem* item = _ChannelMenuItemAt(i); 396*7afc7756SAlex Wilson item->SetMarked(item->DestinationID() == channelID); 397*7afc7756SAlex Wilson } 398*7afc7756SAlex Wilson } 399*7afc7756SAlex Wilson 400*7afc7756SAlex Wilson 401*7afc7756SAlex Wilson void 402*7afc7756SAlex Wilson AudioSettingsView::AttachedToWindow() 403*7afc7756SAlex Wilson { 404*7afc7756SAlex Wilson SettingsView::AttachedToWindow(); 405*7afc7756SAlex Wilson 406*7afc7756SAlex Wilson BMessenger thisMessenger(this); 407*7afc7756SAlex Wilson fChannelMenu->SetTargetForItems(thisMessenger); 408*7afc7756SAlex Wilson fVolumeCheckBox->SetTarget(thisMessenger); 409*7afc7756SAlex Wilson } 410*7afc7756SAlex Wilson 411*7afc7756SAlex Wilson 412*7afc7756SAlex Wilson void 413*7afc7756SAlex Wilson AudioSettingsView::MessageReceived(BMessage* message) 414*7afc7756SAlex Wilson { 415*7afc7756SAlex Wilson switch (message->what) { 416*7afc7756SAlex Wilson case ML_DEFAULT_CHANNEL_CHANGED: 417*7afc7756SAlex Wilson { 418*7afc7756SAlex Wilson int32 index; 419*7afc7756SAlex Wilson if (message->FindInt32("index", &index) != B_OK) 420*7afc7756SAlex Wilson break; 421*7afc7756SAlex Wilson ChannelMenuItem* item = _ChannelMenuItemAt(index); 422*7afc7756SAlex Wilson 423*7afc7756SAlex Wilson if (item) { 424*7afc7756SAlex Wilson BMediaRoster* roster = BMediaRoster::Roster(); 425*7afc7756SAlex Wilson roster->SetAudioOutput(*item->Input()); 426*7afc7756SAlex Wilson RestartRequired(true); 427*7afc7756SAlex Wilson } else 428*7afc7756SAlex Wilson fprintf(stderr, "ChannelMenuItem not found\n"); 429*7afc7756SAlex Wilson } 430*7afc7756SAlex Wilson break; 431*7afc7756SAlex Wilson case MEDIA_SHOW_HIDE_VOLUME_CONTROL: 432*7afc7756SAlex Wilson { 433*7afc7756SAlex Wilson if (fVolumeCheckBox->Value() == B_CONTROL_ON) 434*7afc7756SAlex Wilson _ShowDeskbarVolumeControl(); 435*7afc7756SAlex Wilson else 436*7afc7756SAlex Wilson _HideDeskbarVolumeControl(); 437*7afc7756SAlex Wilson break; 438*7afc7756SAlex Wilson } 439*7afc7756SAlex Wilson 440*7afc7756SAlex Wilson default: 441*7afc7756SAlex Wilson SettingsView::MessageReceived(message); 442*7afc7756SAlex Wilson } 443*7afc7756SAlex Wilson } 444*7afc7756SAlex Wilson 445*7afc7756SAlex Wilson 446*7afc7756SAlex Wilson void 447*7afc7756SAlex Wilson AudioSettingsView::SetDefaultInput(const dormant_node_info* info) 448*7afc7756SAlex Wilson { 449*7afc7756SAlex Wilson SettingsView::SetDefaultInput(info); 450*7afc7756SAlex Wilson _MediaWindow()->UpdateInputListItem(MediaListItem::AUDIO_TYPE, info); 451*7afc7756SAlex Wilson BMediaRoster::Roster()->SetAudioInput(*info); 452*7afc7756SAlex Wilson } 453*7afc7756SAlex Wilson 454*7afc7756SAlex Wilson 455*7afc7756SAlex Wilson void 456*7afc7756SAlex Wilson AudioSettingsView::SetDefaultOutput(const dormant_node_info* info) 457*7afc7756SAlex Wilson { 458*7afc7756SAlex Wilson SettingsView::SetDefaultOutput(info); 459*7afc7756SAlex Wilson _MediaWindow()->UpdateOutputListItem(MediaListItem::AUDIO_TYPE, info); 460*7afc7756SAlex Wilson _FillChannelMenu(info); 461*7afc7756SAlex Wilson BMediaRoster::Roster()->SetAudioOutput(*info); 462*7afc7756SAlex Wilson } 463*7afc7756SAlex Wilson 464*7afc7756SAlex Wilson 465*7afc7756SAlex Wilson BMenuField* 466*7afc7756SAlex Wilson AudioSettingsView::_MakeChannelMenu() 467*7afc7756SAlex Wilson { 468*7afc7756SAlex Wilson fChannelMenu = new BPopUpMenu(B_TRANSLATE("<none>")); 469*7afc7756SAlex Wilson fChannelMenu->SetLabelFromMarked(true); 470*7afc7756SAlex Wilson BMenuField* channelMenuField = new BMenuField("channelMenuField", 471*7afc7756SAlex Wilson B_TRANSLATE("Channel:"), fChannelMenu, NULL); 472*7afc7756SAlex Wilson return channelMenuField; 473*7afc7756SAlex Wilson } 474*7afc7756SAlex Wilson 475*7afc7756SAlex Wilson 476*7afc7756SAlex Wilson BCheckBox* 477*7afc7756SAlex Wilson AudioSettingsView::_MakeVolumeCheckBox() 478*7afc7756SAlex Wilson { 479*7afc7756SAlex Wilson fVolumeCheckBox = new BCheckBox("volumeCheckBox", 480*7afc7756SAlex Wilson B_TRANSLATE("Show volume control on Deskbar"), 481*7afc7756SAlex Wilson new BMessage(MEDIA_SHOW_HIDE_VOLUME_CONTROL)); 482*7afc7756SAlex Wilson 483*7afc7756SAlex Wilson if (BDeskbar().HasItem("MediaReplicant")) 484*7afc7756SAlex Wilson fVolumeCheckBox->SetValue(B_CONTROL_ON); 485*7afc7756SAlex Wilson 486*7afc7756SAlex Wilson return fVolumeCheckBox; 487*7afc7756SAlex Wilson } 488*7afc7756SAlex Wilson 489*7afc7756SAlex Wilson 490*7afc7756SAlex Wilson void 491*7afc7756SAlex Wilson AudioSettingsView::_FillChannelMenu(const dormant_node_info* nodeInfo) 492*7afc7756SAlex Wilson { 493*7afc7756SAlex Wilson _EmptyMenu(fChannelMenu); 494*7afc7756SAlex Wilson 495*7afc7756SAlex Wilson BMediaRoster* roster = BMediaRoster::Roster(); 496*7afc7756SAlex Wilson media_node node; 497*7afc7756SAlex Wilson media_node_id node_id; 498*7afc7756SAlex Wilson 499*7afc7756SAlex Wilson status_t err = roster->GetInstancesFor(nodeInfo->addon, 500*7afc7756SAlex Wilson nodeInfo->flavor_id, &node_id); 501*7afc7756SAlex Wilson if (err != B_OK) { 502*7afc7756SAlex Wilson err = roster->InstantiateDormantNode(*nodeInfo, &node, 503*7afc7756SAlex Wilson B_FLAVOR_IS_GLOBAL); 504*7afc7756SAlex Wilson } else { 505*7afc7756SAlex Wilson err = roster->GetNodeFor(node_id, &node); 506*7afc7756SAlex Wilson } 507*7afc7756SAlex Wilson 508*7afc7756SAlex Wilson if (err == B_OK) { 509*7afc7756SAlex Wilson int32 inputCount = 4; 510*7afc7756SAlex Wilson media_input* inputs = new media_input[inputCount]; 511*7afc7756SAlex Wilson BPrivate::ArrayDeleter<media_input> inputDeleter(inputs); 512*7afc7756SAlex Wilson 513*7afc7756SAlex Wilson while (true) { 514*7afc7756SAlex Wilson int32 realInputCount = 0; 515*7afc7756SAlex Wilson err = roster->GetAllInputsFor(node, inputs, 516*7afc7756SAlex Wilson inputCount, &realInputCount); 517*7afc7756SAlex Wilson if (realInputCount > inputCount) { 518*7afc7756SAlex Wilson inputCount *= 2; 519*7afc7756SAlex Wilson inputs = new media_input[inputCount]; 520*7afc7756SAlex Wilson inputDeleter.SetTo(inputs); 521*7afc7756SAlex Wilson } else { 522*7afc7756SAlex Wilson inputCount = realInputCount; 523*7afc7756SAlex Wilson break; 524*7afc7756SAlex Wilson } 525*7afc7756SAlex Wilson } 526*7afc7756SAlex Wilson 527*7afc7756SAlex Wilson if (err == B_OK) { 528*7afc7756SAlex Wilson BMessage message(ML_DEFAULT_CHANNEL_CHANGED); 529*7afc7756SAlex Wilson 530*7afc7756SAlex Wilson for (int32 i = 0; i < inputCount; i++) { 531*7afc7756SAlex Wilson media_input* input = new media_input(); 532*7afc7756SAlex Wilson memcpy(input, &inputs[i], sizeof(*input)); 533*7afc7756SAlex Wilson ChannelMenuItem* channelItem = new ChannelMenuItem(input, 534*7afc7756SAlex Wilson new BMessage(message)); 535*7afc7756SAlex Wilson fChannelMenu->AddItem(channelItem); 536*7afc7756SAlex Wilson 537*7afc7756SAlex Wilson if (channelItem->DestinationID() == 0) 538*7afc7756SAlex Wilson channelItem->SetMarked(true); 539*7afc7756SAlex Wilson } 540*7afc7756SAlex Wilson } 541*7afc7756SAlex Wilson } 542*7afc7756SAlex Wilson 543*7afc7756SAlex Wilson if (Window()) 544*7afc7756SAlex Wilson fChannelMenu->SetTargetForItems(BMessenger(this)); 545*7afc7756SAlex Wilson } 546*7afc7756SAlex Wilson 547*7afc7756SAlex Wilson 548*7afc7756SAlex Wilson void 549*7afc7756SAlex Wilson AudioSettingsView::_ShowDeskbarVolumeControl() 550*7afc7756SAlex Wilson { 551*7afc7756SAlex Wilson BDeskbar deskbar; 552*7afc7756SAlex Wilson BEntry entry("/bin/desklink", true); 553*7afc7756SAlex Wilson int32 id; 554*7afc7756SAlex Wilson entry_ref ref; 555*7afc7756SAlex Wilson status_t status = entry.GetRef(&ref); 556*7afc7756SAlex Wilson if (status == B_OK) 557*7afc7756SAlex Wilson status = deskbar.AddItem(&ref, &id); 558*7afc7756SAlex Wilson 559*7afc7756SAlex Wilson if (status != B_OK) { 560*7afc7756SAlex Wilson fprintf(stderr, B_TRANSLATE( 561*7afc7756SAlex Wilson "Couldn't add volume control in Deskbar: %s\n"), 562*7afc7756SAlex Wilson strerror(status)); 563*7afc7756SAlex Wilson } 564*7afc7756SAlex Wilson } 565*7afc7756SAlex Wilson 566*7afc7756SAlex Wilson 567*7afc7756SAlex Wilson void 568*7afc7756SAlex Wilson AudioSettingsView::_HideDeskbarVolumeControl() 569*7afc7756SAlex Wilson { 570*7afc7756SAlex Wilson BDeskbar deskbar; 571*7afc7756SAlex Wilson status_t status = deskbar.RemoveItem("MediaReplicant"); 572*7afc7756SAlex Wilson if (status != B_OK) { 573*7afc7756SAlex Wilson fprintf(stderr, B_TRANSLATE( 574*7afc7756SAlex Wilson "Couldn't remove volume control in Deskbar: %s\n"), 575*7afc7756SAlex Wilson strerror(status)); 576*7afc7756SAlex Wilson } 577*7afc7756SAlex Wilson } 578*7afc7756SAlex Wilson 579*7afc7756SAlex Wilson 580*7afc7756SAlex Wilson ChannelMenuItem* 581*7afc7756SAlex Wilson AudioSettingsView::_ChannelMenuItemAt(int32 index) 582*7afc7756SAlex Wilson { 583*7afc7756SAlex Wilson return static_cast<ChannelMenuItem*>(fChannelMenu->ItemAt(index)); 584*7afc7756SAlex Wilson } 585*7afc7756SAlex Wilson 586*7afc7756SAlex Wilson 587*7afc7756SAlex Wilson VideoSettingsView::VideoSettingsView() 588*7afc7756SAlex Wilson { 589*7afc7756SAlex Wilson BBox* defaultsBox = new BBox("defaults"); 590*7afc7756SAlex Wilson defaultsBox->SetLabel(B_TRANSLATE("Defaults")); 591*7afc7756SAlex Wilson BGridView* defaultsGridView = new BGridView(); 592*7afc7756SAlex Wilson 593*7afc7756SAlex Wilson BMenuField* inputMenuField = new BMenuField("inputMenuField", 594*7afc7756SAlex Wilson B_TRANSLATE("Video input:"), InputMenu(), NULL); 595*7afc7756SAlex Wilson 596*7afc7756SAlex Wilson BMenuField* outputMenuField = new BMenuField("outputMenuField", 597*7afc7756SAlex Wilson B_TRANSLATE("Video output:"), OutputMenu(), NULL); 598*7afc7756SAlex Wilson 599*7afc7756SAlex Wilson BLayoutBuilder::Grid<>(defaultsGridView) 600*7afc7756SAlex Wilson .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0) 601*7afc7756SAlex Wilson .AddMenuField(inputMenuField, 0, 0) 602*7afc7756SAlex Wilson .AddMenuField(outputMenuField, 0, 1) 603*7afc7756SAlex Wilson .Add(MakeRestartMessageView(), 0, 2, 2, 1); 604*7afc7756SAlex Wilson 605*7afc7756SAlex Wilson defaultsBox->AddChild(defaultsGridView); 606*7afc7756SAlex Wilson 607*7afc7756SAlex Wilson const char* realtimeLabel = B_TRANSLATE("Enable real-time video"); 608*7afc7756SAlex Wilson const char* realtimeInfo = B_TRANSLATE( 609*7afc7756SAlex Wilson "Enabling real-time video allows system to " 610*7afc7756SAlex Wilson "perform video operations as fast and smoothly as possible. It " 611*7afc7756SAlex Wilson "achieves optimum performance by using more RAM.\n\n" 612*7afc7756SAlex Wilson "Only enable this feature if you need the lowest latency possible."); 613*7afc7756SAlex Wilson 614*7afc7756SAlex Wilson BLayoutBuilder::Grid<>(this) 615*7afc7756SAlex Wilson .SetInsets(0, 0, 0, 0) 616*7afc7756SAlex Wilson .Add(defaultsBox, 0, 0, 2, 1) 617*7afc7756SAlex Wilson .Add(MakeRealtimeBox(realtimeInfo, B_MEDIA_REALTIME_VIDEO, 618*7afc7756SAlex Wilson realtimeLabel), 0, 1, 2, 1) 619*7afc7756SAlex Wilson .Add(MakeRestartButton(), 1, 2, 1, 1) 620*7afc7756SAlex Wilson .SetRowWeight(1, 10); 621*7afc7756SAlex Wilson } 622*7afc7756SAlex Wilson 623*7afc7756SAlex Wilson 624*7afc7756SAlex Wilson void 625*7afc7756SAlex Wilson VideoSettingsView::SetDefaultInput(const dormant_node_info* info) 626*7afc7756SAlex Wilson { 627*7afc7756SAlex Wilson SettingsView::SetDefaultInput(info); 628*7afc7756SAlex Wilson _MediaWindow()->UpdateInputListItem(MediaListItem::VIDEO_TYPE, info); 629*7afc7756SAlex Wilson BMediaRoster::Roster()->SetVideoInput(*info); 630*7afc7756SAlex Wilson } 631*7afc7756SAlex Wilson 632*7afc7756SAlex Wilson 633*7afc7756SAlex Wilson void 634*7afc7756SAlex Wilson VideoSettingsView::SetDefaultOutput(const dormant_node_info* info) 635*7afc7756SAlex Wilson { 636*7afc7756SAlex Wilson SettingsView::SetDefaultOutput(info); 637*7afc7756SAlex Wilson _MediaWindow()->UpdateOutputListItem(MediaListItem::VIDEO_TYPE, info); 638*7afc7756SAlex Wilson BMediaRoster::Roster()->SetVideoOutput(*info); 639*7afc7756SAlex Wilson } 640