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