xref: /haiku/src/preferences/media/MediaViews.cpp (revision 176fb40f5b76af8cb0aefc17f975de11ea6ae24a)
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 -------------------------------------------------------------------------------------------------- //
18f8a1135cSAdrien Destugues #include <stdio.h>
19f8a1135cSAdrien Destugues 
20a10cf76eSAxel Dörfler #include <Box.h>
21a10cf76eSAxel Dörfler #include <Button.h>
22f8a1135cSAdrien Destugues #include <Catalog.h>
23a10cf76eSAxel Dörfler #include <Deskbar.h>
24a10cf76eSAxel Dörfler #include <Entry.h>
25f8a1135cSAdrien Destugues #include <GroupView.h>
26f8a1135cSAdrien Destugues #include <Locale.h>
27a10cf76eSAxel Dörfler #include <MediaAddOn.h>
28f8a1135cSAdrien Destugues #include <MediaRoster.h>
29f8a1135cSAdrien Destugues #include <MenuField.h>
30f8a1135cSAdrien Destugues #include <PopUpMenu.h>
31f8a1135cSAdrien Destugues #include <SpaceLayoutItem.h>
32a10cf76eSAxel Dörfler #include <String.h>
33b4a12470SJérôme Duval #include <TextView.h>
342af5f895SStephan Aßmus 
35a10cf76eSAxel Dörfler #include "MediaViews.h"
36a10cf76eSAxel Dörfler 
37f8a1135cSAdrien Destugues #define TR_CONTEXT "Media views"
38f8a1135cSAdrien Destugues 
39c8602bcdSRene Gollent BarView::BarView()
40c8602bcdSRene Gollent  : BView ("barView", B_WILL_DRAW ),
41b4a12470SJérôme Duval  	fDisplay(true)
42a10cf76eSAxel Dörfler {
43a10cf76eSAxel Dörfler }
44a10cf76eSAxel Dörfler 
45a10cf76eSAxel Dörfler void
46a10cf76eSAxel Dörfler BarView::Draw(BRect updateRect)
47a10cf76eSAxel Dörfler {
48a10cf76eSAxel Dörfler 	BRect r = Bounds();
49a10cf76eSAxel Dörfler 
50b4a12470SJérôme Duval 	if (fDisplay) {
51a10cf76eSAxel Dörfler 		// Display the 3D Look Divider Bar
52a10cf76eSAxel Dörfler 		SetHighColor(140,140,140,0);
53a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
54a10cf76eSAxel Dörfler 		SetHighColor(255,255,255,0);
55a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
56a10cf76eSAxel Dörfler 	} else {
57a10cf76eSAxel Dörfler 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
58a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
59a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
60a10cf76eSAxel Dörfler 	}
61a10cf76eSAxel Dörfler }
62a10cf76eSAxel Dörfler 
63a10cf76eSAxel Dörfler 
64c8602bcdSRene Gollent SettingsView::SettingsView (bool isVideo)
65c8602bcdSRene Gollent  : BView ("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
66b4a12470SJérôme Duval 	fIsVideo(isVideo)
67a10cf76eSAxel Dörfler {
68a10cf76eSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
692af5f895SStephan Aßmus 
70c8602bcdSRene Gollent 	BBox *defaultsBox = new BBox("defaults");
71*176fb40fSMatt Madia 	defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes")
72*176fb40fSMatt Madia 		: B_TRANSLATE("Defaults"));
732af5f895SStephan Aßmus 
742af5f895SStephan Aßmus 	// create the default box
752af5f895SStephan Aßmus 	BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5);
76c8602bcdSRene Gollent 	defaultBoxLayout->SetInsets(10,10,10,10);
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 
85*176fb40fSMatt Madia 	float divider = StringWidth(fIsVideo ? B_TRANSLATE("Video output:")
86*176fb40fSMatt Madia 		: B_TRANSLATE("Audio output:")) + 5;
87b4a12470SJérôme Duval 	fMenu1 = new BPopUpMenu("<none>");
88b4a12470SJérôme Duval 	fMenu1->SetLabelFromMarked(true);
89c8602bcdSRene Gollent 	BMenuField *menuField1 = new BMenuField("menuField1",
90*176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Video input:")
91*176fb40fSMatt Madia 			: B_TRANSLATE("Audio input:"), fMenu1, NULL);
92aaa9b739SJérôme Duval 	menuField1->SetDivider(divider);
93a10cf76eSAxel Dörfler 
94b4a12470SJérôme Duval 	fMenu2 = new BPopUpMenu("<none>");
95b4a12470SJérôme Duval 	fMenu2->SetLabelFromMarked(true);
96c8602bcdSRene Gollent 	BMenuField *menuField2 = new BMenuField("menuField2",
97*176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Video output:")
98*176fb40fSMatt Madia 			: B_TRANSLATE("Audio output:"), fMenu2, NULL);
99aaa9b739SJérôme Duval 	menuField2->SetDivider(divider);
100a10cf76eSAxel Dörfler 
1012af5f895SStephan Aßmus 	inputField->GroupLayout()->AddView(menuField1);
1022af5f895SStephan Aßmus 	outputField->GroupLayout()->AddView(menuField2);
1032af5f895SStephan Aßmus 
1042af5f895SStephan Aßmus 	BMenuField *menuField3 = NULL;
105b4a12470SJérôme Duval 	if (!fIsVideo) {
106b4a12470SJérôme Duval 		fMenu3 = new BPopUpMenu("<none>");
107b4a12470SJérôme Duval 		fMenu3->SetLabelFromMarked(true);
108c8602bcdSRene Gollent 		menuField3 = new BMenuField("menuField3",
109*176fb40fSMatt Madia 			B_TRANSLATE("Channel:"), fMenu3, NULL);
1102af5f895SStephan Aßmus 		outputField->GroupLayout()->AddView(menuField3);
111*176fb40fSMatt Madia 		menuField3->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5);
112a10cf76eSAxel Dörfler 	}
113a10cf76eSAxel Dörfler 
114a10cf76eSAxel Dörfler 	rgb_color red_color = {222, 32, 33};
115c8602bcdSRene Gollent 	fRestartView = new BStringView("restartStringView",
116*176fb40fSMatt Madia 		B_TRANSLATE("Restart the media server to apply changes."));
117b4a12470SJérôme Duval 	fRestartView->SetHighColor(red_color);
118b4a12470SJérôme Duval 	defaultsBox->AddChild(fRestartView);
119b4a12470SJérôme Duval 	fRestartView->Hide();
120a10cf76eSAxel Dörfler 
1212af5f895SStephan Aßmus 	// create the realtime box
122c8602bcdSRene Gollent 	BBox *realtimeBox = new BBox("realtime");
123*176fb40fSMatt Madia 	realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
124a10cf76eSAxel Dörfler 
125a10cf76eSAxel Dörfler 	BMessage *message = new BMessage(ML_ENABLE_REAL_TIME);
126b4a12470SJérôme Duval 	message->AddBool("isVideo", fIsVideo);
127c8602bcdSRene Gollent 	fRealtimeCheckBox = new BCheckBox("realtimeCheckBox",
128*176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Enable real-time video")
129*176fb40fSMatt Madia 			: B_TRANSLATE("Enable real-time audio"),
130c8602bcdSRene Gollent 		message);
131a10cf76eSAxel Dörfler 
132a10cf76eSAxel Dörfler 	uint32 flags;
133a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
134b4a12470SJérôme Duval 	if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
135b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
136a10cf76eSAxel Dörfler 
137c8602bcdSRene Gollent 	BTextView *textView = new BTextView("stringView");
138*176fb40fSMatt Madia 	textView->Insert(fIsVideo ? B_TRANSLATE(
139*176fb40fSMatt Madia 		"Enabling real-time video allows system to "
140f8a1135cSAdrien Destugues 		"perform video operations as fast and smoothly as possible.  It "
141f8a1135cSAdrien Destugues 		"achieves optimum performance by using more RAM."
142f8a1135cSAdrien Destugues 		"\n\nOnly enable this feature if you need the lowest latency possible.")
143*176fb40fSMatt Madia 		: B_TRANSLATE(
144*176fb40fSMatt Madia 		"Enabling real-time audio allows system to record and play audio "
145f8a1135cSAdrien Destugues 		"as fast as possible.  It achieves this performance by using more CPU and RAM."
146f8a1135cSAdrien Destugues 		"\n\nOnly enable this feature if you need the lowest latency possible."));
147b4a12470SJérôme Duval 	textView->MakeEditable(false);
148b4a12470SJérôme Duval 	textView->MakeSelectable(false);
149a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
150a10cf76eSAxel Dörfler 
1512af5f895SStephan Aßmus 	BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
152c8602bcdSRene Gollent 	realtimeBoxLayout->SetInsets(10,10,10,10);
1532af5f895SStephan Aßmus 	realtimeBox->SetLayout(realtimeBoxLayout);
1542af5f895SStephan Aßmus 
1552af5f895SStephan Aßmus 	realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
1562af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(fRealtimeCheckBox);
1572af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(textView);
1582af5f895SStephan Aßmus 
1592af5f895SStephan Aßmus 	// create the bottom line: volumen in deskbar checkbox and restart button
1602af5f895SStephan Aßmus 	BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
161c8602bcdSRene Gollent 	BButton *restartButton = new BButton("restartButton",
162*176fb40fSMatt Madia 		B_TRANSLATE("Restart media services"),
163*176fb40fSMatt Madia 		new BMessage(ML_RESTART_MEDIA_SERVER));
164a10cf76eSAxel Dörfler 
165b4a12470SJérôme Duval 	if (!fIsVideo) {
166c8602bcdSRene Gollent 		fVolumeCheckBox = new BCheckBox("volumeCheckBox",
167*176fb40fSMatt Madia 			B_TRANSLATE("Show volume control on Deskbar"),
168*176fb40fSMatt Madia 			new BMessage(ML_SHOW_VOLUME_CONTROL));
1692af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddView(fVolumeCheckBox);
170a10cf76eSAxel Dörfler 		if (BDeskbar().HasItem("MediaReplicant"))
171b4a12470SJérôme Duval 			fVolumeCheckBox->SetValue(B_CONTROL_ON);
172a10cf76eSAxel Dörfler 	}
1732af5f895SStephan Aßmus 	else{
1742af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
1752af5f895SStephan Aßmus 	}
1762af5f895SStephan Aßmus 	bottomView->GroupLayout()->AddView(restartButton);
1772af5f895SStephan Aßmus 
1782af5f895SStephan Aßmus 	// compose all stuff
1792af5f895SStephan Aßmus 	BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5);
1802af5f895SStephan Aßmus 	SetLayout(rootlayout);
1812af5f895SStephan Aßmus 
1822af5f895SStephan Aßmus 	rootlayout->AddView(defaultsBox);
1832af5f895SStephan Aßmus 	rootlayout->AddView(realtimeBox);
1842af5f895SStephan Aßmus 	rootlayout->AddView(bottomView);
185a10cf76eSAxel Dörfler }
186a10cf76eSAxel Dörfler 
187a10cf76eSAxel Dörfler void
188a10cf76eSAxel Dörfler SettingsView::AddNodes(BList &list, bool isInput)
189a10cf76eSAxel Dörfler {
190b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
191a10cf76eSAxel Dörfler 	void *item;
192a10cf76eSAxel Dörfler 	while ((item = menu->RemoveItem((int32)0)) != NULL)
193a10cf76eSAxel Dörfler 		delete static_cast<dormant_node_info *>(item);
194a10cf76eSAxel Dörfler 
195a10cf76eSAxel Dörfler 	BMessage message(ML_DEFAULT_CHANGE);
196b4a12470SJérôme Duval 	message.AddBool("isVideo", fIsVideo);
197a10cf76eSAxel Dörfler 	message.AddBool("isInput", isInput);
198a10cf76eSAxel Dörfler 
199a10cf76eSAxel Dörfler 	for (int32 i = 0; i < list.CountItems(); i++) {
200a10cf76eSAxel Dörfler 		dormant_node_info *info = static_cast<dormant_node_info *>(list.ItemAt(i));
201a10cf76eSAxel Dörfler 		menu->AddItem(new SettingsItem(info, new BMessage(message)));
202a10cf76eSAxel Dörfler 	}
203a10cf76eSAxel Dörfler }
204a10cf76eSAxel Dörfler 
205a10cf76eSAxel Dörfler void
206a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
207a10cf76eSAxel Dörfler {
208b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
209a10cf76eSAxel Dörfler 
210a10cf76eSAxel Dörfler 	for (int32 i = 0; i < menu->CountItems(); i++) {
211a10cf76eSAxel Dörfler 		SettingsItem *item = static_cast<SettingsItem *>(menu->ItemAt(i));
212b4a12470SJérôme Duval 		if (item->fInfo && item->fInfo->addon == info.addon && item->fInfo->flavor_id == info.flavor_id) {
213a10cf76eSAxel Dörfler 			item->SetMarked(true);
214a10cf76eSAxel Dörfler 			break;
215a10cf76eSAxel Dörfler 		}
216a10cf76eSAxel Dörfler 	}
217a10cf76eSAxel Dörfler 
218b4a12470SJérôme Duval 	if (!fIsVideo&&!isInput&&outputID>-1) {
219a10cf76eSAxel Dörfler 		BMenuItem *item;
220b4a12470SJérôme Duval 		while ((item = fMenu3->RemoveItem((int32)0)) != NULL)
221a10cf76eSAxel Dörfler 			delete item;
222a10cf76eSAxel Dörfler 		BMediaRoster *roster = BMediaRoster::Roster();
223a10cf76eSAxel Dörfler 		media_node node;
224a10cf76eSAxel Dörfler 		media_node_id node_id;
225a10cf76eSAxel Dörfler 		status_t err;
226a10cf76eSAxel Dörfler 		if (roster->GetInstancesFor(info.addon, info.flavor_id, &node_id)!=B_OK)
227a10cf76eSAxel Dörfler 			err = roster->InstantiateDormantNode(info, &node, B_FLAVOR_IS_GLOBAL);
228a10cf76eSAxel Dörfler 		else
229a10cf76eSAxel Dörfler 			err = roster->GetNodeFor(node_id, &node);
230a10cf76eSAxel Dörfler 
231a10cf76eSAxel Dörfler 		if (err == B_OK) {
232a10cf76eSAxel Dörfler 			media_input inputs[16];
233a10cf76eSAxel Dörfler 			int32 inputCount = 16;
234a10cf76eSAxel Dörfler 			if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
235a10cf76eSAxel Dörfler 				BMessage message(ML_DEFAULTOUTPUT_CHANGE);
236a10cf76eSAxel Dörfler 
237a10cf76eSAxel Dörfler 				for (int32 i = 0; i < inputCount; i++) {
238a10cf76eSAxel Dörfler 					media_input *input = new media_input();
239a10cf76eSAxel Dörfler 					memcpy(input, &inputs[i], sizeof(*input));
240b4a12470SJérôme Duval 					fMenu3->AddItem(item = new Settings2Item(&info, input, new BMessage(message)));
241a10cf76eSAxel Dörfler 					if (inputs[i].destination.id == outputID)
242a10cf76eSAxel Dörfler 						item->SetMarked(true);
243a10cf76eSAxel Dörfler 				}
244a10cf76eSAxel Dörfler 			}
245a10cf76eSAxel Dörfler 		}
246a10cf76eSAxel Dörfler 	}
247a10cf76eSAxel Dörfler }
248a10cf76eSAxel Dörfler 
249a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info *info, BMessage *message,
250a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
251a10cf76eSAxel Dörfler 	: BMenuItem(info->name, message, shortcut, modifiers),
252b4a12470SJérôme Duval 	fInfo(info)
253a10cf76eSAxel Dörfler {
254a10cf76eSAxel Dörfler 
255a10cf76eSAxel Dörfler }
256a10cf76eSAxel Dörfler 
2576df0b2d5SJérôme Duval 
2586df0b2d5SJérôme Duval status_t
2596df0b2d5SJérôme Duval SettingsItem::Invoke(BMessage *message)
2606df0b2d5SJérôme Duval {
2616df0b2d5SJérôme Duval 	if (IsMarked())
2626df0b2d5SJérôme Duval 		return B_OK;
2636df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2646df0b2d5SJérôme Duval }
2656df0b2d5SJérôme Duval 
2666df0b2d5SJérôme Duval 
267a10cf76eSAxel Dörfler Settings2Item::Settings2Item(dormant_node_info *info, media_input *input, BMessage *message,
268a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
269a10cf76eSAxel Dörfler 	: BMenuItem(input->name, message, shortcut, modifiers),
270b4a12470SJérôme Duval 	fInfo(info),
271b4a12470SJérôme Duval 	fInput(input)
272a10cf76eSAxel Dörfler {
273a10cf76eSAxel Dörfler 
274a10cf76eSAxel Dörfler }
275a10cf76eSAxel Dörfler 
2766df0b2d5SJérôme Duval 
277a10cf76eSAxel Dörfler Settings2Item::~Settings2Item()
278a10cf76eSAxel Dörfler {
279b4a12470SJérôme Duval 	delete fInput;
280a10cf76eSAxel Dörfler }
281a10cf76eSAxel Dörfler 
2826df0b2d5SJérôme Duval 
2836df0b2d5SJérôme Duval status_t
2846df0b2d5SJérôme Duval Settings2Item::Invoke(BMessage *message)
2856df0b2d5SJérôme Duval {
2866df0b2d5SJérôme Duval 	if (IsMarked())
2876df0b2d5SJérôme Duval 		return B_OK;
2886df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2896df0b2d5SJérôme Duval }
2906df0b2d5SJérôme Duval 
291