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