xref: /haiku/src/preferences/media/MediaViews.cpp (revision b4a124700c73ba45cb0e323ffbc17d08669936c3)
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>
28*b4a12470SJérôme Duval #include <TextView.h>
29a10cf76eSAxel Dörfler #include "MediaViews.h"
30a10cf76eSAxel Dörfler 
31a10cf76eSAxel Dörfler BarView::BarView(BRect frame)
32a10cf76eSAxel Dörfler  : BView (frame, "barView", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW ),
33*b4a12470SJérôme Duval  	fDisplay(true)
34a10cf76eSAxel Dörfler {
35a10cf76eSAxel Dörfler }
36a10cf76eSAxel Dörfler 
37a10cf76eSAxel Dörfler void
38a10cf76eSAxel Dörfler BarView::Draw(BRect updateRect)
39a10cf76eSAxel Dörfler {
40a10cf76eSAxel Dörfler 	BRect r = Bounds();
41a10cf76eSAxel Dörfler 
42*b4a12470SJérôme Duval 	if(fDisplay) {
43a10cf76eSAxel Dörfler 		// Display the 3D Look Divider Bar
44a10cf76eSAxel Dörfler 		SetHighColor(140,140,140,0);
45a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
46a10cf76eSAxel Dörfler 		SetHighColor(255,255,255,0);
47a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
48a10cf76eSAxel Dörfler 	} else {
49a10cf76eSAxel Dörfler 		SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
50a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.top),BPoint(r.right,r.top));
51a10cf76eSAxel Dörfler 		StrokeLine(BPoint(r.left,r.bottom),BPoint(r.right,r.bottom));
52a10cf76eSAxel Dörfler 	}
53a10cf76eSAxel Dörfler }
54a10cf76eSAxel Dörfler 
55a10cf76eSAxel Dörfler 
56a10cf76eSAxel Dörfler SettingsView::SettingsView (BRect frame, bool isVideo)
57a10cf76eSAxel Dörfler  : BView (frame, "SettingsView", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW ),
58*b4a12470SJérôme Duval  	fIsVideo(isVideo)
59a10cf76eSAxel Dörfler {
60a10cf76eSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
61a10cf76eSAxel Dörfler 	BRect rect(frame);
62a10cf76eSAxel Dörfler 	rect.left += 10;
63a10cf76eSAxel Dörfler 	rect.top += 12;
64a10cf76eSAxel Dörfler 	rect.right -=21;
65a10cf76eSAxel Dörfler 	rect.bottom = rect.top + 104;
66a10cf76eSAxel Dörfler 	BBox *defaultsBox = new BBox(rect, "defaults");
67*b4a12470SJérôme Duval 	defaultsBox->SetLabel(fIsVideo ? "Default Nodes" : "Defaults");
68a10cf76eSAxel Dörfler 	AddChild(defaultsBox);
69a10cf76eSAxel Dörfler 
70a10cf76eSAxel Dörfler 	BRect defaultRect(20, 22, 250, 40);
71*b4a12470SJérôme Duval 	float divider = StringWidth(fIsVideo ? "Video Output:" : "Audio Output:") + 5;
72*b4a12470SJérôme Duval 	fMenu1 = new BPopUpMenu("<none>");
73*b4a12470SJérôme Duval 	fMenu1->SetLabelFromMarked(true);
74a10cf76eSAxel Dörfler 	BMenuField *menuField1 = new BMenuField(defaultRect, "menuField1",
75*b4a12470SJérôme Duval 		fIsVideo ? "Video Input:" : "Audio Input:", fMenu1);
76a10cf76eSAxel Dörfler 	defaultsBox->AddChild(menuField1);
77aaa9b739SJérôme Duval 	menuField1->SetDivider(divider);
78a10cf76eSAxel Dörfler 
79a10cf76eSAxel Dörfler 	defaultRect.OffsetBy(0, 26);
80*b4a12470SJérôme Duval 	fMenu2 = new BPopUpMenu("<none>");
81*b4a12470SJérôme Duval 	fMenu2->SetLabelFromMarked(true);
82a10cf76eSAxel Dörfler 	BMenuField *menuField2 = new BMenuField(defaultRect, "menuField2",
83*b4a12470SJérôme Duval 		fIsVideo ? "Video Output:" : "Audio Output:", fMenu2);
84a10cf76eSAxel Dörfler 	defaultsBox->AddChild(menuField2);
85aaa9b739SJérôme Duval 	menuField2->SetDivider(divider);
86a10cf76eSAxel Dörfler 
87*b4a12470SJérôme Duval 	if(!fIsVideo) {
88a10cf76eSAxel Dörfler 		defaultRect.OffsetBy(186, 0);
89*b4a12470SJérôme Duval 		defaultRect.right -= 30;
90*b4a12470SJérôme Duval 		fMenu3 = new BPopUpMenu("<none>");
91*b4a12470SJérôme Duval 		fMenu3->SetLabelFromMarked(true);
92*b4a12470SJérôme Duval 		BMenuField *menuField3 = new BMenuField(defaultRect, "menuField3",
93*b4a12470SJérôme Duval 			"Channel:", fMenu3);
94*b4a12470SJérôme Duval 		defaultsBox->AddChild(menuField3);
95*b4a12470SJérôme Duval 		menuField3->SetDivider(StringWidth("Channel:")+5);
96*b4a12470SJérôme Duval 		defaultRect.right += 30;
97a10cf76eSAxel Dörfler 		defaultRect.OffsetBy(-186, 0);
98a10cf76eSAxel Dörfler 	}
99a10cf76eSAxel Dörfler 
100a10cf76eSAxel Dörfler 	defaultRect.OffsetBy(0, 32);
101*b4a12470SJérôme Duval 	defaultRect.right += 100;
102a10cf76eSAxel Dörfler 	rgb_color red_color = {222, 32, 33};
103*b4a12470SJérôme Duval 	fRestartView = new BStringView(defaultRect, "restartStringView", "Restart the Media Server to apply changes.",
104*b4a12470SJérôme Duval 		B_FOLLOW_ALL, B_WILL_DRAW);
105*b4a12470SJérôme Duval 	fRestartView->SetHighColor(red_color);
106*b4a12470SJérôme Duval 	defaultsBox->AddChild(fRestartView);
107*b4a12470SJérôme Duval 	fRestartView->Hide();
108a10cf76eSAxel Dörfler 
109a10cf76eSAxel Dörfler 	rect.top = rect.bottom + 10;
110a10cf76eSAxel Dörfler 	rect.bottom = rect.top + 162;
111a10cf76eSAxel Dörfler 	BBox *realtimeBox = new BBox(rect, "realtime");
112a10cf76eSAxel Dörfler 	realtimeBox->SetLabel("Real-Time");
113a10cf76eSAxel Dörfler 	AddChild(realtimeBox);
114a10cf76eSAxel Dörfler 
115a10cf76eSAxel Dörfler 	BMessage *message = new BMessage(ML_ENABLE_REAL_TIME);
116*b4a12470SJérôme Duval 	message->AddBool("isVideo", fIsVideo);
117a10cf76eSAxel Dörfler 	BRect rect2(22,20, 190, 40);
118*b4a12470SJérôme Duval 	fRealtimeCheckBox = new BCheckBox(rect2, "realtimeCheckBox",
119*b4a12470SJérôme Duval 		fIsVideo ? "Enable Real-Time Video" : "Enable Real-Time Audio", message);
120*b4a12470SJérôme Duval 	realtimeBox->AddChild(fRealtimeCheckBox);
121a10cf76eSAxel Dörfler 
122a10cf76eSAxel Dörfler 	uint32 flags;
123a10cf76eSAxel Dörfler 	BMediaRoster::Roster()->GetRealtimeFlags(&flags);
124*b4a12470SJérôme Duval 	if(flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
125*b4a12470SJérôme Duval 		fRealtimeCheckBox->SetValue(B_CONTROL_ON);
126a10cf76eSAxel Dörfler 
127a10cf76eSAxel Dörfler 	rect2.top += 26;
1285ffd43dcSJérôme Duval 	rect2.bottom = rect.Height() - 5;
129a10cf76eSAxel Dörfler 	rect2.right = rect.right - 15;
130a10cf76eSAxel Dörfler 	BRect textRect(3, 3, rect2.Width() - 3, rect2.Height() - 3);
131*b4a12470SJérôme Duval 	BTextView *textView = new BTextView(rect2, "stringView", textRect, B_FOLLOW_ALL, B_WILL_DRAW);
132*b4a12470SJérôme Duval 	textView->Insert(fIsVideo ? "Enabling Real-Time Video allows the BeOS to perform video operations as fast and smoothly as possible.  It achieves optimum performance by using more RAM."
133*b4a12470SJérôme Duval 		"\n\nOnly enable this feature if you need the lowest latency possible."
134*b4a12470SJérôme Duval 		: "Enabling Real-time Audio allows BeOS to record and play audio as fast as possible.  It achieves this performance by using more CPU and RAM."
135*b4a12470SJérôme Duval 		"\n\nOnly enable this feature if you need the lowest latency possible.");
136*b4a12470SJérôme Duval 	textView->MakeEditable(false);
137*b4a12470SJérôme Duval 	textView->MakeSelectable(false);
138a10cf76eSAxel Dörfler 	textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
139a10cf76eSAxel Dörfler 	realtimeBox->AddChild(textView);
140a10cf76eSAxel Dörfler 
141a10cf76eSAxel Dörfler 	rect.top = rect.bottom + 11;
142a10cf76eSAxel Dörfler 	rect.bottom = rect.top + 20;
143aaa9b739SJérôme Duval 	rect.left = rect.right - StringWidth("Restart Media Services") - 20;
144a10cf76eSAxel Dörfler 	BButton *restartButton = new BButton(rect, "restartButton",
145a10cf76eSAxel Dörfler 		"Restart Media Services", new BMessage(ML_RESTART_MEDIA_SERVER));
146a10cf76eSAxel Dörfler 	AddChild(restartButton);
147a10cf76eSAxel Dörfler 
148*b4a12470SJérôme Duval 	if(!fIsVideo) {
149*b4a12470SJérôme Duval 		rect.right = rect.left - 10;
150a10cf76eSAxel Dörfler 		rect.top += 4;
151a10cf76eSAxel Dörfler 		rect.left = frame.left + 33;
152*b4a12470SJérôme Duval 		if (StringWidth("Show Volume Control on Deskbar") > rect.Width() - 30)
153*b4a12470SJérôme Duval 			rect.left -= 10;
154a10cf76eSAxel Dörfler 
155*b4a12470SJérôme Duval 		fVolumeCheckBox = new BCheckBox(rect, "volumeCheckBox",
156a10cf76eSAxel Dörfler 			"Show Volume Control on Deskbar", new BMessage(ML_SHOW_VOLUME_CONTROL));
157*b4a12470SJérôme Duval 		AddChild(fVolumeCheckBox);
158a10cf76eSAxel Dörfler 
159a10cf76eSAxel Dörfler 		if(BDeskbar().HasItem("MediaReplicant"))
160*b4a12470SJérôme Duval 			fVolumeCheckBox->SetValue(B_CONTROL_ON);
161a10cf76eSAxel Dörfler 	}
162a10cf76eSAxel Dörfler }
163a10cf76eSAxel Dörfler 
164a10cf76eSAxel Dörfler void
165a10cf76eSAxel Dörfler SettingsView::AddNodes(BList &list, bool isInput)
166a10cf76eSAxel Dörfler {
167*b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
168a10cf76eSAxel Dörfler 	void *item;
169a10cf76eSAxel Dörfler 	while ((item = menu->RemoveItem((int32)0)) != NULL)
170a10cf76eSAxel Dörfler 		delete static_cast<dormant_node_info *>(item);
171a10cf76eSAxel Dörfler 
172a10cf76eSAxel Dörfler 	BMessage message(ML_DEFAULT_CHANGE);
173*b4a12470SJérôme Duval 	message.AddBool("isVideo", fIsVideo);
174a10cf76eSAxel Dörfler 	message.AddBool("isInput", isInput);
175a10cf76eSAxel Dörfler 
176a10cf76eSAxel Dörfler 	for (int32 i = 0; i < list.CountItems(); i++) {
177a10cf76eSAxel Dörfler 		dormant_node_info *info = static_cast<dormant_node_info *>(list.ItemAt(i));
178a10cf76eSAxel Dörfler 		menu->AddItem(new SettingsItem(info, new BMessage(message)));
179a10cf76eSAxel Dörfler 	}
180a10cf76eSAxel Dörfler }
181a10cf76eSAxel Dörfler 
182a10cf76eSAxel Dörfler void
183a10cf76eSAxel Dörfler SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
184a10cf76eSAxel Dörfler {
185*b4a12470SJérôme Duval 	BMenu *menu = isInput ? fMenu1 : fMenu2;
186a10cf76eSAxel Dörfler 
187a10cf76eSAxel Dörfler 	for (int32 i = 0; i < menu->CountItems(); i++) {
188a10cf76eSAxel Dörfler 		SettingsItem *item = static_cast<SettingsItem *>(menu->ItemAt(i));
189*b4a12470SJérôme Duval 		if(item->fInfo && item->fInfo->addon == info.addon && item->fInfo->flavor_id == info.flavor_id) {
190a10cf76eSAxel Dörfler 			item->SetMarked(true);
191a10cf76eSAxel Dörfler 			break;
192a10cf76eSAxel Dörfler 		}
193a10cf76eSAxel Dörfler 	}
194a10cf76eSAxel Dörfler 
195*b4a12470SJérôme Duval 	if (!fIsVideo&&!isInput&&outputID>-1) {
196a10cf76eSAxel Dörfler 		BMenuItem *item;
197*b4a12470SJérôme Duval 		while ((item = fMenu3->RemoveItem((int32)0)) != NULL)
198a10cf76eSAxel Dörfler 			delete item;
199a10cf76eSAxel Dörfler 		BMediaRoster *roster = BMediaRoster::Roster();
200a10cf76eSAxel Dörfler 		media_node node;
201a10cf76eSAxel Dörfler 		media_node_id node_id;
202a10cf76eSAxel Dörfler 		status_t err;
203a10cf76eSAxel Dörfler 		if (roster->GetInstancesFor(info.addon, info.flavor_id, &node_id)!=B_OK)
204a10cf76eSAxel Dörfler 			err = roster->InstantiateDormantNode(info, &node, B_FLAVOR_IS_GLOBAL);
205a10cf76eSAxel Dörfler 		else
206a10cf76eSAxel Dörfler 			err = roster->GetNodeFor(node_id, &node);
207a10cf76eSAxel Dörfler 
208a10cf76eSAxel Dörfler 		if (err == B_OK) {
209a10cf76eSAxel Dörfler 			media_input inputs[16];
210a10cf76eSAxel Dörfler 			int32 inputCount = 16;
211a10cf76eSAxel Dörfler 			if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
212a10cf76eSAxel Dörfler 				BMessage message(ML_DEFAULTOUTPUT_CHANGE);
213a10cf76eSAxel Dörfler 
214a10cf76eSAxel Dörfler 				for (int32 i = 0; i < inputCount; i++) {
215a10cf76eSAxel Dörfler 					media_input *input = new media_input();
216a10cf76eSAxel Dörfler 					memcpy(input, &inputs[i], sizeof(*input));
217*b4a12470SJérôme Duval 					fMenu3->AddItem(item = new Settings2Item(&info, input, new BMessage(message)));
218a10cf76eSAxel Dörfler 					if(inputs[i].destination.id == outputID)
219a10cf76eSAxel Dörfler 						item->SetMarked(true);
220a10cf76eSAxel Dörfler 				}
221a10cf76eSAxel Dörfler 			}
222a10cf76eSAxel Dörfler 		}
223a10cf76eSAxel Dörfler 	}
224a10cf76eSAxel Dörfler }
225a10cf76eSAxel Dörfler 
226a10cf76eSAxel Dörfler SettingsItem::SettingsItem(dormant_node_info *info, BMessage *message,
227a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
228a10cf76eSAxel Dörfler 	: BMenuItem(info->name, message, shortcut, modifiers),
229*b4a12470SJérôme Duval 	fInfo(info)
230a10cf76eSAxel Dörfler {
231a10cf76eSAxel Dörfler 
232a10cf76eSAxel Dörfler }
233a10cf76eSAxel Dörfler 
234a10cf76eSAxel Dörfler Settings2Item::Settings2Item(dormant_node_info *info, media_input *input, BMessage *message,
235a10cf76eSAxel Dörfler 			char shortcut, uint32 modifiers)
236a10cf76eSAxel Dörfler 	: BMenuItem(input->name, message, shortcut, modifiers),
237*b4a12470SJérôme Duval 	fInfo(info),
238*b4a12470SJérôme Duval 	fInput(input)
239a10cf76eSAxel Dörfler {
240a10cf76eSAxel Dörfler 
241a10cf76eSAxel Dörfler }
242a10cf76eSAxel Dörfler 
243a10cf76eSAxel Dörfler Settings2Item::~Settings2Item()
244a10cf76eSAxel Dörfler {
245*b4a12470SJérôme Duval 	delete fInput;
246a10cf76eSAxel Dörfler }
247a10cf76eSAxel Dörfler 
248