xref: /haiku/src/preferences/media/MediaViews.cpp (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
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