IECore::RunTimeTypedPtr GraphGadget::dragBegin( GadgetPtr gadget, const DragDropEvent &event ) { if( !m_scriptNode ) { return 0; } V3f i; if( !event.line.intersect( Plane3f( V3f( 0, 0, 1 ), 0 ), i ) ) { return 0; } m_dragMode = None; m_dragStartPosition = m_lastDragPosition = V2f( i.x, i.y ); NodeGadget *nodeGadget = nodeGadgetAt( event.line ); if( event.buttons == ButtonEvent::Left ) { if( nodeGadget && m_scriptNode->selection()->contains( nodeGadget->node() ) ) { m_dragMode = Moving; // we have to return an object to start the drag but the drag we're // starting is for our purposes only, so we return an object that won't // be accepted by any other drag targets. return IECore::NullObject::defaultNullObject(); } else if( !nodeGadget ) { m_dragMode = Selecting; return IECore::NullObject::defaultNullObject(); } } else if( event.buttons == ButtonEvent::Middle ) { if( nodeGadget ) { m_dragMode = Sending; Pointer::setFromFile( "nodes.png" ); if( m_scriptNode->selection()->contains( nodeGadget->node() ) ) { return m_scriptNode->selection(); } else { return nodeGadget->node(); } } } return 0; }
bool GraphGadget::buttonPress( GadgetPtr gadget, const ButtonEvent &event ) { if( event.buttons==ButtonEvent::Left ) { // selection/deselection if( !m_scriptNode ) { return false; } ViewportGadget *viewportGadget = ancestor<ViewportGadget>(); std::vector<GadgetPtr> gadgetsUnderMouse; viewportGadget->gadgetsAt( viewportGadget->gadgetToRasterSpace( event.line.p0, this ), gadgetsUnderMouse ); if( !gadgetsUnderMouse.size() || gadgetsUnderMouse[0] == this ) { // background click. clear selection unless shift is // held, in which case we're expecting a shift drag // to add to the selection. if( !(event.modifiers & ButtonEvent::Shift) ) { m_scriptNode->selection()->clear(); } return true; } NodeGadget *nodeGadget = runTimeCast<NodeGadget>( gadgetsUnderMouse[0] ); if( !nodeGadget ) { nodeGadget = gadgetsUnderMouse[0]->ancestor<NodeGadget>(); } if( nodeGadget ) { Gaffer::NodePtr node = nodeGadget->node(); bool shiftHeld = event.modifiers && ButtonEvent::Shift; bool nodeSelected = m_scriptNode->selection()->contains( node ); std::vector<Gaffer::Node *> affectedNodes; if( const BackdropNodeGadget *backdrop = runTimeCast<BackdropNodeGadget>( nodeGadget ) ) { backdrop->framed( affectedNodes ); } if( event.modifiers & ButtonEvent::Alt ) { std::vector<NodeGadget *> upstream; upstreamNodeGadgets( node, upstream ); for( std::vector<NodeGadget *>::const_iterator it = upstream.begin(), eIt = upstream.end(); it != eIt; ++it ) { affectedNodes.push_back( (*it)->node() ); } } affectedNodes.push_back( node ); if( nodeSelected ) { if( shiftHeld ) { m_scriptNode->selection()->remove( affectedNodes.begin(), affectedNodes.end() ); } } else { if( !shiftHeld ) { m_scriptNode->selection()->clear(); } m_scriptNode->selection()->add( affectedNodes.begin(), affectedNodes.end() ); } return true; } } else if( event.buttons == ButtonEvent::Middle ) { // potentially the start of a middle button drag on a node return nodeGadgetAt( event.line ); } return false; }