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