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 BarView::BarView() 42 : 43 BView("barView", B_WILL_DRAW ), 44 fDisplay(true) 45 { 46 } 47 48 49 void 50 BarView::Draw(BRect updateRect) 51 { 52 BRect r = Bounds(); 53 54 if (fDisplay) { 55 // Display the 3D Look Divider Bar 56 SetHighColor(140,140,140,0); 57 StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top)); 58 SetHighColor(255,255,255,0); 59 StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom)); 60 } else { 61 SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 62 StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top)); 63 StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom)); 64 } 65 } 66 67 68 SettingsView::SettingsView (bool isVideo) 69 : 70 BView("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT), 71 fIsVideo(isVideo) 72 { 73 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 74 75 BBox* defaultsBox = new BBox("defaults"); 76 defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes") 77 : B_TRANSLATE("Defaults")); 78 79 // create the default box 80 BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5); 81 defaultBoxLayout->SetInsets(10,10,10,10); 82 defaultsBox->SetLayout(defaultBoxLayout); 83 defaultBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5)); 84 85 BGroupView* inputField = new BGroupView(B_HORIZONTAL); 86 BGroupView* outputField = new BGroupView(B_HORIZONTAL); 87 defaultsBox->GetLayout()->AddView(inputField); 88 defaultsBox->GetLayout()->AddView(outputField); 89 90 float divider = StringWidth(fIsVideo ? B_TRANSLATE("Video output:") 91 : B_TRANSLATE("Audio output:")) + 5; 92 fMenu1 = new BPopUpMenu(B_TRANSLATE("<none>")); 93 fMenu1->SetLabelFromMarked(true); 94 BMenuField* menuField1 = new BMenuField("menuField1", 95 fIsVideo ? B_TRANSLATE("Video input:") 96 : B_TRANSLATE("Audio input:"), fMenu1, NULL); 97 menuField1->SetDivider(divider); 98 99 fMenu2 = new BPopUpMenu(B_TRANSLATE("<none>")); 100 fMenu2->SetLabelFromMarked(true); 101 BMenuField* menuField2 = new BMenuField("menuField2", 102 fIsVideo ? B_TRANSLATE("Video output:") 103 : B_TRANSLATE("Audio output:"), fMenu2, NULL); 104 menuField2->SetDivider(divider); 105 106 inputField->GroupLayout()->AddView(menuField1); 107 outputField->GroupLayout()->AddView(menuField2); 108 109 BMenuField* menuField3 = NULL; 110 if (!fIsVideo) { 111 fMenu3 = new BPopUpMenu(B_TRANSLATE("<none>")); 112 fMenu3->SetLabelFromMarked(true); 113 menuField3 = new BMenuField("menuField3", 114 B_TRANSLATE("Channel:"), fMenu3, NULL); 115 outputField->GroupLayout()->AddView(menuField3); 116 menuField3->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5); 117 } 118 119 rgb_color red_color = {222, 32, 33}; 120 fRestartView = new BStringView("restartStringView", 121 B_TRANSLATE("Restart the media server to apply changes.")); 122 fRestartView->SetHighColor(red_color); 123 defaultsBox->AddChild(fRestartView); 124 fRestartView->Hide(); 125 126 // create the realtime box 127 BBox* realtimeBox = new BBox("realtime"); 128 realtimeBox->SetLabel(B_TRANSLATE("Real-time")); 129 130 BMessage* message = new BMessage(ML_ENABLE_REAL_TIME); 131 message->AddBool("isVideo", fIsVideo); 132 fRealtimeCheckBox = new BCheckBox("realtimeCheckBox", 133 fIsVideo ? B_TRANSLATE("Enable real-time video") 134 : B_TRANSLATE("Enable real-time audio"), 135 message); 136 137 uint32 flags; 138 BMediaRoster::Roster()->GetRealtimeFlags(&flags); 139 if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO)) 140 fRealtimeCheckBox->SetValue(B_CONTROL_ON); 141 142 BTextView* textView = new BTextView("stringView"); 143 textView->Insert(fIsVideo ? B_TRANSLATE( 144 "Enabling real-time video allows system to " 145 "perform video operations as fast and smoothly as possible. It " 146 "achieves optimum performance by using more RAM." 147 "\n\nOnly enable this feature if you need the lowest latency possible.") 148 : B_TRANSLATE( 149 "Enabling real-time audio allows system to record and play audio " 150 "as fast as possible. It achieves this performance by using more" 151 " CPU and RAM.\n\nOnly enable this feature if you need the lowest" 152 " latency possible.")); 153 154 textView->MakeEditable(false); 155 textView->MakeSelectable(false); 156 textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 157 158 BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5); 159 realtimeBoxLayout->SetInsets(10,10,10,10); 160 realtimeBox->SetLayout(realtimeBoxLayout); 161 162 realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5)); 163 realtimeBoxLayout->AddView(fRealtimeCheckBox); 164 realtimeBoxLayout->AddView(textView); 165 166 // create the bottom line: volumen in deskbar checkbox and restart button 167 BGroupView* bottomView = new BGroupView(B_HORIZONTAL); 168 BButton* restartButton = new BButton("restartButton", 169 B_TRANSLATE("Restart media services"), 170 new BMessage(ML_RESTART_MEDIA_SERVER)); 171 172 if (!fIsVideo) { 173 fVolumeCheckBox = new BCheckBox("volumeCheckBox", 174 B_TRANSLATE("Show volume control on Deskbar"), 175 new BMessage(ML_SHOW_VOLUME_CONTROL)); 176 bottomView->GroupLayout()->AddView(fVolumeCheckBox); 177 if (BDeskbar().HasItem("MediaReplicant")) 178 fVolumeCheckBox->SetValue(B_CONTROL_ON); 179 } 180 else{ 181 bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue()); 182 } 183 bottomView->GroupLayout()->AddView(restartButton); 184 185 // compose all stuff 186 BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5); 187 SetLayout(rootlayout); 188 189 rootlayout->AddView(defaultsBox); 190 rootlayout->AddView(realtimeBox); 191 rootlayout->AddView(bottomView); 192 } 193 194 195 void 196 SettingsView::AddNodes(BList& list, bool isInput) 197 { 198 BMenu* menu = isInput ? fMenu1 : fMenu2; 199 void* item; 200 while ((item = menu->RemoveItem((int32)0)) != NULL) 201 delete static_cast<dormant_node_info*>(item); 202 203 BMessage message(ML_DEFAULT_CHANGE); 204 message.AddBool("isVideo", fIsVideo); 205 message.AddBool("isInput", isInput); 206 207 for (int32 i = 0; i < list.CountItems(); i++) { 208 dormant_node_info* info 209 = static_cast<dormant_node_info*>(list.ItemAt(i)); 210 menu->AddItem(new SettingsItem(info, new BMessage(message))); 211 } 212 } 213 214 215 void 216 SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID) 217 { 218 BMenu* menu = isInput ? fMenu1 : fMenu2; 219 220 for (int32 i = 0; i < menu->CountItems(); i++) { 221 SettingsItem* item = static_cast<SettingsItem*>(menu->ItemAt(i)); 222 if (item->fInfo && item->fInfo->addon == info.addon 223 && item->fInfo->flavor_id == info.flavor_id) { 224 item->SetMarked(true); 225 break; 226 } 227 } 228 229 if (!fIsVideo && !isInput && outputID >= 0) { 230 BMenuItem* item; 231 while ((item = fMenu3->RemoveItem((int32)0)) != NULL) 232 delete item; 233 234 BMediaRoster* roster = BMediaRoster::Roster(); 235 media_node node; 236 media_node_id node_id; 237 status_t err; 238 if (roster->GetInstancesFor(info.addon, info.flavor_id, 239 &node_id) != B_OK) { 240 err = roster->InstantiateDormantNode(info, &node, 241 B_FLAVOR_IS_GLOBAL); 242 } else { 243 err = roster->GetNodeFor(node_id, &node); 244 } 245 246 if (err == B_OK) { 247 media_input inputs[16]; 248 int32 inputCount = 16; 249 if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) { 250 BMessage message(ML_DEFAULTOUTPUT_CHANGE); 251 252 for (int32 i = 0; i < inputCount; i++) { 253 media_input* input = new media_input(); 254 memcpy(input, &inputs[i], sizeof(*input)); 255 item = new Settings2Item(&info, input, 256 new BMessage(message)); 257 fMenu3->AddItem(item); 258 if (inputs[i].destination.id == outputID) 259 item->SetMarked(true); 260 } 261 } 262 } 263 } 264 } 265 266 267 SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message, 268 char shortcut, uint32 modifiers) 269 : 270 BMenuItem(info->name, message, shortcut, modifiers), 271 fInfo(info) 272 { 273 274 } 275 276 277 status_t 278 SettingsItem::Invoke(BMessage* message) 279 { 280 if (IsMarked()) 281 return B_OK; 282 return BMenuItem::Invoke(message); 283 } 284 285 286 Settings2Item::Settings2Item(dormant_node_info* info, media_input* input, 287 BMessage* message, char shortcut, uint32 modifiers) 288 : 289 BMenuItem(input->name, message, shortcut, modifiers), 290 fInfo(info), 291 fInput(input) 292 { 293 } 294 295 296 Settings2Item::~Settings2Item() 297 { 298 delete fInput; 299 } 300 301 302 status_t 303 Settings2Item::Invoke(BMessage* message) 304 { 305 if (IsMarked()) 306 return B_OK; 307 return BMenuItem::Invoke(message); 308 } 309 310