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 // #pragma mark - 21 22 23 DiagramBox::DiagramBox(BRect frame, uint32 flags) 24 : DiagramItem(DiagramItem::M_BOX), 25 DiagramItemGroup(DiagramItem::M_ENDPOINT), 26 m_frame(frame), 27 m_flags(flags) 28 { 29 D_METHOD(("DiagramBox::DiagramBox()\n")); 30 makeDraggable(true); 31 } 32 33 34 DiagramBox::~DiagramBox() 35 { 36 D_METHOD(("DiagramBox::~DiagramBox()\n")); 37 } 38 39 40 // derived from DiagramItemGroup (public) 41 bool 42 DiagramBox::AddItem(DiagramItem *item) 43 { 44 D_METHOD(("DiagramBox::AddItem()\n")); 45 if (item) { 46 if (DiagramItemGroup::AddItem(item)) { 47 if (m_view) { 48 item->_setOwner(m_view); 49 item->attachedToDiagram(); 50 } 51 return true; 52 } 53 } 54 return false; 55 } 56 57 58 bool 59 DiagramBox::RemoveItem(DiagramItem *item) 60 { 61 D_METHOD(("DiagramBox::RemoveItem()\n")); 62 if (item) { 63 item->detachedFromDiagram(); 64 if (DiagramItemGroup::RemoveItem(item)) { 65 item->_setOwner(0); 66 return true; 67 } 68 } 69 return false; 70 } 71 72 73 // derived from DiagramItem (public) 74 void 75 DiagramBox::draw(BRect updateRect) 76 { 77 D_DRAW(("DiagramBox::draw()\n")); 78 if (view()) { 79 view()->PushState(); 80 { 81 if (m_flags & M_DRAW_UNDER_ENDPOINTS) { 82 BRegion region, clipping; 83 region.Include(frame()); 84 if (group()->GetClippingAbove(this, &clipping)) 85 region.Exclude(&clipping); 86 view()->ConstrainClippingRegion(®ion); 87 drawBox(); 88 for (uint32 i = 0; i < CountItems(); i++) { 89 DiagramItem *item = ItemAt(i); 90 if (region.Intersects(item->frame())) 91 item->draw(item->frame()); 92 } 93 } else { 94 BRegion region, clipping; 95 region.Include(frame()); 96 if (view()->GetClippingAbove(this, &clipping)) 97 region.Exclude(&clipping); 98 for (uint32 i = 0; i < CountItems(); i++) { 99 DiagramItem *item = ItemAt(i); 100 BRect r; 101 if (region.Intersects(r = item->frame())) { 102 item->draw(r); 103 region.Exclude(r); 104 } 105 } 106 view()->ConstrainClippingRegion(®ion); 107 drawBox(); 108 } 109 } 110 view()->PopState(); 111 } 112 } 113 114 115 void 116 DiagramBox::mouseDown(BPoint point, uint32 buttons, uint32 clicks) 117 { 118 D_MOUSE(("DiagramBox::mouseDown()\n")); 119 DiagramItem *item = ItemUnder(point); 120 if (item) 121 item->mouseDown(point, buttons, clicks); 122 else if (clicks == 1) { 123 if (isSelectable()) { 124 BMessage selectMsg(M_SELECTION_CHANGED); 125 if (modifiers() & B_SHIFT_KEY) 126 selectMsg.AddBool("replace", false); 127 else 128 selectMsg.AddBool("replace", true); 129 selectMsg.AddPointer("item", reinterpret_cast<void *>(this)); 130 DiagramView* v = view(); 131 BMessenger(v).SendMessage(&selectMsg); 132 } 133 if (isDraggable() && (buttons == B_PRIMARY_MOUSE_BUTTON)) { 134 BMessage dragMsg(M_BOX_DRAGGED); 135 dragMsg.AddPointer("item", static_cast<void *>(this)); 136 dragMsg.AddPoint("offset", point - frame().LeftTop()); 137 view()->DragMessage(&dragMsg, BRect(0.0, 0.0, -1.0, -1.0), view()); 138 } 139 } 140 } 141 142 143 void 144 DiagramBox::mouseOver(BPoint point, uint32 transit) 145 { 146 D_MOUSE(("DiagramBox::mouseOver()\n")); 147 DiagramItem *last = _LastItemUnder(); 148 if (last && (transit == B_EXITED_VIEW)) { 149 last->mouseOver(point, B_EXITED_VIEW); 150 _ResetItemUnder(); 151 } else { 152 DiagramItem *item = ItemUnder(point); 153 if (item) { 154 if (item != last) { 155 if (last) 156 last->mouseOver(point, B_EXITED_VIEW); 157 item->mouseOver(point, B_ENTERED_VIEW); 158 } else 159 item->mouseOver(point, B_INSIDE_VIEW); 160 } 161 else if (last) 162 last->mouseOver(point, B_EXITED_VIEW); 163 } 164 } 165 166 167 void 168 DiagramBox::messageDragged(BPoint point, uint32 transit, const BMessage *message) 169 { 170 D_MOUSE(("DiagramBox::messageDragged()\n")); 171 DiagramItem *last = _LastItemUnder(); 172 if (last && (transit == B_EXITED_VIEW)) { 173 last->messageDragged(point, B_EXITED_VIEW, message); 174 _ResetItemUnder(); 175 } else { 176 DiagramItem *item = ItemUnder(point); 177 if (item) { 178 if (item != last) { 179 if (last) 180 last->messageDragged(point, B_EXITED_VIEW, message); 181 item->messageDragged(point, B_ENTERED_VIEW, message); 182 } else 183 item->messageDragged(point, B_INSIDE_VIEW, message); 184 return; 185 } else if (last) 186 last->messageDragged(point, B_EXITED_VIEW, message); 187 if (message->what == M_WIRE_DRAGGED) 188 view()->trackWire(point); 189 } 190 } 191 192 193 void 194 DiagramBox::messageDropped(BPoint point, BMessage *message) 195 { 196 D_METHOD(("DiagramBox::messageDropped()\n")); 197 DiagramItem *item = ItemUnder(point); 198 if (item) { 199 item->messageDropped(point, message); 200 return; 201 } 202 } 203 204 205 // operations (public) 206 void 207 DiagramBox::moveBy(float x, float y, BRegion *wireRegion) 208 { 209 D_METHOD(("DiagramBox::moveBy()\n")); 210 if (view()) { 211 view()->PushState(); 212 { 213 for (uint32 i = 0; i < CountItems(); i++) { 214 DiagramEndPoint *endPoint = dynamic_cast<DiagramEndPoint *>(ItemAt(i)); 215 if (endPoint) 216 endPoint->moveBy(x, y, wireRegion); 217 } 218 if (wireRegion) { 219 wireRegion->Include(m_frame); 220 m_frame.OffsetBy(x, y); 221 wireRegion->Include(m_frame); 222 } 223 else 224 m_frame.OffsetBy(x, y); 225 } 226 view()->PopState(); 227 } 228 } 229 230 231 void 232 DiagramBox::resizeBy(float horizontal, float vertical) 233 { 234 D_METHOD(("DiagramBox::resizeBy()\n")); 235 m_frame.right += horizontal; 236 m_frame.bottom += vertical; 237 } 238 239 240 // internal operations (private) 241 void 242 DiagramBox::_setOwner(DiagramView *owner) 243 { 244 D_METHOD(("DiagramBox::_setOwner()\n")); 245 m_view = owner; 246 for (uint32 i = 0; i < CountItems(DiagramItem::M_ENDPOINT); i++) { 247 DiagramItem *item = ItemAt(i); 248 item->_setOwner(m_view); 249 if (m_view) 250 item->attachedToDiagram(); 251 } 252 } 253