/* * Copyright (c) 1999-2000, Eric Moon. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions, and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ParameterWindow.cpp #include "ParameterWindow.h" // ParameterWindow #include "ParameterContainerView.h" // Application Kit #include #include // Interface Kit #include #include #include #include #include #include // Media Kit #include #include #include // Storage Kit #include #include // Support Kit #include // Locale Kit #undef B_CATALOG #define B_CATALOG (&sCatalog) #include #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "ParameterWindow" __USE_CORTEX_NAMESPACE #include #define D_ALLOC(x) //PRINT (x) #define D_HOOK(x) //PRINT (x) #define D_INTERNAL(x) //PRINT (x) #define D_MESSAGE(x) //PRINT (x) static BCatalog sCatalog("x-vnd.Cortex.ParameterView"); // -------------------------------------------------------- // // ctor/dtor // -------------------------------------------------------- // ParameterWindow::ParameterWindow( BPoint position, live_node_info &nodeInfo, BMessenger *notifyTarget) : BWindow(BRect(position, position + BPoint(50.0, 50.0)), "parameters", B_DOCUMENT_WINDOW, B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS), m_node(nodeInfo.node), m_parameters(0), m_notifyTarget(0), m_zoomed(false), m_zooming(false) { D_ALLOC(("ParameterWindow::ParameterWindow()\n")); // add the nodes name to the title { BString title = B_TRANSLATE("%nodeinfo% parameters"); title.ReplaceFirst("%nodeinfo%", nodeInfo.name); SetTitle(title); } // add the menu bar BMenuBar *menuBar = new BMenuBar(Bounds(), "ParameterWindow MenuBar"); BMenu *menu = new BMenu(B_TRANSLATE("Window")); menu->AddItem(new BMenuItem(B_TRANSLATE("Start control panel"), new BMessage(M_START_CONTROL_PANEL), 'P', B_COMMAND_KEY | B_SHIFT_KEY)); menu->AddSeparatorItem(); menu->AddItem(new BMenuItem(B_TRANSLATE("Close"), new BMessage(B_QUIT_REQUESTED), 'W', B_COMMAND_KEY)); menuBar->AddItem(menu); // future Media Theme selection capabilities go here menu = new BMenu(B_TRANSLATE("Themes")); BMessage *message = new BMessage(M_THEME_SELECTED); BMediaTheme *theme = BMediaTheme::PreferredTheme(); message->AddInt32("themeID", theme->ID()); BMenuItem *item = new BMenuItem(theme->Name(), message); item->SetMarked(true); menu->AddItem(item); menuBar->AddItem(menu); AddChild(menuBar); _updateParameterView(); _init(); // start watching for parameter web changes BMediaRoster *roster = BMediaRoster::CurrentRoster(); roster->StartWatching(this, nodeInfo.node, B_MEDIA_WILDCARD); if (notifyTarget) { m_notifyTarget = new BMessenger(*notifyTarget); } } ParameterWindow::~ParameterWindow() { D_ALLOC(("ParameterWindow::~ParameterWindow()\n")); if (m_notifyTarget) { delete m_notifyTarget; } } // -------------------------------------------------------- // // BWindow impl // -------------------------------------------------------- // void ParameterWindow::FrameResized( float width, float height) { D_HOOK(("ParameterWindow::FrameResized()\n")); if (!m_zooming) { m_zoomed = false; } else { m_zooming = false; } } void ParameterWindow::MessageReceived( BMessage *message) { D_MESSAGE(("ParameterWindow::MessageReceived()\n")); switch (message->what) { case M_START_CONTROL_PANEL: { D_MESSAGE((" -> M_START_CONTROL_PANEL\n")); status_t error = _startControlPanel(); if (error) { BString s = B_TRANSLATE( "Could not start control panel (%error%)"); s.ReplaceFirst("%error%", strerror(error)); BAlert *alert = new BAlert("", s.String(), B_TRANSLATE("OK"), 0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT); alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); alert->Go(0); } bool replace = false; if ((message->FindBool("replace", &replace) == B_OK) && (replace == true)) { PostMessage(B_QUIT_REQUESTED); } break; } case M_THEME_SELECTED: { D_MESSAGE((" -> M_THEME_SELECTED\n")); int32 themeID; if (message->FindInt32("themeID", &themeID) != B_OK) { return; } // not yet implemented break; } case B_MEDIA_WEB_CHANGED: { D_MESSAGE((" -> B_MEDIA_WEB_CHANGED\n")); _updateParameterView(); _constrainToScreen(); break; } default: { BWindow::MessageReceived(message); } } } bool ParameterWindow::QuitRequested() { D_HOOK(("ParameterWindow::QuitRequested()\n")); // stop watching the MediaRoster BMediaRoster *roster = BMediaRoster::CurrentRoster(); if (roster) { roster->StopWatching(this, m_node, B_MEDIA_WILDCARD); } // tell the notification target to forget about us if (m_notifyTarget && m_notifyTarget->IsValid()) { BMessage message(M_CLOSED); message.AddInt32("nodeID", m_node.node); status_t error = m_notifyTarget->SendMessage(&message); if (error) { D_HOOK((" -> error sending message (%s) !\n", strerror(error))); } } return true; } void ParameterWindow::Zoom( BPoint origin, float width, float height) { D_HOOK(("ParameterWindow::Zoom()\n")); m_zooming = true; BScreen screen(this); if (!screen.Frame().Contains(Frame())) { m_zoomed = false; } if (!m_zoomed) { // resize to the ideal size m_manualSize = Bounds(); ResizeTo(m_idealSize.Width(), m_idealSize.Height()); _constrainToScreen(); m_zoomed = true; } else { // resize to the most recent manual size ResizeTo(m_manualSize.Width(), m_manualSize.Height()); m_zoomed = false; } } // -------------------------------------------------------- // // internal operations // -------------------------------------------------------- // void ParameterWindow::_init() { D_INTERNAL(("ParameterWindow::_init()\n")); // offset to a new position _constrainToScreen(); m_manualSize = Bounds().OffsetToCopy(0.0, 0.0); // add the hidden option to close this window when the // control panel has been started successfully BMessage *message = new BMessage(M_START_CONTROL_PANEL); message->AddBool("replace", true); AddShortcut('P', B_COMMAND_KEY | B_SHIFT_KEY | B_OPTION_KEY, message); } void ParameterWindow::_updateParameterView( BMediaTheme *theme) { D_INTERNAL(("ParameterWindow::_updateParameterView()\n")); // clear the old version if (m_parameters) { ParameterContainerView *view = dynamic_cast(FindView("ParameterContainerView")); RemoveChild(view); delete m_parameters; m_parameters = 0; delete view; } // fetch ParameterWeb from the MediaRoster BMediaRoster *roster = BMediaRoster::CurrentRoster(); if (roster) { BParameterWeb *web; status_t error = roster->GetParameterWebFor(m_node, &web); if (!error && (web->CountParameters() || web->CountGroups())) { // if no theme was specified, use the preferred theme if (!theme) { theme = BMediaTheme::PreferredTheme(); } // acquire the view m_parameters = BMediaTheme::ViewFor(web, 0, theme); if (m_parameters) { BMenuBar *menuBar = KeyMenuBar(); m_idealSize = m_parameters->Bounds(); m_idealSize.right += B_V_SCROLL_BAR_WIDTH; m_idealSize.bottom += B_H_SCROLL_BAR_HEIGHT; if (menuBar) { m_parameters->MoveTo(0.0, menuBar->Bounds().bottom + 1.0); m_idealSize.bottom += menuBar->Bounds().bottom + 1.0; } } } } // limit min size to avoid funny-looking scrollbars float hMin = B_V_SCROLL_BAR_WIDTH*6, vMin = B_H_SCROLL_BAR_HEIGHT*3; // limit max size to full extents of the parameter view float hMax = m_idealSize.Width(), vMax = m_idealSize.Height(); SetSizeLimits(hMin, hMax, vMin, vMax); // adapt the window to the new dimensions ResizeTo(m_idealSize.Width(), m_idealSize.Height()); m_zoomed = true; if (m_parameters) { BRect paramRect = m_parameters->Bounds(); AddChild(new ParameterContainerView(paramRect, m_parameters)); } } void ParameterWindow::_constrainToScreen() { D_INTERNAL(("ParameterWindow::_constrainToScreen()\n")); BScreen screen(this); BRect screenRect = screen.Frame(); BRect windowRect = Frame(); // if the window is outside the screen rect // move it to the default position if (!screenRect.Intersects(windowRect)) { windowRect.OffsetTo(screenRect.LeftTop()); MoveTo(windowRect.LeftTop()); windowRect = Frame(); } // if the window is larger than the screen rect // resize it to fit at each side if (!screenRect.Contains(windowRect)) { if (windowRect.left < screenRect.left) { windowRect.left = screenRect.left + 5.0; MoveTo(windowRect.LeftTop()); windowRect = Frame(); } if (windowRect.top < screenRect.top) { windowRect.top = screenRect.top + 5.0; MoveTo(windowRect.LeftTop()); windowRect = Frame(); } if (windowRect.right > screenRect.right) { windowRect.right = screenRect.right - 5.0; } if (windowRect.bottom > screenRect.bottom) { windowRect.bottom = screenRect.bottom - 5.0; } ResizeTo(windowRect.Width(), windowRect.Height()); } } status_t ParameterWindow::_startControlPanel() { D_INTERNAL(("ParameterWindow::_startControlPanel()\n")); // get roster instance BMediaRoster *roster = BMediaRoster::CurrentRoster(); if (!roster) { D_INTERNAL((" -> MediaRoster not available\n")); return B_ERROR; } // try to StartControlPanel() BMessenger messenger; status_t error = roster->StartControlPanel(m_node, &messenger); if (error) { D_INTERNAL((" -> StartControlPanel() failed (%s)\n", strerror(error))); return error; } // notify the notification target, if any if (m_notifyTarget) { BMessage message(M_CONTROL_PANEL_STARTED); message.AddInt32("nodeID", m_node.node); message.AddMessenger("messenger", messenger); error = m_notifyTarget->SendMessage(&message); if (error) { D_INTERNAL((" -> failed to notify target\n")); } } return B_OK; } // END -- ParameterWindow.cpp --