2 * Copyright (c) 1999-2000, Eric Moon.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // ParameterWindow.cpp
34 #include "ParameterWindow.h"
36 #include "ParameterContainerView.h"
40 #include <Messenger.h>
47 #include <ScrollBar.h>
49 #include <MediaRoster.h>
50 #include <MediaTheme.h>
51 #include <ParameterWeb.h>
53 #include <FilePanel.h>
58 __USE_CORTEX_NAMESPACE
61 #define D_ALLOC(x) //PRINT (x)
62 #define D_HOOK(x) //PRINT (x)
63 #define D_INTERNAL(x) //PRINT (x)
64 #define D_MESSAGE(x) //PRINT (x)
66 // -------------------------------------------------------- //
68 // -------------------------------------------------------- //
70 ParameterWindow::ParameterWindow(
72 live_node_info
&nodeInfo
,
73 BMessenger
*notifyTarget
)
74 : BWindow(BRect(position
, position
+ BPoint(50.0, 50.0)),
75 "parameters", B_DOCUMENT_WINDOW
,
76 B_WILL_ACCEPT_FIRST_CLICK
| B_ASYNCHRONOUS_CONTROLS
),
77 m_node(nodeInfo
.node
),
82 D_ALLOC(("ParameterWindow::ParameterWindow()\n"));
84 // add the nodes name to the title
86 char* title
= new char[strlen(nodeInfo
.name
) + strlen(" parameters") + 1];
87 sprintf(title
, "%s parameters", nodeInfo
.name
);
92 BMenuBar
*menuBar
= new BMenuBar(Bounds(), "ParameterWindow MenuBar");
94 BMenu
*menu
= new BMenu("Window");
95 menu
->AddItem(new BMenuItem("Start control panel",
96 new BMessage(M_START_CONTROL_PANEL
),
97 'P', B_COMMAND_KEY
| B_SHIFT_KEY
));
98 menu
->AddSeparatorItem();
99 menu
->AddItem(new BMenuItem("Close",
100 new BMessage(B_QUIT_REQUESTED
),
101 'W', B_COMMAND_KEY
));
102 menuBar
->AddItem(menu
);
104 // future Media Theme selection capabilities go here
105 menu
= new BMenu("Themes");
106 BMessage
*message
= new BMessage(M_THEME_SELECTED
);
107 BMediaTheme
*theme
= BMediaTheme::PreferredTheme();
108 message
->AddInt32("themeID", theme
->ID());
109 BMenuItem
*item
= new BMenuItem(theme
->Name(), message
);
110 item
->SetMarked(true);
112 menuBar
->AddItem(menu
);
115 _updateParameterView();
118 // start watching for parameter web changes
119 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
120 roster
->StartWatching(this, nodeInfo
.node
, B_MEDIA_WILDCARD
);
123 m_notifyTarget
= new BMessenger(*notifyTarget
);
127 ParameterWindow::~ParameterWindow() {
128 D_ALLOC(("ParameterWindow::~ParameterWindow()\n"));
130 if (m_notifyTarget
) {
131 delete m_notifyTarget
;
135 // -------------------------------------------------------- //
137 // -------------------------------------------------------- //
139 void ParameterWindow::FrameResized(
142 D_HOOK(("ParameterWindow::FrameResized()\n"));
152 void ParameterWindow::MessageReceived(
154 D_MESSAGE(("ParameterWindow::MessageReceived()\n"));
156 switch (message
->what
) {
157 case M_START_CONTROL_PANEL
: {
158 D_MESSAGE((" -> M_START_CONTROL_PANEL\n"));
159 status_t error
= _startControlPanel();
161 BString s
= "Could not start control panel";
162 s
<< " (" << strerror(error
) << ")";
163 BAlert
*alert
= new BAlert("", s
.String(), "OK", 0, 0,
164 B_WIDTH_AS_USUAL
, B_WARNING_ALERT
);
165 alert
->SetFlags(alert
->Flags() | B_CLOSE_ON_ESCAPE
);
168 bool replace
= false;
169 if ((message
->FindBool("replace", &replace
) == B_OK
)
170 && (replace
== true)) {
171 PostMessage(B_QUIT_REQUESTED
);
175 case M_THEME_SELECTED
: {
176 D_MESSAGE((" -> M_THEME_SELECTED\n"));
178 if (message
->FindInt32("themeID", &themeID
) != B_OK
) {
181 // not yet implemented
184 case B_MEDIA_WEB_CHANGED
: {
185 D_MESSAGE((" -> B_MEDIA_WEB_CHANGED\n"));
186 _updateParameterView();
187 _constrainToScreen();
191 BWindow::MessageReceived(message
);
196 bool ParameterWindow::QuitRequested() {
197 D_HOOK(("ParameterWindow::QuitRequested()\n"));
199 // stop watching the MediaRoster
200 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
202 roster
->StopWatching(this, m_node
, B_MEDIA_WILDCARD
);
205 // tell the notification target to forget about us
206 if (m_notifyTarget
&& m_notifyTarget
->IsValid()) {
207 BMessage
message(M_CLOSED
);
208 message
.AddInt32("nodeID", m_node
.node
);
209 status_t error
= m_notifyTarget
->SendMessage(&message
);
211 D_HOOK((" -> error sending message (%s) !\n", strerror(error
)));
218 void ParameterWindow::Zoom(
222 D_HOOK(("ParameterWindow::Zoom()\n"));
226 BScreen
screen(this);
227 if (!screen
.Frame().Contains(Frame())) {
232 // resize to the ideal size
233 m_manualSize
= Bounds();
234 ResizeTo(m_idealSize
.Width(), m_idealSize
.Height());
235 _constrainToScreen();
239 // resize to the most recent manual size
240 ResizeTo(m_manualSize
.Width(), m_manualSize
.Height());
245 // -------------------------------------------------------- //
246 // internal operations
247 // -------------------------------------------------------- //
249 void ParameterWindow::_init() {
250 D_INTERNAL(("ParameterWindow::_init()\n"));
252 // offset to a new position
253 _constrainToScreen();
254 m_manualSize
= Bounds().OffsetToCopy(0.0, 0.0);
256 // add the hidden option to close this window when the
257 // control panel has been started successfully
258 BMessage
*message
= new BMessage(M_START_CONTROL_PANEL
);
259 message
->AddBool("replace", true);
260 AddShortcut('P', B_COMMAND_KEY
| B_SHIFT_KEY
| B_OPTION_KEY
,
264 void ParameterWindow::_updateParameterView(
265 BMediaTheme
*theme
) {
266 D_INTERNAL(("ParameterWindow::_updateParameterView()\n"));
268 // clear the old version
270 ParameterContainerView
*view
= dynamic_cast<ParameterContainerView
*>(FindView("ParameterContainerView"));
277 // fetch ParameterWeb from the MediaRoster
278 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
281 status_t error
= roster
->GetParameterWebFor(m_node
, &web
);
282 if (!error
&& (web
->CountParameters() || web
->CountGroups())) {
283 // if no theme was specified, use the preferred theme
285 theme
= BMediaTheme::PreferredTheme();
288 m_parameters
= BMediaTheme::ViewFor(web
, 0, theme
);
290 BMenuBar
*menuBar
= KeyMenuBar();
291 m_idealSize
= m_parameters
->Bounds();
292 m_idealSize
.right
+= B_V_SCROLL_BAR_WIDTH
;
293 m_idealSize
.bottom
+= B_H_SCROLL_BAR_HEIGHT
;
295 m_parameters
->MoveTo(0.0, menuBar
->Bounds().bottom
+ 1.0);
296 m_idealSize
.bottom
+= menuBar
->Bounds().bottom
+ 1.0;
302 // limit min size to avoid funny-looking scrollbars
303 float hMin
= B_V_SCROLL_BAR_WIDTH
*6, vMin
= B_H_SCROLL_BAR_HEIGHT
*3;
304 // limit max size to full extents of the parameter view
305 float hMax
= m_idealSize
.Width(), vMax
= m_idealSize
.Height();
306 SetSizeLimits(hMin
, hMax
, vMin
, vMax
);
308 // adapt the window to the new dimensions
309 ResizeTo(m_idealSize
.Width(), m_idealSize
.Height());
313 BRect paramRect
= m_parameters
->Bounds();
314 AddChild(new ParameterContainerView(paramRect
, m_parameters
));
318 void ParameterWindow::_constrainToScreen() {
319 D_INTERNAL(("ParameterWindow::_constrainToScreen()\n"));
321 BScreen
screen(this);
322 BRect screenRect
= screen
.Frame();
323 BRect windowRect
= Frame();
325 // if the window is outside the screen rect
326 // move it to the default position
327 if (!screenRect
.Intersects(windowRect
)) {
328 windowRect
.OffsetTo(screenRect
.LeftTop());
329 MoveTo(windowRect
.LeftTop());
330 windowRect
= Frame();
333 // if the window is larger than the screen rect
334 // resize it to fit at each side
335 if (!screenRect
.Contains(windowRect
)) {
336 if (windowRect
.left
< screenRect
.left
) {
337 windowRect
.left
= screenRect
.left
+ 5.0;
338 MoveTo(windowRect
.LeftTop());
339 windowRect
= Frame();
341 if (windowRect
.top
< screenRect
.top
) {
342 windowRect
.top
= screenRect
.top
+ 5.0;
343 MoveTo(windowRect
.LeftTop());
344 windowRect
= Frame();
346 if (windowRect
.right
> screenRect
.right
) {
347 windowRect
.right
= screenRect
.right
- 5.0;
349 if (windowRect
.bottom
> screenRect
.bottom
) {
350 windowRect
.bottom
= screenRect
.bottom
- 5.0;
352 ResizeTo(windowRect
.Width(), windowRect
.Height());
356 status_t
ParameterWindow::_startControlPanel() {
357 D_INTERNAL(("ParameterWindow::_startControlPanel()\n"));
359 // get roster instance
360 BMediaRoster
*roster
= BMediaRoster::CurrentRoster();
362 D_INTERNAL((" -> MediaRoster not available\n"));
366 // try to StartControlPanel()
367 BMessenger messenger
;
368 status_t error
= roster
->StartControlPanel(m_node
, &messenger
);
370 D_INTERNAL((" -> StartControlPanel() failed (%s)\n", strerror(error
)));
374 // notify the notification target, if any
375 if (m_notifyTarget
) {
376 BMessage
message(M_CONTROL_PANEL_STARTED
);
377 message
.AddInt32("nodeID", m_node
.node
);
378 message
.AddMessenger("messenger", messenger
);
379 error
= m_notifyTarget
->SendMessage(&message
);
381 D_INTERNAL((" -> failed to notify target\n"));
388 // END -- ParameterWindow.cpp --