xref: /haiku/src/preferences/media/MediaViews.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
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 Settings2Item::Settings2Item(dormant_node_info *info, media_input *input, BMessage *message,
235 			char shortcut, uint32 modifiers)
236 	: BMenuItem(input->name, message, shortcut, modifiers),
237 	fInfo(info),
238 	fInput(input)
239 {
240 
241 }
242 
243 Settings2Item::~Settings2Item()
244 {
245 	delete fInput;
246 }
247 
248