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 17a10cf76eSAxel Dörfler // Includes -------------------------------------------------------------------------------------------------- // 18a10cf76eSAxel Dörfler #include <Box.h> 19a10cf76eSAxel Dörfler #include <Button.h> 20a10cf76eSAxel Dörfler #include <MenuField.h> 21a10cf76eSAxel Dörfler #include <PopUpMenu.h> 22a10cf76eSAxel Dörfler #include <MediaRoster.h> 23a10cf76eSAxel Dörfler #include <Deskbar.h> 24a10cf76eSAxel Dörfler #include <Entry.h> 25a10cf76eSAxel Dörfler #include <stdio.h> 26a10cf76eSAxel Dörfler #include <MediaAddOn.h> 27a10cf76eSAxel Dörfler #include <String.h> 28b4a12470SJérôme Duval #include <TextView.h> 292af5f895SStephan Aßmus #include <GroupView.h> 302af5f895SStephan Aßmus #include <SpaceLayoutItem.h> 312af5f895SStephan Aßmus 32a10cf76eSAxel Dörfler #include "MediaViews.h" 33a10cf76eSAxel Dörfler 34a10cf76eSAxel Dörfler BarView::BarView(BRect frame) 35a10cf76eSAxel Dörfler : BView (frame, "barView", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW ), 36b4a12470SJérôme Duval fDisplay(true) 37a10cf76eSAxel Dörfler { 38a10cf76eSAxel Dörfler } 39a10cf76eSAxel Dörfler 40a10cf76eSAxel Dörfler void 41a10cf76eSAxel Dörfler BarView::Draw(BRect updateRect) 42a10cf76eSAxel Dörfler { 43a10cf76eSAxel Dörfler BRect r = Bounds(); 44a10cf76eSAxel Dörfler 45b4a12470SJérôme Duval if (fDisplay) { 46a10cf76eSAxel Dörfler // Display the 3D Look Divider Bar 47a10cf76eSAxel Dörfler SetHighColor(140,140,140,0); 48a10cf76eSAxel Dörfler StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top)); 49a10cf76eSAxel Dörfler SetHighColor(255,255,255,0); 50a10cf76eSAxel Dörfler StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom)); 51a10cf76eSAxel Dörfler } else { 52a10cf76eSAxel Dörfler SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 53a10cf76eSAxel Dörfler StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top)); 54a10cf76eSAxel Dörfler StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom)); 55a10cf76eSAxel Dörfler } 56a10cf76eSAxel Dörfler } 57a10cf76eSAxel Dörfler 58a10cf76eSAxel Dörfler 59a10cf76eSAxel Dörfler SettingsView::SettingsView (BRect frame, bool isVideo) 60a10cf76eSAxel Dörfler : BView (frame, "SettingsView", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW ), 61b4a12470SJérôme Duval fIsVideo(isVideo) 62a10cf76eSAxel Dörfler { 63a10cf76eSAxel Dörfler SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 642af5f895SStephan Aßmus 65a10cf76eSAxel Dörfler BRect rect(frame); 66a10cf76eSAxel Dörfler rect.left += 10; 67a10cf76eSAxel Dörfler rect.top += 12; 68a10cf76eSAxel Dörfler rect.right -=21; 69a10cf76eSAxel Dörfler rect.bottom = rect.top + 104; 70a10cf76eSAxel Dörfler BBox *defaultsBox = new BBox(rect, "defaults"); 71b4a12470SJérôme Duval defaultsBox->SetLabel(fIsVideo ? "Default Nodes" : "Defaults"); 722af5f895SStephan Aßmus 732af5f895SStephan Aßmus // create the default box 742af5f895SStephan Aßmus BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5); 752af5f895SStephan Aßmus float inset = defaultsBox->Frame().left - defaultsBox->InnerFrame().left; 762af5f895SStephan Aßmus defaultBoxLayout->SetInsets(inset, defaultsBox->TopBorderOffset() * 2, inset, inset); 772af5f895SStephan Aßmus defaultsBox->SetLayout(defaultBoxLayout); 782af5f895SStephan Aßmus defaultBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5)); 792af5f895SStephan Aßmus 802af5f895SStephan Aßmus BGroupView* inputField = new BGroupView(B_HORIZONTAL); 812af5f895SStephan Aßmus BGroupView* outputField = new BGroupView(B_HORIZONTAL); 822af5f895SStephan Aßmus defaultsBox->GetLayout()->AddView(inputField); 832af5f895SStephan Aßmus defaultsBox->GetLayout()->AddView(outputField); 84a10cf76eSAxel Dörfler 85a10cf76eSAxel Dörfler BRect defaultRect(20, 22, 250, 40); 86b4a12470SJérôme Duval float divider = StringWidth(fIsVideo ? "Video Output:" : "Audio Output:") + 5; 87b4a12470SJérôme Duval fMenu1 = new BPopUpMenu("<none>"); 88b4a12470SJérôme Duval fMenu1->SetLabelFromMarked(true); 89a10cf76eSAxel Dörfler BMenuField *menuField1 = new BMenuField(defaultRect, "menuField1", 90b4a12470SJérôme Duval fIsVideo ? "Video Input:" : "Audio Input:", fMenu1); 91aaa9b739SJérôme Duval menuField1->SetDivider(divider); 92a10cf76eSAxel Dörfler 93a10cf76eSAxel Dörfler defaultRect.OffsetBy(0, 26); 94b4a12470SJérôme Duval fMenu2 = new BPopUpMenu("<none>"); 95b4a12470SJérôme Duval fMenu2->SetLabelFromMarked(true); 96a10cf76eSAxel Dörfler BMenuField *menuField2 = new BMenuField(defaultRect, "menuField2", 97b4a12470SJérôme Duval fIsVideo ? "Video Output:" : "Audio Output:", fMenu2); 98aaa9b739SJérôme Duval menuField2->SetDivider(divider); 99a10cf76eSAxel Dörfler 1002af5f895SStephan Aßmus inputField->GroupLayout()->AddView(menuField1); 1012af5f895SStephan Aßmus outputField->GroupLayout()->AddView(menuField2); 1022af5f895SStephan Aßmus 1032af5f895SStephan Aßmus BMenuField *menuField3 = NULL; 104b4a12470SJérôme Duval if (!fIsVideo) { 105a10cf76eSAxel Dörfler defaultRect.OffsetBy(186, 0); 106b4a12470SJérôme Duval defaultRect.right -= 30; 107b4a12470SJérôme Duval fMenu3 = new BPopUpMenu("<none>"); 108b4a12470SJérôme Duval fMenu3->SetLabelFromMarked(true); 1092af5f895SStephan Aßmus menuField3 = new BMenuField(defaultRect, "menuField3", 110b4a12470SJérôme Duval "Channel:", fMenu3); 1112af5f895SStephan Aßmus outputField->GroupLayout()->AddView(menuField3); 112b4a12470SJérôme Duval menuField3->SetDivider(StringWidth("Channel:")+5); 113b4a12470SJérôme Duval defaultRect.right += 30; 114a10cf76eSAxel Dörfler defaultRect.OffsetBy(-186, 0); 115a10cf76eSAxel Dörfler } 116a10cf76eSAxel Dörfler 117a10cf76eSAxel Dörfler defaultRect.OffsetBy(0, 32); 118b4a12470SJérôme Duval defaultRect.right += 100; 119a10cf76eSAxel Dörfler rgb_color red_color = {222, 32, 33}; 120b4a12470SJérôme Duval fRestartView = new BStringView(defaultRect, "restartStringView", "Restart the Media Server to apply changes.", 121b4a12470SJérôme Duval B_FOLLOW_ALL, B_WILL_DRAW); 122b4a12470SJérôme Duval fRestartView->SetHighColor(red_color); 123b4a12470SJérôme Duval defaultsBox->AddChild(fRestartView); 124b4a12470SJérôme Duval fRestartView->Hide(); 125a10cf76eSAxel Dörfler 1262af5f895SStephan Aßmus // create the realtime box 127a10cf76eSAxel Dörfler rect.top = rect.bottom + 10; 128a10cf76eSAxel Dörfler rect.bottom = rect.top + 162; 129a10cf76eSAxel Dörfler BBox *realtimeBox = new BBox(rect, "realtime"); 130a10cf76eSAxel Dörfler realtimeBox->SetLabel("Real-Time"); 131a10cf76eSAxel Dörfler 132a10cf76eSAxel Dörfler BMessage *message = new BMessage(ML_ENABLE_REAL_TIME); 133b4a12470SJérôme Duval message->AddBool("isVideo", fIsVideo); 1342af5f895SStephan Aßmus BRect rect2(22,20, frame.Width() - 22, 40); 135b4a12470SJérôme Duval fRealtimeCheckBox = new BCheckBox(rect2, "realtimeCheckBox", 136b4a12470SJérôme Duval fIsVideo ? "Enable Real-Time Video" : "Enable Real-Time Audio", message); 137a10cf76eSAxel Dörfler 138a10cf76eSAxel Dörfler uint32 flags; 139a10cf76eSAxel Dörfler BMediaRoster::Roster()->GetRealtimeFlags(&flags); 140b4a12470SJérôme Duval if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO)) 141b4a12470SJérôme Duval fRealtimeCheckBox->SetValue(B_CONTROL_ON); 142a10cf76eSAxel Dörfler 143a10cf76eSAxel Dörfler rect2.top += 26; 1445ffd43dcSJérôme Duval rect2.bottom = rect.Height() - 5; 145a10cf76eSAxel Dörfler BRect textRect(3, 3, rect2.Width() - 3, rect2.Height() - 3); 146b4a12470SJérôme Duval BTextView *textView = new BTextView(rect2, "stringView", textRect, B_FOLLOW_ALL, B_WILL_DRAW); 147*774e87aaSPhilippe Houdoin textView->Insert(fIsVideo ? "Enabling Real-Time Video allows system to perform video operations as fast and smoothly as possible. It achieves optimum performance by using more RAM." 148b4a12470SJérôme Duval "\n\nOnly enable this feature if you need the lowest latency possible." 149*774e87aaSPhilippe Houdoin : "Enabling Real-time Audio allows system to record and play audio as fast as possible. It achieves this performance by using more CPU and RAM." 150b4a12470SJérôme Duval "\n\nOnly enable this feature if you need the lowest latency possible."); 151b4a12470SJérôme Duval textView->MakeEditable(false); 152b4a12470SJérôme Duval textView->MakeSelectable(false); 153a10cf76eSAxel Dörfler textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 154a10cf76eSAxel Dörfler 1552af5f895SStephan Aßmus BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5); 1562af5f895SStephan Aßmus inset = realtimeBox->Frame().left - realtimeBox->InnerFrame().left; 1572af5f895SStephan Aßmus realtimeBoxLayout->SetInsets(inset, defaultsBox->TopBorderOffset() * 2, inset, inset); 1582af5f895SStephan Aßmus realtimeBox->SetLayout(realtimeBoxLayout); 1592af5f895SStephan Aßmus 1602af5f895SStephan Aßmus realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5)); 1612af5f895SStephan Aßmus realtimeBoxLayout->AddView(fRealtimeCheckBox); 1622af5f895SStephan Aßmus realtimeBoxLayout->AddView(textView); 1632af5f895SStephan Aßmus 1642af5f895SStephan Aßmus // create the bottom line: volumen in deskbar checkbox and restart button 1652af5f895SStephan Aßmus BGroupView* bottomView = new BGroupView(B_HORIZONTAL); 166a10cf76eSAxel Dörfler rect.top = rect.bottom + 11; 167a10cf76eSAxel Dörfler rect.bottom = rect.top + 20; 168aaa9b739SJérôme Duval rect.left = rect.right - StringWidth("Restart Media Services") - 20; 169a10cf76eSAxel Dörfler BButton *restartButton = new BButton(rect, "restartButton", 170a10cf76eSAxel Dörfler "Restart Media Services", new BMessage(ML_RESTART_MEDIA_SERVER)); 171a10cf76eSAxel Dörfler 172b4a12470SJérôme Duval if (!fIsVideo) { 173b4a12470SJérôme Duval rect.right = rect.left - 10; 174a10cf76eSAxel Dörfler rect.top += 4; 175a10cf76eSAxel Dörfler rect.left = frame.left + 33; 176b4a12470SJérôme Duval if (StringWidth("Show Volume Control on Deskbar") > rect.Width() - 30) 177b4a12470SJérôme Duval rect.left -= 10; 178b4a12470SJérôme Duval fVolumeCheckBox = new BCheckBox(rect, "volumeCheckBox", 179a10cf76eSAxel Dörfler "Show Volume Control on Deskbar", new BMessage(ML_SHOW_VOLUME_CONTROL)); 1802af5f895SStephan Aßmus bottomView->GroupLayout()->AddView(fVolumeCheckBox); 181a10cf76eSAxel Dörfler if (BDeskbar().HasItem("MediaReplicant")) 182b4a12470SJérôme Duval fVolumeCheckBox->SetValue(B_CONTROL_ON); 183a10cf76eSAxel Dörfler } 1842af5f895SStephan Aßmus else{ 1852af5f895SStephan Aßmus bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue()); 1862af5f895SStephan Aßmus } 1872af5f895SStephan Aßmus bottomView->GroupLayout()->AddView(restartButton); 1882af5f895SStephan Aßmus 1892af5f895SStephan Aßmus // compose all stuff 1902af5f895SStephan Aßmus BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5); 1912af5f895SStephan Aßmus SetLayout(rootlayout); 1922af5f895SStephan Aßmus 1932af5f895SStephan Aßmus rootlayout->AddView(defaultsBox); 1942af5f895SStephan Aßmus rootlayout->AddView(realtimeBox); 1952af5f895SStephan Aßmus rootlayout->AddView(bottomView); 196a10cf76eSAxel Dörfler } 197a10cf76eSAxel Dörfler 198a10cf76eSAxel Dörfler void 199a10cf76eSAxel Dörfler SettingsView::AddNodes(BList &list, bool isInput) 200a10cf76eSAxel Dörfler { 201b4a12470SJérôme Duval BMenu *menu = isInput ? fMenu1 : fMenu2; 202a10cf76eSAxel Dörfler void *item; 203a10cf76eSAxel Dörfler while ((item = menu->RemoveItem((int32)0)) != NULL) 204a10cf76eSAxel Dörfler delete static_cast<dormant_node_info *>(item); 205a10cf76eSAxel Dörfler 206a10cf76eSAxel Dörfler BMessage message(ML_DEFAULT_CHANGE); 207b4a12470SJérôme Duval message.AddBool("isVideo", fIsVideo); 208a10cf76eSAxel Dörfler message.AddBool("isInput", isInput); 209a10cf76eSAxel Dörfler 210a10cf76eSAxel Dörfler for (int32 i = 0; i < list.CountItems(); i++) { 211a10cf76eSAxel Dörfler dormant_node_info *info = static_cast<dormant_node_info *>(list.ItemAt(i)); 212a10cf76eSAxel Dörfler menu->AddItem(new SettingsItem(info, new BMessage(message))); 213a10cf76eSAxel Dörfler } 214a10cf76eSAxel Dörfler } 215a10cf76eSAxel Dörfler 216a10cf76eSAxel Dörfler void 217a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID) 218a10cf76eSAxel Dörfler { 219b4a12470SJérôme Duval BMenu *menu = isInput ? fMenu1 : fMenu2; 220a10cf76eSAxel Dörfler 221a10cf76eSAxel Dörfler for (int32 i = 0; i < menu->CountItems(); i++) { 222a10cf76eSAxel Dörfler SettingsItem *item = static_cast<SettingsItem *>(menu->ItemAt(i)); 223b4a12470SJérôme Duval if (item->fInfo && item->fInfo->addon == info.addon && item->fInfo->flavor_id == info.flavor_id) { 224a10cf76eSAxel Dörfler item->SetMarked(true); 225a10cf76eSAxel Dörfler break; 226a10cf76eSAxel Dörfler } 227a10cf76eSAxel Dörfler } 228a10cf76eSAxel Dörfler 229b4a12470SJérôme Duval if (!fIsVideo&&!isInput&&outputID>-1) { 230a10cf76eSAxel Dörfler BMenuItem *item; 231b4a12470SJérôme Duval while ((item = fMenu3->RemoveItem((int32)0)) != NULL) 232a10cf76eSAxel Dörfler delete item; 233a10cf76eSAxel Dörfler BMediaRoster *roster = BMediaRoster::Roster(); 234a10cf76eSAxel Dörfler media_node node; 235a10cf76eSAxel Dörfler media_node_id node_id; 236a10cf76eSAxel Dörfler status_t err; 237a10cf76eSAxel Dörfler if (roster->GetInstancesFor(info.addon, info.flavor_id, &node_id)!=B_OK) 238a10cf76eSAxel Dörfler err = roster->InstantiateDormantNode(info, &node, B_FLAVOR_IS_GLOBAL); 239a10cf76eSAxel Dörfler else 240a10cf76eSAxel Dörfler err = roster->GetNodeFor(node_id, &node); 241a10cf76eSAxel Dörfler 242a10cf76eSAxel Dörfler if (err == B_OK) { 243a10cf76eSAxel Dörfler media_input inputs[16]; 244a10cf76eSAxel Dörfler int32 inputCount = 16; 245a10cf76eSAxel Dörfler if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) { 246a10cf76eSAxel Dörfler BMessage message(ML_DEFAULTOUTPUT_CHANGE); 247a10cf76eSAxel Dörfler 248a10cf76eSAxel Dörfler for (int32 i = 0; i < inputCount; i++) { 249a10cf76eSAxel Dörfler media_input *input = new media_input(); 250a10cf76eSAxel Dörfler memcpy(input, &inputs[i], sizeof(*input)); 251b4a12470SJérôme Duval fMenu3->AddItem(item = new Settings2Item(&info, input, new BMessage(message))); 252a10cf76eSAxel Dörfler if (inputs[i].destination.id == outputID) 253a10cf76eSAxel Dörfler item->SetMarked(true); 254a10cf76eSAxel Dörfler } 255a10cf76eSAxel Dörfler } 256a10cf76eSAxel Dörfler } 257a10cf76eSAxel Dörfler } 258a10cf76eSAxel Dörfler } 259a10cf76eSAxel Dörfler 260a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info *info, BMessage *message, 261a10cf76eSAxel Dörfler char shortcut, uint32 modifiers) 262a10cf76eSAxel Dörfler : BMenuItem(info->name, message, shortcut, modifiers), 263b4a12470SJérôme Duval fInfo(info) 264a10cf76eSAxel Dörfler { 265a10cf76eSAxel Dörfler 266a10cf76eSAxel Dörfler } 267a10cf76eSAxel Dörfler 2686df0b2d5SJérôme Duval 2696df0b2d5SJérôme Duval status_t 2706df0b2d5SJérôme Duval SettingsItem::Invoke(BMessage *message) 2716df0b2d5SJérôme Duval { 2726df0b2d5SJérôme Duval if (IsMarked()) 2736df0b2d5SJérôme Duval return B_OK; 2746df0b2d5SJérôme Duval return BMenuItem::Invoke(message); 2756df0b2d5SJérôme Duval } 2766df0b2d5SJérôme Duval 2776df0b2d5SJérôme Duval 278a10cf76eSAxel Dörfler Settings2Item::Settings2Item(dormant_node_info *info, media_input *input, BMessage *message, 279a10cf76eSAxel Dörfler char shortcut, uint32 modifiers) 280a10cf76eSAxel Dörfler : BMenuItem(input->name, message, shortcut, modifiers), 281b4a12470SJérôme Duval fInfo(info), 282b4a12470SJérôme Duval fInput(input) 283a10cf76eSAxel Dörfler { 284a10cf76eSAxel Dörfler 285a10cf76eSAxel Dörfler } 286a10cf76eSAxel Dörfler 2876df0b2d5SJérôme Duval 288a10cf76eSAxel Dörfler Settings2Item::~Settings2Item() 289a10cf76eSAxel Dörfler { 290b4a12470SJérôme Duval delete fInput; 291a10cf76eSAxel Dörfler } 292a10cf76eSAxel Dörfler 2936df0b2d5SJérôme Duval 2946df0b2d5SJérôme Duval status_t 2956df0b2d5SJérôme Duval Settings2Item::Invoke(BMessage *message) 2966df0b2d5SJérôme Duval { 2976df0b2d5SJérôme Duval if (IsMarked()) 2986df0b2d5SJérôme Duval return B_OK; 2996df0b2d5SJérôme Duval return BMenuItem::Invoke(message); 3006df0b2d5SJérôme Duval } 3016df0b2d5SJérôme Duval 302