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