1 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 2 // 3 // Copyright (c) 2003, OpenBeOS 4 // 5 // This software is part of the OpenBeOS distribution and is covered 6 // by the OpenBeOS license. 7 // 8 // 9 // File: MediaViews.cpp 10 // Author: Sikosis, Jérôme Duval 11 // Description: Media Preferences 12 // Created : June 25, 2003 13 // 14 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 15 16 17 #include "MediaViews.h" 18 19 #include <Box.h> 20 #include <Button.h> 21 #include <Catalog.h> 22 #include <Deskbar.h> 23 #include <Entry.h> 24 #include <GroupView.h> 25 #include <Locale.h> 26 #include <MediaAddOn.h> 27 #include <MediaRoster.h> 28 #include <MenuField.h> 29 #include <PopUpMenu.h> 30 #include <SpaceLayoutItem.h> 31 #include <String.h> 32 #include <TextView.h> 33 34 #include <stdio.h> 35 36 37 #undef B_TRANSLATE_CONTEXT 38 #define B_TRANSLATE_CONTEXT "Media views" 39 40 41 SettingsView::SettingsView (bool isVideo) 42 : 43 BView("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT), 44 fIsVideo(isVideo) 45 { 46 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 47 48 BBox* defaultsBox = new BBox("defaults"); 49 defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes") 50 : B_TRANSLATE("Defaults")); 51 52 // create the default box 53 BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5); 54 defaultBoxLayout->SetInsets(10,10,10,10); 55 defaultsBox->SetLayout(defaultBoxLayout); 56 defaultBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5)); 57 58 BGroupView* inputField = new BGroupView(B_HORIZONTAL); 59 BGroupView* outputField = new BGroupView(B_HORIZONTAL); 60 defaultsBox->GetLayout()->AddView(inputField); 61 defaultsBox->GetLayout()->AddView(outputField); 62 63 float divider = StringWidth(fIsVideo ? B_TRANSLATE("Video output:") 64 : B_TRANSLATE("Audio output:")) + 5; 65 fMenu1 = new BPopUpMenu(B_TRANSLATE("<none>")); 66 fMenu1->SetLabelFromMarked(true); 67 BMenuField* menuField1 = new BMenuField("menuField1", 68 fIsVideo ? B_TRANSLATE("Video input:") 69 : B_TRANSLATE("Audio input:"), fMenu1, NULL); 70 menuField1->SetDivider(divider); 71 72 fMenu2 = new BPopUpMenu(B_TRANSLATE("<none>")); 73 fMenu2->SetLabelFromMarked(true); 74 BMenuField* menuField2 = new BMenuField("menuField2", 75 fIsVideo ? B_TRANSLATE("Video output:") 76 : B_TRANSLATE("Audio output:"), fMenu2, NULL); 77 menuField2->SetDivider(divider); 78 79 inputField->GroupLayout()->AddView(menuField1); 80 outputField->GroupLayout()->AddView(menuField2); 81 82 BMenuField* menuField3 = NULL; 83 if (!fIsVideo) { 84 fMenu3 = new BPopUpMenu(B_TRANSLATE("<none>")); 85 fMenu3->SetLabelFromMarked(true); 86 menuField3 = new BMenuField("menuField3", 87 B_TRANSLATE("Channel:"), fMenu3, NULL); 88 outputField->GroupLayout()->AddView(menuField3); 89 menuField3->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5); 90 } 91 92 rgb_color red_color = {222, 32, 33}; 93 fRestartView = new BStringView("restartStringView", 94 B_TRANSLATE("Restart the media server to apply changes.")); 95 fRestartView->SetHighColor(red_color); 96 defaultsBox->AddChild(fRestartView); 97 fRestartView->Hide(); 98 99 // create the realtime box 100 BBox* realtimeBox = new BBox("realtime"); 101 realtimeBox->SetLabel(B_TRANSLATE("Real-time")); 102 103 BMessage* message = new BMessage(ML_ENABLE_REAL_TIME); 104 message->AddBool("isVideo", fIsVideo); 105 fRealtimeCheckBox = new BCheckBox("realtimeCheckBox", 106 fIsVideo ? B_TRANSLATE("Enable real-time video") 107 : B_TRANSLATE("Enable real-time audio"), 108 message); 109 110 uint32 flags; 111 BMediaRoster::Roster()->GetRealtimeFlags(&flags); 112 if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO)) 113 fRealtimeCheckBox->SetValue(B_CONTROL_ON); 114 115 BTextView* textView = new BTextView("stringView"); 116 textView->Insert(fIsVideo ? B_TRANSLATE( 117 "Enabling real-time video allows system to " 118 "perform video operations as fast and smoothly as possible. It " 119 "achieves optimum performance by using more RAM." 120 "\n\nOnly enable this feature if you need the lowest latency possible.") 121 : B_TRANSLATE( 122 "Enabling real-time audio allows system to record and play audio " 123 "as fast as possible. It achieves this performance by using more" 124 " CPU and RAM.\n\nOnly enable this feature if you need the lowest" 125 " latency possible.")); 126 127 textView->MakeEditable(false); 128 textView->MakeSelectable(false); 129 textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 130 131 BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5); 132 realtimeBoxLayout->SetInsets(10,10,10,10); 133 realtimeBox->SetLayout(realtimeBoxLayout); 134 135 realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5)); 136 realtimeBoxLayout->AddView(fRealtimeCheckBox); 137 realtimeBoxLayout->AddView(textView); 138 139 // create the bottom line: volumen in deskbar checkbox and restart button 140 BGroupView* bottomView = new BGroupView(B_HORIZONTAL); 141 BButton* restartButton = new BButton("restartButton", 142 B_TRANSLATE("Restart media services"), 143 new BMessage(ML_RESTART_MEDIA_SERVER)); 144 145 if (!fIsVideo) { 146 fVolumeCheckBox = new BCheckBox("volumeCheckBox", 147 B_TRANSLATE("Show volume control on Deskbar"), 148 new BMessage(ML_SHOW_VOLUME_CONTROL)); 149 bottomView->GroupLayout()->AddView(fVolumeCheckBox); 150 if (BDeskbar().HasItem("MediaReplicant")) 151 fVolumeCheckBox->SetValue(B_CONTROL_ON); 152 } 153 else{ 154 bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue()); 155 } 156 bottomView->GroupLayout()->AddView(restartButton); 157 158 // compose all stuff 159 BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5); 160 SetLayout(rootlayout); 161 162 rootlayout->AddView(defaultsBox); 163 rootlayout->AddView(realtimeBox); 164 rootlayout->AddView(bottomView); 165 } 166 167 168 void 169 SettingsView::AddNodes(NodeList& list, bool isInput) 170 { 171 BMenu* menu = isInput ? fMenu1 : fMenu2; 172 void* item; 173 while ((item = menu->RemoveItem((int32)0)) != NULL) 174 delete static_cast<dormant_node_info*>(item); 175 176 BMessage message(ML_DEFAULT_CHANGE); 177 message.AddBool("isVideo", fIsVideo); 178 message.AddBool("isInput", isInput); 179 180 for (int32 i = 0; i < list.CountItems(); i++) { 181 dormant_node_info* info = list.ItemAt(i); 182 menu->AddItem(new SettingsItem(info, new BMessage(message))); 183 } 184 } 185 186 187 void 188 SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID) 189 { 190 BMenu* menu = isInput ? fMenu1 : fMenu2; 191 192 for (int32 i = 0; i < menu->CountItems(); i++) { 193 SettingsItem* item = static_cast<SettingsItem*>(menu->ItemAt(i)); 194 if (item->fInfo && item->fInfo->addon == info.addon 195 && item->fInfo->flavor_id == info.flavor_id) { 196 item->SetMarked(true); 197 break; 198 } 199 } 200 201 if (!fIsVideo && !isInput && outputID >= 0) { 202 BMenuItem* item; 203 while ((item = fMenu3->RemoveItem((int32)0)) != NULL) 204 delete item; 205 206 BMediaRoster* roster = BMediaRoster::Roster(); 207 media_node node; 208 media_node_id node_id; 209 status_t err; 210 if (roster->GetInstancesFor(info.addon, info.flavor_id, 211 &node_id) != B_OK) { 212 err = roster->InstantiateDormantNode(info, &node, 213 B_FLAVOR_IS_GLOBAL); 214 } else { 215 err = roster->GetNodeFor(node_id, &node); 216 } 217 218 if (err == B_OK) { 219 media_input inputs[16]; 220 int32 inputCount = 16; 221 if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) { 222 BMessage message(ML_DEFAULTOUTPUT_CHANGE); 223 224 for (int32 i = 0; i < inputCount; i++) { 225 media_input* input = new media_input(); 226 memcpy(input, &inputs[i], sizeof(*input)); 227 item = new Settings2Item(&info, input, 228 new BMessage(message)); 229 fMenu3->AddItem(item); 230 if (inputs[i].destination.id == outputID) 231 item->SetMarked(true); 232 } 233 } 234 } 235 } 236 } 237 238 239 SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message, 240 char shortcut, uint32 modifiers) 241 : 242 BMenuItem(info->name, message, shortcut, modifiers), 243 fInfo(info) 244 { 245 246 } 247 248 249 status_t 250 SettingsItem::Invoke(BMessage* message) 251 { 252 if (IsMarked()) 253 return B_OK; 254 return BMenuItem::Invoke(message); 255 } 256 257 258 Settings2Item::Settings2Item(dormant_node_info* info, media_input* input, 259 BMessage* message, char shortcut, uint32 modifiers) 260 : 261 BMenuItem(input->name, message, shortcut, modifiers), 262 fInfo(info), 263 fInput(input) 264 { 265 } 266 267 268 Settings2Item::~Settings2Item() 269 { 270 delete fInput; 271 } 272 273 274 status_t 275 Settings2Item::Invoke(BMessage* message) 276 { 277 if (IsMarked()) 278 return B_OK; 279 return BMenuItem::Invoke(message); 280 } 281 282