xref: /haiku/src/preferences/media/MediaViews.cpp (revision 774e87aac9be280608686bfd91f0ded6a15633ad)
1a10cf76eSAxel Dörfler // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2a10cf76eSAxel Dörfler //
3a10cf76eSAxel Dörfler //	Copyright (c) 2003, OpenBeOS
4a10cf76eSAxel Dörfler //
5a10cf76eSAxel Dörfler //  This software is part of the OpenBeOS distribution and is covered
6a10cf76eSAxel Dörfler //  by the OpenBeOS license.
7a10cf76eSAxel Dörfler //
8a10cf76eSAxel Dörfler //
9a10cf76eSAxel Dörfler //  File:        MediaViews.cpp
10a10cf76eSAxel Dörfler //  Author:      Sikosis, Jérôme Duval
11a10cf76eSAxel Dörfler //  Description: Media Preferences
12a10cf76eSAxel Dörfler //  Created :    June 25, 2003
13a10cf76eSAxel Dörfler //
14a10cf76eSAxel Dörfler // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
15a10cf76eSAxel Dörfler 
16a10cf76eSAxel Dörfler 
17a10cf76eSAxel Dörfler // Includes -------------------------------------------------------------------------------------------------- //
18a10cf76eSAxel Dörfler #include <Box.h>
19a10cf76eSAxel Dörfler #include <Button.h>
20a10cf76eSAxel Dörfler #include <MenuField.h>
21a10cf76eSAxel Dörfler #include <PopUpMenu.h>
22a10cf76eSAxel Dörfler #include <MediaRoster.h>
23a10cf76eSAxel Dörfler #include <Deskbar.h>
24a10cf76eSAxel Dörfler #include <Entry.h>
25a10cf76eSAxel Dörfler #include <stdio.h>
26a10cf76eSAxel Dörfler #include <MediaAddOn.h>
27a10cf76eSAxel Dörfler #include <String.h>
28b4a12470SJérôme Duval #include <TextView.h>
292af5f895SStephan Aßmus #include <GroupView.h>
302af5f895SStephan Aßmus #include <SpaceLayoutItem.h>
312af5f895SStephan Aßmus 
32a10cf76eSAxel Dörfler #include "MediaViews.h"
33a10cf76eSAxel Dörfler 
34a10cf76eSAxel Dörfler BarView::BarView(BRect frame)
35a10cf76eSAxel Dörfler  : BView (frame, "barView", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW ),
36b4a12470SJérôme Duval  	fDisplay(true)
37a10cf76eSAxel Dörfler {
38a10cf76eSAxel Dörfler }
39a10cf76eSAxel Dörfler 
40a10cf76eSAxel Dörfler void
41a10cf76eSAxel Dörfler BarView::Draw(BRect updateRect)
42a10cf76eSAxel Dörfler {
43a10cf76eSAxel Dörfler 	BRect r = Bounds();
44a10cf76eSAxel Dörfler 
45b4a12470SJérôme Duval 	if (fDisplay) {
46a10cf76eSAxel Dörfler 		// Display the 3D Look Divider Bar
47a10cf76eSAxel Dörfler 		SetHighColor(140,140,140,0);
48a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
49a10cf76eSAxel Dörfler 		SetHighColor(255,255,255,0);
50a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
51a10cf76eSAxel Dörfler 	} else {
52a10cf76eSAxel Dörfler 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
53a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
54a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
55a10cf76eSAxel Dörfler 	}
56a10cf76eSAxel Dörfler }
57a10cf76eSAxel Dörfler 
58a10cf76eSAxel Dörfler 
59a10cf76eSAxel Dörfler SettingsView::SettingsView (BRect frame, bool isVideo)
60a10cf76eSAxel Dörfler  : BView (frame, "SettingsView", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW ),
61b4a12470SJérôme Duval 	fIsVideo(isVideo)
62a10cf76eSAxel Dörfler {
63a10cf76eSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
642af5f895SStephan Aßmus 
65a10cf76eSAxel Dörfler 	BRect rect(frame);
66a10cf76eSAxel Dörfler 	rect.left += 10;
67a10cf76eSAxel Dörfler 	rect.top += 12;
68a10cf76eSAxel Dörfler 	rect.right -=21;
69a10cf76eSAxel Dörfler 	rect.bottom = rect.top + 104;
70a10cf76eSAxel Dörfler 	BBox *defaultsBox = new BBox(rect, "defaults");
71b4a12470SJérôme Duval 	defaultsBox->SetLabel(fIsVideo ? "Default Nodes" : "Defaults");
722af5f895SStephan Aßmus 
732af5f895SStephan Aßmus 	// create the default box
742af5f895SStephan Aßmus 	BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5);
752af5f895SStephan Aßmus 	float inset = defaultsBox->Frame().left - defaultsBox->InnerFrame().left;
762af5f895SStephan Aßmus 	defaultBoxLayout->SetInsets(inset, defaultsBox->TopBorderOffset() * 2, inset, inset);
772af5f895SStephan Aßmus 	defaultsBox->SetLayout(defaultBoxLayout);
782af5f895SStephan Aßmus 	defaultBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
792af5f895SStephan Aßmus 
802af5f895SStephan Aßmus 	BGroupView* inputField = new BGroupView(B_HORIZONTAL);
812af5f895SStephan Aßmus 	BGroupView* outputField = new BGroupView(B_HORIZONTAL);
822af5f895SStephan Aßmus 	defaultsBox->GetLayout()->AddView(inputField);
832af5f895SStephan Aßmus 	defaultsBox->GetLayout()->AddView(outputField);
84a10cf76eSAxel Dörfler 
85a10cf76eSAxel Dörfler 	BRect defaultRect(20, 22, 250, 40);
86b4a12470SJérôme Duval 	float divider = StringWidth(fIsVideo ? "Video Output:" : "Audio Output:") + 5;
87b4a12470SJérôme Duval 	fMenu1 = new BPopUpMenu("<none>");
88b4a12470SJérôme Duval 	fMenu1->SetLabelFromMarked(true);
89a10cf76eSAxel Dörfler 	BMenuField *menuField1 = new BMenuField(defaultRect, "menuField1",
90b4a12470SJérôme Duval 		fIsVideo ? "Video Input:" : "Audio Input:", fMenu1);
91aaa9b739SJérôme Duval 	menuField1->SetDivider(divider);
92a10cf76eSAxel Dörfler 
93a10cf76eSAxel Dörfler 	defaultRect.OffsetBy(0, 26);
94b4a12470SJérôme Duval 	fMenu2 = new BPopUpMenu("<none>");
95b4a12470SJérôme Duval 	fMenu2->SetLabelFromMarked(true);
96a10cf76eSAxel Dörfler 	BMenuField *menuField2 = new BMenuField(defaultRect, "menuField2",
97b4a12470SJérôme Duval 		fIsVideo ? "Video Output:" : "Audio Output:", fMenu2);
98aaa9b739SJérôme Duval 	menuField2->SetDivider(divider);
99a10cf76eSAxel Dörfler 
1002af5f895SStephan Aßmus 	inputField->GroupLayout()->AddView(menuField1);
1012af5f895SStephan Aßmus 	outputField->GroupLayout()->AddView(menuField2);
1022af5f895SStephan Aßmus 
1032af5f895SStephan Aßmus 	BMenuField *menuField3 = NULL;
104b4a12470SJérôme Duval 	if (!fIsVideo) {
105a10cf76eSAxel Dörfler 		defaultRect.OffsetBy(186, 0);
106b4a12470SJérôme Duval 		defaultRect.right -= 30;
107b4a12470SJérôme Duval 		fMenu3 = new BPopUpMenu("<none>");
108b4a12470SJérôme Duval 		fMenu3->SetLabelFromMarked(true);
1092af5f895SStephan Aßmus 		menuField3 = new BMenuField(defaultRect, "menuField3",
110b4a12470SJérôme Duval 			"Channel:", fMenu3);
1112af5f895SStephan Aßmus 		outputField->GroupLayout()->AddView(menuField3);
112b4a12470SJérôme Duval 		menuField3->SetDivider(StringWidth("Channel:")+5);
113b4a12470SJérôme Duval 		defaultRect.right += 30;
114a10cf76eSAxel Dörfler 		defaultRect.OffsetBy(-186, 0);
115a10cf76eSAxel Dörfler 	}
116a10cf76eSAxel Dörfler 
117a10cf76eSAxel Dörfler 	defaultRect.OffsetBy(0, 32);
118b4a12470SJérôme Duval 	defaultRect.right += 100;
119a10cf76eSAxel Dörfler 	rgb_color red_color = {222, 32, 33};
120b4a12470SJérôme Duval 	fRestartView = new BStringView(defaultRect, "restartStringView", "Restart the Media Server to apply changes.",
121b4a12470SJérôme Duval 		B_FOLLOW_ALL, B_WILL_DRAW);
122b4a12470SJérôme Duval 	fRestartView->SetHighColor(red_color);
123b4a12470SJérôme Duval 	defaultsBox->AddChild(fRestartView);
124b4a12470SJérôme Duval 	fRestartView->Hide();
125a10cf76eSAxel Dörfler 
1262af5f895SStephan Aßmus 	// create the realtime box
127a10cf76eSAxel Dörfler 	rect.top = rect.bottom + 10;
128a10cf76eSAxel Dörfler 	rect.bottom = rect.top + 162;
129a10cf76eSAxel Dörfler 	BBox *realtimeBox = new BBox(rect, "realtime");
130a10cf76eSAxel Dörfler 	realtimeBox->SetLabel("Real-Time");
131a10cf76eSAxel Dörfler 
132a10cf76eSAxel Dörfler 	BMessage *message = new BMessage(ML_ENABLE_REAL_TIME);
133b4a12470SJérôme Duval 	message->AddBool("isVideo", fIsVideo);
1342af5f895SStephan Aßmus 	BRect rect2(22,20, frame.Width() - 22, 40);
135b4a12470SJérôme Duval 	fRealtimeCheckBox = new BCheckBox(rect2, "realtimeCheckBox",
136b4a12470SJérôme Duval 		fIsVideo ? "Enable Real-Time Video" : "Enable Real-Time Audio", message);
137a10cf76eSAxel Dörfler 
138a10cf76eSAxel Dörfler 	uint32 flags;
139a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
140b4a12470SJérôme Duval 	if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
141b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
142a10cf76eSAxel Dörfler 
143a10cf76eSAxel Dörfler 	rect2.top += 26;
1445ffd43dcSJérôme Duval 	rect2.bottom = rect.Height() - 5;
145a10cf76eSAxel Dörfler 	BRect textRect(3, 3, rect2.Width() - 3, rect2.Height() - 3);
146b4a12470SJérôme Duval 	BTextView *textView = new BTextView(rect2, "stringView", textRect, B_FOLLOW_ALL, B_WILL_DRAW);
147*774e87aaSPhilippe Houdoin 	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."
148b4a12470SJérôme Duval 		"\n\nOnly enable this feature if you need the lowest latency possible."
149*774e87aaSPhilippe Houdoin 		: "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."
150b4a12470SJérôme Duval 		"\n\nOnly enable this feature if you need the lowest latency possible.");
151b4a12470SJérôme Duval 	textView->MakeEditable(false);
152b4a12470SJérôme Duval 	textView->MakeSelectable(false);
153a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
154a10cf76eSAxel Dörfler 
1552af5f895SStephan Aßmus 	BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
1562af5f895SStephan Aßmus 	inset = realtimeBox->Frame().left - realtimeBox->InnerFrame().left;
1572af5f895SStephan Aßmus 	realtimeBoxLayout->SetInsets(inset, defaultsBox->TopBorderOffset() * 2, inset, inset);
1582af5f895SStephan Aßmus 	realtimeBox->SetLayout(realtimeBoxLayout);
1592af5f895SStephan Aßmus 
1602af5f895SStephan Aßmus 	realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
1612af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(fRealtimeCheckBox);
1622af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(textView);
1632af5f895SStephan Aßmus 
1642af5f895SStephan Aßmus 	// create the bottom line: volumen in deskbar checkbox and restart button
1652af5f895SStephan Aßmus 	BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
166a10cf76eSAxel Dörfler 	rect.top = rect.bottom + 11;
167a10cf76eSAxel Dörfler 	rect.bottom = rect.top + 20;
168aaa9b739SJérôme Duval 	rect.left = rect.right - StringWidth("Restart Media Services") - 20;
169a10cf76eSAxel Dörfler 	BButton *restartButton = new BButton(rect, "restartButton",
170a10cf76eSAxel Dörfler 		"Restart Media Services", new BMessage(ML_RESTART_MEDIA_SERVER));
171a10cf76eSAxel Dörfler 
172b4a12470SJérôme Duval 	if (!fIsVideo) {
173b4a12470SJérôme Duval 		rect.right = rect.left - 10;
174a10cf76eSAxel Dörfler 		rect.top += 4;
175a10cf76eSAxel Dörfler 		rect.left = frame.left + 33;
176b4a12470SJérôme Duval 		if (StringWidth("Show Volume Control on Deskbar") > rect.Width() - 30)
177b4a12470SJérôme Duval 			rect.left -= 10;
178b4a12470SJérôme Duval 		fVolumeCheckBox = new BCheckBox(rect, "volumeCheckBox",
179a10cf76eSAxel Dörfler 			"Show Volume Control on Deskbar", new BMessage(ML_SHOW_VOLUME_CONTROL));
1802af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddView(fVolumeCheckBox);
181a10cf76eSAxel Dörfler 		if (BDeskbar().HasItem("MediaReplicant"))
182b4a12470SJérôme Duval 			fVolumeCheckBox->SetValue(B_CONTROL_ON);
183a10cf76eSAxel Dörfler 	}
1842af5f895SStephan Aßmus 	else{
1852af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
1862af5f895SStephan Aßmus 	}
1872af5f895SStephan Aßmus 	bottomView->GroupLayout()->AddView(restartButton);
1882af5f895SStephan Aßmus 
1892af5f895SStephan Aßmus 	// compose all stuff
1902af5f895SStephan Aßmus 	BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5);
1912af5f895SStephan Aßmus 	SetLayout(rootlayout);
1922af5f895SStephan Aßmus 
1932af5f895SStephan Aßmus 	rootlayout->AddView(defaultsBox);
1942af5f895SStephan Aßmus 	rootlayout->AddView(realtimeBox);
1952af5f895SStephan Aßmus 	rootlayout->AddView(bottomView);
196a10cf76eSAxel Dörfler }
197a10cf76eSAxel Dörfler 
198a10cf76eSAxel Dörfler void
199a10cf76eSAxel Dörfler SettingsView::AddNodes(BList &list, bool isInput)
200a10cf76eSAxel Dörfler {
201b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
202a10cf76eSAxel Dörfler 	void *item;
203a10cf76eSAxel Dörfler 	while ((item = menu->RemoveItem((int32)0)) != NULL)
204a10cf76eSAxel Dörfler 		delete static_cast<dormant_node_info *>(item);
205a10cf76eSAxel Dörfler 
206a10cf76eSAxel Dörfler 	BMessage message(ML_DEFAULT_CHANGE);
207b4a12470SJérôme Duval 	message.AddBool("isVideo", fIsVideo);
208a10cf76eSAxel Dörfler 	message.AddBool("isInput", isInput);
209a10cf76eSAxel Dörfler 
210a10cf76eSAxel Dörfler 	for (int32 i = 0; i < list.CountItems(); i++) {
211a10cf76eSAxel Dörfler 		dormant_node_info *info = static_cast<dormant_node_info *>(list.ItemAt(i));
212a10cf76eSAxel Dörfler 		menu->AddItem(new SettingsItem(info, new BMessage(message)));
213a10cf76eSAxel Dörfler 	}
214a10cf76eSAxel Dörfler }
215a10cf76eSAxel Dörfler 
216a10cf76eSAxel Dörfler void
217a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
218a10cf76eSAxel Dörfler {
219b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
220a10cf76eSAxel Dörfler 
221a10cf76eSAxel Dörfler 	for (int32 i = 0; i < menu->CountItems(); i++) {
222a10cf76eSAxel Dörfler 		SettingsItem *item = static_cast<SettingsItem *>(menu->ItemAt(i));
223b4a12470SJérôme Duval 		if (item->fInfo && item->fInfo->addon == info.addon && item->fInfo->flavor_id == info.flavor_id) {
224a10cf76eSAxel Dörfler 			item->SetMarked(true);
225a10cf76eSAxel Dörfler 			break;
226a10cf76eSAxel Dörfler 		}
227a10cf76eSAxel Dörfler 	}
228a10cf76eSAxel Dörfler 
229b4a12470SJérôme Duval 	if (!fIsVideo&&!isInput&&outputID>-1) {
230a10cf76eSAxel Dörfler 		BMenuItem *item;
231b4a12470SJérôme Duval 		while ((item = fMenu3->RemoveItem((int32)0)) != NULL)
232a10cf76eSAxel Dörfler 			delete item;
233a10cf76eSAxel Dörfler 		BMediaRoster *roster = BMediaRoster::Roster();
234a10cf76eSAxel Dörfler 		media_node node;
235a10cf76eSAxel Dörfler 		media_node_id node_id;
236a10cf76eSAxel Dörfler 		status_t err;
237a10cf76eSAxel Dörfler 		if (roster->GetInstancesFor(info.addon, info.flavor_id, &node_id)!=B_OK)
238a10cf76eSAxel Dörfler 			err = roster->InstantiateDormantNode(info, &node, B_FLAVOR_IS_GLOBAL);
239a10cf76eSAxel Dörfler 		else
240a10cf76eSAxel Dörfler 			err = roster->GetNodeFor(node_id, &node);
241a10cf76eSAxel Dörfler 
242a10cf76eSAxel Dörfler 		if (err == B_OK) {
243a10cf76eSAxel Dörfler 			media_input inputs[16];
244a10cf76eSAxel Dörfler 			int32 inputCount = 16;
245a10cf76eSAxel Dörfler 			if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
246a10cf76eSAxel Dörfler 				BMessage message(ML_DEFAULTOUTPUT_CHANGE);
247a10cf76eSAxel Dörfler 
248a10cf76eSAxel Dörfler 				for (int32 i = 0; i < inputCount; i++) {
249a10cf76eSAxel Dörfler 					media_input *input = new media_input();
250a10cf76eSAxel Dörfler 					memcpy(input, &inputs[i], sizeof(*input));
251b4a12470SJérôme Duval 					fMenu3->AddItem(item = new Settings2Item(&info, input, new BMessage(message)));
252a10cf76eSAxel Dörfler 					if (inputs[i].destination.id == outputID)
253a10cf76eSAxel Dörfler 						item->SetMarked(true);
254a10cf76eSAxel Dörfler 				}
255a10cf76eSAxel Dörfler 			}
256a10cf76eSAxel Dörfler 		}
257a10cf76eSAxel Dörfler 	}
258a10cf76eSAxel Dörfler }
259a10cf76eSAxel Dörfler 
260a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info *info, BMessage *message,
261a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
262a10cf76eSAxel Dörfler 	: BMenuItem(info->name, message, shortcut, modifiers),
263b4a12470SJérôme Duval 	fInfo(info)
264a10cf76eSAxel Dörfler {
265a10cf76eSAxel Dörfler 
266a10cf76eSAxel Dörfler }
267a10cf76eSAxel Dörfler 
2686df0b2d5SJérôme Duval 
2696df0b2d5SJérôme Duval status_t
2706df0b2d5SJérôme Duval SettingsItem::Invoke(BMessage *message)
2716df0b2d5SJérôme Duval {
2726df0b2d5SJérôme Duval 	if (IsMarked())
2736df0b2d5SJérôme Duval 		return B_OK;
2746df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2756df0b2d5SJérôme Duval }
2766df0b2d5SJérôme Duval 
2776df0b2d5SJérôme Duval 
278a10cf76eSAxel Dörfler Settings2Item::Settings2Item(dormant_node_info *info, media_input *input, BMessage *message,
279a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
280a10cf76eSAxel Dörfler 	: BMenuItem(input->name, message, shortcut, modifiers),
281b4a12470SJérôme Duval 	fInfo(info),
282b4a12470SJérôme Duval 	fInput(input)
283a10cf76eSAxel Dörfler {
284a10cf76eSAxel Dörfler 
285a10cf76eSAxel Dörfler }
286a10cf76eSAxel Dörfler 
2876df0b2d5SJérôme Duval 
288a10cf76eSAxel Dörfler Settings2Item::~Settings2Item()
289a10cf76eSAxel Dörfler {
290b4a12470SJérôme Duval 	delete fInput;
291a10cf76eSAxel Dörfler }
292a10cf76eSAxel Dörfler 
2936df0b2d5SJérôme Duval 
2946df0b2d5SJérôme Duval status_t
2956df0b2d5SJérôme Duval Settings2Item::Invoke(BMessage *message)
2966df0b2d5SJérôme Duval {
2976df0b2d5SJérôme Duval 	if (IsMarked())
2986df0b2d5SJérôme Duval 		return B_OK;
2996df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
3006df0b2d5SJérôme Duval }
3016df0b2d5SJérôme Duval 
302