btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / cortex / ParameterView / ParameterWindow.cpp
blob8a8b963636cdb4258f3ad51d98054f50ec3c9e61
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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"
35 // ParameterWindow
36 #include "ParameterContainerView.h"
38 // Application Kit
39 #include <Message.h>
40 #include <Messenger.h>
41 // Interface Kit
42 #include <Alert.h>
43 #include <Menu.h>
44 #include <MenuBar.h>
45 #include <MenuItem.h>
46 #include <Screen.h>
47 #include <ScrollBar.h>
48 // Media Kit
49 #include <MediaRoster.h>
50 #include <MediaTheme.h>
51 #include <ParameterWeb.h>
52 // Storage Kit
53 #include <FilePanel.h>
54 #include <Path.h>
55 // Support Kit
56 #include <String.h>
58 __USE_CORTEX_NAMESPACE
60 #include <Debug.h>
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 // -------------------------------------------------------- //
67 // ctor/dtor
68 // -------------------------------------------------------- //
70 ParameterWindow::ParameterWindow(
71 BPoint position,
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),
78 m_parameters(0),
79 m_notifyTarget(0),
80 m_zoomed(false),
81 m_zooming(false) {
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);
88 SetTitle(title);
89 delete [] title;
91 // add the menu bar
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);
111 menu->AddItem(item);
112 menuBar->AddItem(menu);
113 AddChild(menuBar);
115 _updateParameterView();
116 _init();
118 // start watching for parameter web changes
119 BMediaRoster *roster = BMediaRoster::CurrentRoster();
120 roster->StartWatching(this, nodeInfo.node, B_MEDIA_WILDCARD);
122 if (notifyTarget) {
123 m_notifyTarget = new BMessenger(*notifyTarget);
127 ParameterWindow::~ParameterWindow() {
128 D_ALLOC(("ParameterWindow::~ParameterWindow()\n"));
130 if (m_notifyTarget) {
131 delete m_notifyTarget;
135 // -------------------------------------------------------- //
136 // BWindow impl
137 // -------------------------------------------------------- //
139 void ParameterWindow::FrameResized(
140 float width,
141 float height) {
142 D_HOOK(("ParameterWindow::FrameResized()\n"));
144 if (!m_zooming) {
145 m_zoomed = false;
147 else {
148 m_zooming = false;
152 void ParameterWindow::MessageReceived(
153 BMessage *message) {
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();
160 if (error) {
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);
166 alert->Go(0);
168 bool replace = false;
169 if ((message->FindBool("replace", &replace) == B_OK)
170 && (replace == true)) {
171 PostMessage(B_QUIT_REQUESTED);
173 break;
175 case M_THEME_SELECTED: {
176 D_MESSAGE((" -> M_THEME_SELECTED\n"));
177 int32 themeID;
178 if (message->FindInt32("themeID", &themeID) != B_OK) {
179 return;
181 // not yet implemented
182 break;
184 case B_MEDIA_WEB_CHANGED: {
185 D_MESSAGE((" -> B_MEDIA_WEB_CHANGED\n"));
186 _updateParameterView();
187 _constrainToScreen();
188 break;
190 default: {
191 BWindow::MessageReceived(message);
196 bool ParameterWindow::QuitRequested() {
197 D_HOOK(("ParameterWindow::QuitRequested()\n"));
199 // stop watching the MediaRoster
200 BMediaRoster *roster = BMediaRoster::CurrentRoster();
201 if (roster) {
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);
210 if (error) {
211 D_HOOK((" -> error sending message (%s) !\n", strerror(error)));
215 return true;
218 void ParameterWindow::Zoom(
219 BPoint origin,
220 float width,
221 float height) {
222 D_HOOK(("ParameterWindow::Zoom()\n"));
224 m_zooming = true;
226 BScreen screen(this);
227 if (!screen.Frame().Contains(Frame())) {
228 m_zoomed = false;
231 if (!m_zoomed) {
232 // resize to the ideal size
233 m_manualSize = Bounds();
234 ResizeTo(m_idealSize.Width(), m_idealSize.Height());
235 _constrainToScreen();
236 m_zoomed = true;
238 else {
239 // resize to the most recent manual size
240 ResizeTo(m_manualSize.Width(), m_manualSize.Height());
241 m_zoomed = false;
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,
261 message);
264 void ParameterWindow::_updateParameterView(
265 BMediaTheme *theme) {
266 D_INTERNAL(("ParameterWindow::_updateParameterView()\n"));
268 // clear the old version
269 if (m_parameters) {
270 ParameterContainerView *view = dynamic_cast<ParameterContainerView *>(FindView("ParameterContainerView"));
271 RemoveChild(view);
272 delete m_parameters;
273 m_parameters = 0;
274 delete view;
277 // fetch ParameterWeb from the MediaRoster
278 BMediaRoster *roster = BMediaRoster::CurrentRoster();
279 if (roster) {
280 BParameterWeb *web;
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
284 if (!theme) {
285 theme = BMediaTheme::PreferredTheme();
287 // acquire the view
288 m_parameters = BMediaTheme::ViewFor(web, 0, theme);
289 if (m_parameters) {
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;
294 if (menuBar) {
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());
310 m_zoomed = true;
312 if (m_parameters) {
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();
361 if (!roster) {
362 D_INTERNAL((" -> MediaRoster not available\n"));
363 return B_ERROR;
366 // try to StartControlPanel()
367 BMessenger messenger;
368 status_t error = roster->StartControlPanel(m_node, &messenger);
369 if (error) {
370 D_INTERNAL((" -> StartControlPanel() failed (%s)\n", strerror(error)));
371 return 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);
380 if (error) {
381 D_INTERNAL((" -> failed to notify target\n"));
385 return B_OK;
388 // END -- ParameterWindow.cpp --