xref: /haiku/src/preferences/media/MediaViews.cpp (revision 9cedafe60c43b9a27136d05b951342261b3c4d7b)
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 
37*9cedafe6SWim van der Meer 
38*9cedafe6SWim van der Meer #undef B_TRANSLATE_CONTEXT
394eb0cbb0SMatt Madia #define B_TRANSLATE_CONTEXT "Media views"
40f8a1135cSAdrien Destugues 
41*9cedafe6SWim van der Meer 
42c8602bcdSRene Gollent BarView::BarView()
43c8602bcdSRene Gollent  : BView ("barView", B_WILL_DRAW ),
44b4a12470SJérôme Duval  	fDisplay(true)
45a10cf76eSAxel Dörfler {
46a10cf76eSAxel Dörfler }
47a10cf76eSAxel Dörfler 
48a10cf76eSAxel Dörfler void
49a10cf76eSAxel Dörfler BarView::Draw(BRect updateRect)
50a10cf76eSAxel Dörfler {
51a10cf76eSAxel Dörfler 	BRect r = Bounds();
52a10cf76eSAxel Dörfler 
53b4a12470SJérôme Duval 	if (fDisplay) {
54a10cf76eSAxel Dörfler 		// Display the 3D Look Divider Bar
55a10cf76eSAxel Dörfler 		SetHighColor(140,140,140,0);
56a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
57a10cf76eSAxel Dörfler 		SetHighColor(255,255,255,0);
58a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
59a10cf76eSAxel Dörfler 	} else {
60a10cf76eSAxel Dörfler 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
61a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
62a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
63a10cf76eSAxel Dörfler 	}
64a10cf76eSAxel Dörfler }
65a10cf76eSAxel Dörfler 
66a10cf76eSAxel Dörfler 
67c8602bcdSRene Gollent SettingsView::SettingsView (bool isVideo)
68c8602bcdSRene Gollent  : BView ("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
69b4a12470SJérôme Duval 	fIsVideo(isVideo)
70a10cf76eSAxel Dörfler {
71a10cf76eSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
722af5f895SStephan Aßmus 
73c8602bcdSRene Gollent 	BBox *defaultsBox = new BBox("defaults");
74176fb40fSMatt Madia 	defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes")
75176fb40fSMatt Madia 		: B_TRANSLATE("Defaults"));
762af5f895SStephan Aßmus 
772af5f895SStephan Aßmus 	// create the default box
782af5f895SStephan Aßmus 	BGroupLayout* defaultBoxLayout = new BGroupLayout(B_VERTICAL, 5);
79c8602bcdSRene Gollent 	defaultBoxLayout->SetInsets(10,10,10,10);
802af5f895SStephan Aßmus 	defaultsBox->SetLayout(defaultBoxLayout);
812af5f895SStephan Aßmus 	defaultBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
822af5f895SStephan Aßmus 
832af5f895SStephan Aßmus 	BGroupView* inputField = new BGroupView(B_HORIZONTAL);
842af5f895SStephan Aßmus 	BGroupView* outputField = new BGroupView(B_HORIZONTAL);
852af5f895SStephan Aßmus 	defaultsBox->GetLayout()->AddView(inputField);
862af5f895SStephan Aßmus 	defaultsBox->GetLayout()->AddView(outputField);
87a10cf76eSAxel Dörfler 
88176fb40fSMatt Madia 	float divider = StringWidth(fIsVideo ? B_TRANSLATE("Video output:")
89176fb40fSMatt Madia 		: B_TRANSLATE("Audio output:")) + 5;
90b4a12470SJérôme Duval 	fMenu1 = new BPopUpMenu("<none>");
91b4a12470SJérôme Duval 	fMenu1->SetLabelFromMarked(true);
92c8602bcdSRene Gollent 	BMenuField *menuField1 = new BMenuField("menuField1",
93176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Video input:")
94176fb40fSMatt Madia 			: B_TRANSLATE("Audio input:"), fMenu1, NULL);
95aaa9b739SJérôme Duval 	menuField1->SetDivider(divider);
96a10cf76eSAxel Dörfler 
97b4a12470SJérôme Duval 	fMenu2 = new BPopUpMenu("<none>");
98b4a12470SJérôme Duval 	fMenu2->SetLabelFromMarked(true);
99c8602bcdSRene Gollent 	BMenuField *menuField2 = new BMenuField("menuField2",
100176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Video output:")
101176fb40fSMatt Madia 			: B_TRANSLATE("Audio output:"), fMenu2, NULL);
102aaa9b739SJérôme Duval 	menuField2->SetDivider(divider);
103a10cf76eSAxel Dörfler 
1042af5f895SStephan Aßmus 	inputField->GroupLayout()->AddView(menuField1);
1052af5f895SStephan Aßmus 	outputField->GroupLayout()->AddView(menuField2);
1062af5f895SStephan Aßmus 
1072af5f895SStephan Aßmus 	BMenuField *menuField3 = NULL;
108b4a12470SJérôme Duval 	if (!fIsVideo) {
109b4a12470SJérôme Duval 		fMenu3 = new BPopUpMenu("<none>");
110b4a12470SJérôme Duval 		fMenu3->SetLabelFromMarked(true);
111c8602bcdSRene Gollent 		menuField3 = new BMenuField("menuField3",
112176fb40fSMatt Madia 			B_TRANSLATE("Channel:"), fMenu3, NULL);
1132af5f895SStephan Aßmus 		outputField->GroupLayout()->AddView(menuField3);
114176fb40fSMatt Madia 		menuField3->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5);
115a10cf76eSAxel Dörfler 	}
116a10cf76eSAxel Dörfler 
117a10cf76eSAxel Dörfler 	rgb_color red_color = {222, 32, 33};
118c8602bcdSRene Gollent 	fRestartView = new BStringView("restartStringView",
119176fb40fSMatt Madia 		B_TRANSLATE("Restart the media server to apply changes."));
120b4a12470SJérôme Duval 	fRestartView->SetHighColor(red_color);
121b4a12470SJérôme Duval 	defaultsBox->AddChild(fRestartView);
122b4a12470SJérôme Duval 	fRestartView->Hide();
123a10cf76eSAxel Dörfler 
1242af5f895SStephan Aßmus 	// create the realtime box
125c8602bcdSRene Gollent 	BBox *realtimeBox = new BBox("realtime");
126176fb40fSMatt Madia 	realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
127a10cf76eSAxel Dörfler 
128a10cf76eSAxel Dörfler 	BMessage *message = new BMessage(ML_ENABLE_REAL_TIME);
129b4a12470SJérôme Duval 	message->AddBool("isVideo", fIsVideo);
130c8602bcdSRene Gollent 	fRealtimeCheckBox = new BCheckBox("realtimeCheckBox",
131176fb40fSMatt Madia 		fIsVideo ? B_TRANSLATE("Enable real-time video")
132176fb40fSMatt Madia 			: B_TRANSLATE("Enable real-time audio"),
133c8602bcdSRene Gollent 		message);
134a10cf76eSAxel Dörfler 
135a10cf76eSAxel Dörfler 	uint32 flags;
136a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
137b4a12470SJérôme Duval 	if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
138b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
139a10cf76eSAxel Dörfler 
140c8602bcdSRene Gollent 	BTextView *textView = new BTextView("stringView");
141176fb40fSMatt Madia 	textView->Insert(fIsVideo ? B_TRANSLATE(
142176fb40fSMatt Madia 		"Enabling real-time video allows system to "
143f8a1135cSAdrien Destugues 		"perform video operations as fast and smoothly as possible.  It "
144f8a1135cSAdrien Destugues 		"achieves optimum performance by using more RAM."
145f8a1135cSAdrien Destugues 		"\n\nOnly enable this feature if you need the lowest latency possible.")
146176fb40fSMatt Madia 		: B_TRANSLATE(
147176fb40fSMatt Madia 		"Enabling real-time audio allows system to record and play audio "
148f8a1135cSAdrien Destugues 		"as fast as possible.  It achieves this performance by using more CPU and RAM."
149f8a1135cSAdrien Destugues 		"\n\nOnly enable this feature if you need the lowest latency possible."));
150b4a12470SJérôme Duval 	textView->MakeEditable(false);
151b4a12470SJérôme Duval 	textView->MakeSelectable(false);
152a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
153a10cf76eSAxel Dörfler 
1542af5f895SStephan Aßmus 	BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
155c8602bcdSRene Gollent 	realtimeBoxLayout->SetInsets(10,10,10,10);
1562af5f895SStephan Aßmus 	realtimeBox->SetLayout(realtimeBoxLayout);
1572af5f895SStephan Aßmus 
1582af5f895SStephan Aßmus 	realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
1592af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(fRealtimeCheckBox);
1602af5f895SStephan Aßmus 	realtimeBoxLayout->AddView(textView);
1612af5f895SStephan Aßmus 
1622af5f895SStephan Aßmus 	// create the bottom line: volumen in deskbar checkbox and restart button
1632af5f895SStephan Aßmus 	BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
164c8602bcdSRene Gollent 	BButton *restartButton = new BButton("restartButton",
165176fb40fSMatt Madia 		B_TRANSLATE("Restart media services"),
166176fb40fSMatt Madia 		new BMessage(ML_RESTART_MEDIA_SERVER));
167a10cf76eSAxel Dörfler 
168b4a12470SJérôme Duval 	if (!fIsVideo) {
169c8602bcdSRene Gollent 		fVolumeCheckBox = new BCheckBox("volumeCheckBox",
170176fb40fSMatt Madia 			B_TRANSLATE("Show volume control on Deskbar"),
171176fb40fSMatt Madia 			new BMessage(ML_SHOW_VOLUME_CONTROL));
1722af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddView(fVolumeCheckBox);
173a10cf76eSAxel Dörfler 		if (BDeskbar().HasItem("MediaReplicant"))
174b4a12470SJérôme Duval 			fVolumeCheckBox->SetValue(B_CONTROL_ON);
175a10cf76eSAxel Dörfler 	}
1762af5f895SStephan Aßmus 	else{
1772af5f895SStephan Aßmus 		bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
1782af5f895SStephan Aßmus 	}
1792af5f895SStephan Aßmus 	bottomView->GroupLayout()->AddView(restartButton);
1802af5f895SStephan Aßmus 
1812af5f895SStephan Aßmus 	// compose all stuff
1822af5f895SStephan Aßmus 	BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5);
1832af5f895SStephan Aßmus 	SetLayout(rootlayout);
1842af5f895SStephan Aßmus 
1852af5f895SStephan Aßmus 	rootlayout->AddView(defaultsBox);
1862af5f895SStephan Aßmus 	rootlayout->AddView(realtimeBox);
1872af5f895SStephan Aßmus 	rootlayout->AddView(bottomView);
188a10cf76eSAxel Dörfler }
189a10cf76eSAxel Dörfler 
190a10cf76eSAxel Dörfler void
191a10cf76eSAxel Dörfler SettingsView::AddNodes(BList &list, bool isInput)
192a10cf76eSAxel Dörfler {
193b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
194a10cf76eSAxel Dörfler 	void *item;
195a10cf76eSAxel Dörfler 	while ((item = menu->RemoveItem((int32)0)) != NULL)
196a10cf76eSAxel Dörfler 		delete static_cast<dormant_node_info *>(item);
197a10cf76eSAxel Dörfler 
198a10cf76eSAxel Dörfler 	BMessage message(ML_DEFAULT_CHANGE);
199b4a12470SJérôme Duval 	message.AddBool("isVideo", fIsVideo);
200a10cf76eSAxel Dörfler 	message.AddBool("isInput", isInput);
201a10cf76eSAxel Dörfler 
202a10cf76eSAxel Dörfler 	for (int32 i = 0; i < list.CountItems(); i++) {
203a10cf76eSAxel Dörfler 		dormant_node_info *info = static_cast<dormant_node_info *>(list.ItemAt(i));
204a10cf76eSAxel Dörfler 		menu->AddItem(new SettingsItem(info, new BMessage(message)));
205a10cf76eSAxel Dörfler 	}
206a10cf76eSAxel Dörfler }
207a10cf76eSAxel Dörfler 
208a10cf76eSAxel Dörfler void
209a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
210a10cf76eSAxel Dörfler {
211b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
212a10cf76eSAxel Dörfler 
213a10cf76eSAxel Dörfler 	for (int32 i = 0; i < menu->CountItems(); i++) {
214a10cf76eSAxel Dörfler 		SettingsItem *item = static_cast<SettingsItem *>(menu->ItemAt(i));
215b4a12470SJérôme Duval 		if (item->fInfo && item->fInfo->addon == info.addon && item->fInfo->flavor_id == info.flavor_id) {
216a10cf76eSAxel Dörfler 			item->SetMarked(true);
217a10cf76eSAxel Dörfler 			break;
218a10cf76eSAxel Dörfler 		}
219a10cf76eSAxel Dörfler 	}
220a10cf76eSAxel Dörfler 
221b4a12470SJérôme Duval 	if (!fIsVideo&&!isInput&&outputID>-1) {
222a10cf76eSAxel Dörfler 		BMenuItem *item;
223b4a12470SJérôme Duval 		while ((item = fMenu3->RemoveItem((int32)0)) != NULL)
224a10cf76eSAxel Dörfler 			delete item;
225a10cf76eSAxel Dörfler 		BMediaRoster *roster = BMediaRoster::Roster();
226a10cf76eSAxel Dörfler 		media_node node;
227a10cf76eSAxel Dörfler 		media_node_id node_id;
228a10cf76eSAxel Dörfler 		status_t err;
229a10cf76eSAxel Dörfler 		if (roster->GetInstancesFor(info.addon, info.flavor_id, &node_id)!=B_OK)
230a10cf76eSAxel Dörfler 			err = roster->InstantiateDormantNode(info, &node, B_FLAVOR_IS_GLOBAL);
231a10cf76eSAxel Dörfler 		else
232a10cf76eSAxel Dörfler 			err = roster->GetNodeFor(node_id, &node);
233a10cf76eSAxel Dörfler 
234a10cf76eSAxel Dörfler 		if (err == B_OK) {
235a10cf76eSAxel Dörfler 			media_input inputs[16];
236a10cf76eSAxel Dörfler 			int32 inputCount = 16;
237a10cf76eSAxel Dörfler 			if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
238a10cf76eSAxel Dörfler 				BMessage message(ML_DEFAULTOUTPUT_CHANGE);
239a10cf76eSAxel Dörfler 
240a10cf76eSAxel Dörfler 				for (int32 i = 0; i < inputCount; i++) {
241a10cf76eSAxel Dörfler 					media_input *input = new media_input();
242a10cf76eSAxel Dörfler 					memcpy(input, &inputs[i], sizeof(*input));
243b4a12470SJérôme Duval 					fMenu3->AddItem(item = new Settings2Item(&info, input, new BMessage(message)));
244a10cf76eSAxel Dörfler 					if (inputs[i].destination.id == outputID)
245a10cf76eSAxel Dörfler 						item->SetMarked(true);
246a10cf76eSAxel Dörfler 				}
247a10cf76eSAxel Dörfler 			}
248a10cf76eSAxel Dörfler 		}
249a10cf76eSAxel Dörfler 	}
250a10cf76eSAxel Dörfler }
251a10cf76eSAxel Dörfler 
252a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info *info, BMessage *message,
253a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
254a10cf76eSAxel Dörfler 	: BMenuItem(info->name, message, shortcut, modifiers),
255b4a12470SJérôme Duval 	fInfo(info)
256a10cf76eSAxel Dörfler {
257a10cf76eSAxel Dörfler 
258a10cf76eSAxel Dörfler }
259a10cf76eSAxel Dörfler 
2606df0b2d5SJérôme Duval 
2616df0b2d5SJérôme Duval status_t
2626df0b2d5SJérôme Duval SettingsItem::Invoke(BMessage *message)
2636df0b2d5SJérôme Duval {
2646df0b2d5SJérôme Duval 	if (IsMarked())
2656df0b2d5SJérôme Duval 		return B_OK;
2666df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2676df0b2d5SJérôme Duval }
2686df0b2d5SJérôme Duval 
2696df0b2d5SJérôme Duval 
270a10cf76eSAxel Dörfler Settings2Item::Settings2Item(dormant_node_info *info, media_input *input, BMessage *message,
271a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
272a10cf76eSAxel Dörfler 	: BMenuItem(input->name, message, shortcut, modifiers),
273b4a12470SJérôme Duval 	fInfo(info),
274b4a12470SJérôme Duval 	fInput(input)
275a10cf76eSAxel Dörfler {
276a10cf76eSAxel Dörfler 
277a10cf76eSAxel Dörfler }
278a10cf76eSAxel Dörfler 
2796df0b2d5SJérôme Duval 
280a10cf76eSAxel Dörfler Settings2Item::~Settings2Item()
281a10cf76eSAxel Dörfler {
282b4a12470SJérôme Duval 	delete fInput;
283a10cf76eSAxel Dörfler }
284a10cf76eSAxel Dörfler 
2856df0b2d5SJérôme Duval 
2866df0b2d5SJérôme Duval status_t
2876df0b2d5SJérôme Duval Settings2Item::Invoke(BMessage *message)
2886df0b2d5SJérôme Duval {
2896df0b2d5SJérôme Duval 	if (IsMarked())
2906df0b2d5SJérôme Duval 		return B_OK;
2916df0b2d5SJérôme Duval 	return BMenuItem::Invoke(message);
2926df0b2d5SJérôme Duval }
2936df0b2d5SJérôme Duval 
294