1 /* 2 * Copyright (c) 1999-2000, Eric Moon. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions, and the following disclaimer. 11 * 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. 15 * 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. 18 * 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. 29 */ 30 31 32 // MediaWire.cpp 33 34 #include "MediaWire.h" 35 // InfoWindow 36 #include "InfoWindowManager.h" 37 // MediaRoutingView 38 #include "MediaJack.h" 39 #include "MediaRoutingDefs.h" 40 #include "MediaRoutingView.h" 41 // Support 42 #include "cortex_ui.h" 43 #include "MediaString.h" 44 // TipManager 45 #include "TipManager.h" 46 47 // Application Kit 48 #include <Application.h> 49 // Interface Kit 50 #include <MenuItem.h> 51 #include <PopUpMenu.h> 52 // Media Kit 53 #include <MediaDefs.h> 54 // Locale Kit 55 #undef B_CATALOG 56 #define B_CATALOG (&sCatalog) 57 #include <Catalog.h> 58 59 #undef B_TRANSLATION_CONTEXT 60 #define B_TRANSLATION_CONTEXT "MediaRoutingView" 61 62 __USE_CORTEX_NAMESPACE 63 64 #include <Debug.h> 65 #define D_METHOD(x) //PRINT (x) 66 #define D_DRAW(x) //PRINT (x) 67 #define D_MOUSE(x) //PRINT (x) 68 69 static BCatalog sCatalog("x-vnd.Cortex.MediaRoutingView"); 70 71 // -------------------------------------------------------- // 72 // constants 73 // -------------------------------------------------------- // 74 75 const float MediaWire::M_WIRE_OFFSET = 4.0; 76 77 // -------------------------------------------------------- // 78 // *** ctor/dtor 79 // -------------------------------------------------------- // 80 81 MediaWire::MediaWire( 82 Connection connection, 83 MediaJack *outputJack, 84 MediaJack *inputJack) 85 : DiagramWire(outputJack, inputJack), 86 connection(connection) 87 { 88 D_METHOD(("MediaWire::MediaWire()\n")); 89 } 90 91 MediaWire::MediaWire( 92 MediaJack *jack, 93 bool isStartPoint) 94 : DiagramWire(jack, isStartPoint) 95 { 96 D_METHOD(("MediaWire::MediaWire(temp)\n")); 97 } 98 99 MediaWire::~MediaWire() 100 { 101 D_METHOD(("MediaWire::~MediaWire()\n")); 102 } 103 104 // -------------------------------------------------------- // 105 // *** derived from DiagramWire (public) 106 // -------------------------------------------------------- // 107 108 void MediaWire::attachedToDiagram() 109 { 110 D_METHOD(("MediaWire::detachedFromDiagram()\n")); 111 112 endPointMoved(startPoint()); 113 endPointMoved(endPoint()); 114 } 115 116 void MediaWire::detachedFromDiagram() 117 { 118 D_METHOD(("MediaWire::detachedFromDiagram()\n")); 119 120 // make sure we're no longer displaying a tooltip 121 TipManager *tips = TipManager::Instance(); 122 tips->hideTip(view()->ConvertToScreen(Frame())); 123 } 124 125 BRect MediaWire::Frame() const 126 { 127 D_DRAW(("MediaWire::Frame()\n")); 128 return m_frame; 129 } 130 131 float MediaWire::howCloseTo( 132 BPoint point) const 133 { 134 D_MOUSE(("MediaWire::howCloseTo()\n")); 135 if (Frame().Contains(point)) 136 { 137 BPoint sp = m_startPoint; 138 BPoint ep = m_endPoint; 139 BPoint so = m_startOffset; 140 BPoint eo = m_endOffset; 141 BRect wireFrame, startFrame, endFrame; 142 wireFrame.left = so.x < eo.x ? so.x : eo.x; 143 wireFrame.top = so.y < eo.y ? so.y : eo.y; 144 wireFrame.right = so.x > eo.x ? so.x : eo.x; 145 wireFrame.bottom = so.y > eo.y ? so.y : eo.y; 146 startFrame.Set(sp.x, sp.y, so.x, so.y); 147 endFrame.Set(ep.x, ep.y, eo.x, eo.y); 148 wireFrame.InsetBy(-1.0, -1.0); 149 startFrame.InsetBy(-1.0, -1.0); 150 endFrame.InsetBy(-1.0, -1.0); 151 if ((wireFrame.Width() <= 5.0) || (wireFrame.Height() <= 5.0) || startFrame.Contains(point) || endFrame.Contains(point)) 152 { 153 return 1.0; 154 } 155 else 156 { 157 float length, result; 158 length = sqrt(pow(eo.x - so.x, 2) + pow(eo.y - so.y, 2)); 159 result = ((so.y - point.y) * (eo.x - so.x)) - ((so.x - point.x) * (eo.y - so.y)); 160 result = 3.0 - fabs(result / length); 161 return result; 162 } 163 } 164 return 0.0; 165 } 166 167 void MediaWire::drawWire() 168 { 169 D_DRAW(("MediaWire::drawWire()\n")); 170 171 rgb_color border = isSelected() ? M_BLUE_COLOR : M_DARK_GRAY_COLOR; 172 rgb_color fill = isSelected() ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR; 173 view()->SetPenSize(3.0); 174 view()->BeginLineArray(3); 175 view()->AddLine(m_startPoint, m_startOffset, border); 176 view()->AddLine(m_startOffset, m_endOffset, border); 177 view()->AddLine(m_endOffset, m_endPoint, border); 178 view()->EndLineArray(); 179 view()->SetPenSize(1.0); 180 view()->BeginLineArray(3); 181 view()->AddLine(m_startPoint, m_startOffset, fill); 182 view()->AddLine(m_startOffset, m_endOffset, fill); 183 view()->AddLine(m_endOffset, m_endPoint, fill); 184 view()->EndLineArray(); 185 } 186 187 void MediaWire::MouseDown( 188 BPoint point, 189 uint32 buttons, 190 uint32 clicks) 191 { 192 D_MOUSE(("MediaWire::MouseDown()\n")); 193 _inherited::MouseDown(point, buttons, clicks); 194 195 switch (buttons) 196 { 197 case B_SECONDARY_MOUSE_BUTTON: 198 { 199 if (clicks == 1) 200 { 201 showContextMenu(point); 202 } 203 } 204 } 205 } 206 207 void MediaWire::MouseOver( 208 BPoint point, 209 uint32 transit) 210 { 211 D_MOUSE(("MediaWire::MouseOver()\n")); 212 213 if (isDragging()) 214 { 215 return; 216 } 217 switch (transit) 218 { 219 case B_ENTERED_VIEW: 220 { 221 TipManager *tips = TipManager::Instance(); 222 BString tipText = MediaString::getStringFor(connection.format(), false); 223 tips->showTip(tipText.String(), view()->ConvertToScreen(Frame()), 224 TipManager::LEFT_OFFSET_FROM_POINTER, BPoint(12.0, 8.0)); 225 be_app->SetCursor(M_CABLE_CURSOR); 226 break; 227 } 228 case B_EXITED_VIEW: 229 { 230 be_app->SetCursor(B_HAND_CURSOR); 231 TipManager *tips = TipManager::Instance(); 232 tips->hideTip(view()->ConvertToScreen(Frame())); 233 break; 234 } 235 } 236 } 237 238 void MediaWire::selected() 239 { 240 D_METHOD(("MediaWire::selected()\n")); 241 if (startPoint()) 242 { 243 MediaJack *outputJack = static_cast<MediaJack *>(startPoint()); 244 outputJack->select(); 245 } 246 if (endPoint()) 247 { 248 MediaJack *inputJack = static_cast<MediaJack *>(endPoint()); 249 inputJack->select(); 250 } 251 } 252 253 void MediaWire::deselected() 254 { 255 D_METHOD(("MediaWire::deselected()\n")); 256 if (startPoint()) 257 { 258 MediaJack *outputJack = static_cast<MediaJack *>(startPoint()); 259 outputJack->deselect(); 260 } 261 if (endPoint()) 262 { 263 MediaJack *inputJack = static_cast<MediaJack *>(endPoint()); 264 inputJack->deselect(); 265 } 266 } 267 268 void MediaWire::endPointMoved( 269 DiagramEndPoint *which) 270 { 271 if (which == startPoint()) 272 { 273 m_startPoint = startConnectionPoint(); 274 switch (dynamic_cast<MediaRoutingView *>(view())->getLayout()) 275 { 276 case MediaRoutingView::M_ICON_VIEW: 277 { 278 m_startOffset = m_startPoint + BPoint(M_WIRE_OFFSET, 0.0); 279 break; 280 } 281 case MediaRoutingView::M_MINI_ICON_VIEW: 282 { 283 m_startOffset = m_startPoint + BPoint(0.0, M_WIRE_OFFSET); 284 break; 285 } 286 } 287 m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0; 288 m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0; 289 m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0; 290 m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0; 291 } 292 else if (which == endPoint()) 293 { 294 m_endPoint = endConnectionPoint(); 295 switch (dynamic_cast<MediaRoutingView *>(view())->getLayout()) 296 { 297 case MediaRoutingView::M_ICON_VIEW: 298 { 299 m_endOffset = m_endPoint - BPoint(M_WIRE_OFFSET, 0.0); 300 break; 301 } 302 case MediaRoutingView::M_MINI_ICON_VIEW: 303 { 304 m_endOffset = m_endPoint - BPoint(0.0, M_WIRE_OFFSET); 305 break; 306 } 307 } 308 m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0; 309 m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0; 310 m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0; 311 m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0; 312 } 313 } 314 315 // -------------------------------------------------------- // 316 // *** internal operations (protected) 317 // -------------------------------------------------------- // 318 319 void MediaWire::showContextMenu( 320 BPoint point) 321 { 322 D_METHOD(("MediaWire::showContextMenu()\n")); 323 324 BPopUpMenu *menu = new BPopUpMenu("MediaWire PopUp", false, false, B_ITEMS_IN_COLUMN); 325 menu->SetFont(be_plain_font); 326 BMenuItem *item; 327 328 // add the "Get Info" item 329 media_output output; 330 connection.getOutput(&output); 331 BMessage *message = new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED); 332 message->AddData("connection", B_RAW_TYPE, 333 reinterpret_cast<const void *>(&output), sizeof(output)); 334 menu->AddItem(new BMenuItem(B_TRANSLATE("Get info"), message, 'I')); 335 336 // add the "Disconnect" item 337 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Disconnect"), 338 new BMessage(MediaRoutingView::M_DELETE_SELECTION), 'T')); 339 if (connection.flags() & Connection::LOCKED) 340 { 341 item->SetEnabled(false); 342 } 343 344 menu->SetTargetForItems(view()); 345 view()->ConvertToScreen(&point); 346 point -= BPoint(1.0, 1.0); 347 menu->Go(point, true, true, true); 348 } 349 350 // END -- MediaWire.cpp -- 351