1 // DiagramBox.cpp 2 3 #include "DiagramBox.h" 4 #include "DiagramDefs.h" 5 #include "DiagramEndPoint.h" 6 #include "DiagramView.h" 7 8 #include <Message.h> 9 #include <Messenger.h> 10 11 __USE_CORTEX_NAMESPACE 12 13 #include <Debug.h> 14 #define D_METHOD(x) //PRINT (x) 15 #define D_MESSAGE(x) //PRINT (x) 16 #define D_MOUSE(x) //PRINT (x) 17 #define D_DRAW(x) //PRINT (x) 18 19 // -------------------------------------------------------- // 20 // *** ctor/dtor (public) 21 // -------------------------------------------------------- // 22 23 DiagramBox::DiagramBox( 24 BRect frame, 25 uint32 flags) 26 : DiagramItem(DiagramItem::M_BOX), 27 DiagramItemGroup(DiagramItem::M_ENDPOINT), 28 m_frame(frame), 29 m_flags(flags) 30 { 31 D_METHOD(("DiagramBox::DiagramBox()\n")); 32 makeDraggable(true); 33 } 34 35 DiagramBox::~DiagramBox() 36 { 37 D_METHOD(("DiagramBox::~DiagramBox()\n")); 38 } 39 40 // -------------------------------------------------------- // 41 // *** derived from DiagramItemGroup (public) 42 // -------------------------------------------------------- // 43 44 bool DiagramBox::addItem( 45 DiagramItem *item) 46 { 47 D_METHOD(("DiagramBox::addItem()\n")); 48 if (item) 49 { 50 if (DiagramItemGroup::addItem(item)) 51 { 52 if (m_view) 53 { 54 item->_setOwner(m_view); 55 item->attachedToDiagram(); 56 } 57 return true; 58 } 59 } 60 return false; 61 } 62 63 bool DiagramBox::removeItem( 64 DiagramItem *item) 65 { 66 D_METHOD(("DiagramBox::removeItem()\n")); 67 if (item) 68 { 69 item->detachedFromDiagram(); 70 if (DiagramItemGroup::removeItem(item)) 71 { 72 item->_setOwner(0); 73 return true; 74 } 75 } 76 return false; 77 } 78 79 // -------------------------------------------------------- // 80 // *** derived from DiagramItem (public) 81 // -------------------------------------------------------- // 82 83 void DiagramBox::draw( 84 BRect updateRect) 85 { 86 D_DRAW(("DiagramBox::draw()\n")); 87 if (view()) 88 { 89 view()->PushState(); 90 { 91 if (m_flags & M_DRAW_UNDER_ENDPOINTS) 92 { 93 BRegion region, clipping; 94 region.Include(frame()); 95 if (group()->getClippingAbove(this, &clipping)) 96 region.Exclude(&clipping); 97 view()->ConstrainClippingRegion(®ion); 98 drawBox(); 99 for (int32 i = 0; i < countItems(); i++) 100 { 101 DiagramItem *item = itemAt(i); 102 if (region.Intersects(item->frame())) 103 { 104 item->draw(item->frame()); 105 } 106 } 107 } 108 else 109 { 110 BRegion region, clipping; 111 region.Include(frame()); 112 if (view()->getClippingAbove(this, &clipping)) 113 region.Exclude(&clipping); 114 for (int32 i = 0; i < countItems(); i++) 115 { 116 DiagramItem *item = itemAt(i); 117 BRect r; 118 if (region.Intersects(r = item->frame())) 119 { 120 item->draw(r); 121 region.Exclude(r); 122 } 123 } 124 view()->ConstrainClippingRegion(®ion); 125 drawBox(); 126 } 127 } 128 view()->PopState(); 129 } 130 } 131 132 void DiagramBox::mouseDown( 133 BPoint point, 134 uint32 buttons, 135 uint32 clicks) 136 { 137 D_MOUSE(("DiagramBox::mouseDown()\n")); 138 DiagramItem *item = itemUnder(point); 139 if (item) 140 { 141 item->mouseDown(point, buttons, clicks); 142 } 143 else if (clicks == 1) 144 { 145 if (isSelectable()) 146 { 147 BMessage selectMsg(M_SELECTION_CHANGED); 148 if (modifiers() & B_SHIFT_KEY) 149 { 150 selectMsg.AddBool("replace", false); 151 } 152 else 153 { 154 selectMsg.AddBool("replace", true); 155 } 156 selectMsg.AddPointer("item", reinterpret_cast<void *>(this)); 157 DiagramView* v = view(); 158 BMessenger(v).SendMessage(&selectMsg); 159 } 160 if (isDraggable() && (buttons == B_PRIMARY_MOUSE_BUTTON)) 161 { 162 BMessage dragMsg(M_BOX_DRAGGED); 163 dragMsg.AddPointer("item", static_cast<void *>(this)); 164 dragMsg.AddPoint("offset", point - frame().LeftTop()); 165 view()->DragMessage(&dragMsg, BRect(0.0, 0.0, -1.0, -1.0), view()); 166 } 167 } 168 } 169 170 void DiagramBox::mouseOver( 171 BPoint point, 172 uint32 transit) 173 { 174 D_MOUSE(("DiagramBox::mouseOver()\n")); 175 DiagramItem *last = lastItemUnder(); 176 if (last && (transit == B_EXITED_VIEW)) 177 { 178 last->mouseOver(point, B_EXITED_VIEW); 179 resetItemUnder(); 180 } 181 else 182 { 183 DiagramItem *item = itemUnder(point); 184 if (item) 185 { 186 if (item != last) 187 { 188 if (last) 189 last->mouseOver(point, B_EXITED_VIEW); 190 item->mouseOver(point, B_ENTERED_VIEW); 191 } 192 else 193 { 194 item->mouseOver(point, B_INSIDE_VIEW); 195 } 196 } 197 else if (last) 198 { 199 last->mouseOver(point, B_EXITED_VIEW); 200 } 201 } 202 } 203 204 void DiagramBox::messageDragged( 205 BPoint point, 206 uint32 transit, 207 const BMessage *message) 208 { 209 D_MOUSE(("DiagramBox::messageDragged()\n")); 210 DiagramItem *last = lastItemUnder(); 211 if (last && (transit == B_EXITED_VIEW)) 212 { 213 last->messageDragged(point, B_EXITED_VIEW, message); 214 resetItemUnder(); 215 } 216 else 217 { 218 DiagramItem *item = itemUnder(point); 219 if (item) 220 { 221 if (item != last) 222 { 223 if (last) 224 { 225 last->messageDragged(point, B_EXITED_VIEW, message); 226 } 227 item->messageDragged(point, B_ENTERED_VIEW, message); 228 } 229 else 230 { 231 item->messageDragged(point, B_INSIDE_VIEW, message); 232 } 233 return; 234 } 235 else if (last) 236 { 237 last->messageDragged(point, B_EXITED_VIEW, message); 238 } 239 if (message->what == M_WIRE_DRAGGED) 240 { 241 view()->trackWire(point); 242 } 243 } 244 } 245 246 void DiagramBox::messageDropped( 247 BPoint point, 248 BMessage *message) 249 { 250 D_METHOD(("DiagramBox::messageDropped()\n")); 251 DiagramItem *item = itemUnder(point); 252 if (item) 253 { 254 item->messageDropped(point, message); 255 return; 256 } 257 } 258 259 // -------------------------------------------------------- // 260 // *** operations (public) 261 // -------------------------------------------------------- // 262 263 void DiagramBox::moveBy( 264 float x, 265 float y, 266 BRegion *wireRegion) 267 { 268 D_METHOD(("DiagramBox::moveBy()\n")); 269 if (view()) 270 { 271 view()->PushState(); 272 { 273 for (int32 i = 0; i < countItems(); i++) 274 { 275 DiagramEndPoint *endPoint = dynamic_cast<DiagramEndPoint *>(itemAt(i)); 276 if (endPoint) 277 { 278 endPoint->moveBy(x, y, wireRegion); 279 } 280 } 281 if (wireRegion) 282 { 283 wireRegion->Include(m_frame); 284 m_frame.OffsetBy(x, y); 285 wireRegion->Include(m_frame); 286 } 287 else 288 { 289 m_frame.OffsetBy(x, y); 290 } 291 } 292 view()->PopState(); 293 } 294 } 295 296 void DiagramBox::resizeBy( 297 float horizontal, 298 float vertical) 299 { 300 D_METHOD(("DiagramBox::resizeBy()\n")); 301 m_frame.right += horizontal; 302 m_frame.bottom += vertical; 303 } 304 305 // -------------------------------------------------------- // 306 // *** internal operations (private) 307 // -------------------------------------------------------- // 308 309 void DiagramBox::_setOwner( 310 DiagramView *owner) 311 { 312 D_METHOD(("DiagramBox::_setOwner()\n")); 313 m_view = owner; 314 for (int32 i = 0; i < countItems(DiagramItem::M_ENDPOINT); i++) 315 { 316 DiagramItem *item = itemAt(i); 317 item->_setOwner(m_view); 318 if (m_view) 319 { 320 item->attachedToDiagram(); 321 } 322 } 323 } 324 325 // END -- DiagramBox.cpp -- 326