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