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