void RadiantSelectionSystem::keyChanged()
{
    if (!nothingSelected()) {
        pivotChanged();
        ConstructPivot();
    }
}
void RadiantSelectionSystem::cancelMove() {

    // Unselect any currently selected manipulators to be sure
    _manipulator->setSelected(false);

    // Tell all the scene objects to revert their transformations
    RevertTransformForSelected walker;
    Node_traverseSubgraph(GlobalSceneGraph().root(), walker);

    _pivotMoving = false;
    pivotChanged();

    // greebo: Deselect all faces if we are in brush and drag mode
    if (Mode() == ePrimitive && ManipulatorMode() == eDrag)
    {
        SelectAllComponentWalker faceSelector(false, SelectionSystem::eFace);
        Node_traverseSubgraph(GlobalSceneGraph().root(), faceSelector);
    }

    if (_undoBegun) {
        // Cancel the undo operation, if one has been begun
        GlobalUndoSystem().cancel();
        _undoBegun = false;
    }

    // Update the views
    SceneChangeNotify();
}
// Sets the current selection mode (Entity, Component or Primitive)
void RadiantSelectionSystem::SetMode(SelectionSystem::EMode mode) {
    // Only change something if the mode has actually changed
    if (_mode != mode) {
        _mode = mode;
        pivotChanged();
    }
}
void RadiantSelectionSystem::initialiseModule(const ApplicationContext& ctx) 
{
    rMessage() << "RadiantSelectionSystem::initialiseModule called.\n";

    constructStatic();

    SetManipulatorMode(eTranslate);
    pivotChanged();

    _sigSelectionChanged.connect(
        sigc::mem_fun(this, &RadiantSelectionSystem::pivotChangedSelection)
    );

    GlobalGrid().signal_gridChanged().connect(
        sigc::mem_fun(this, &RadiantSelectionSystem::pivotChanged)
    );

    GlobalRegistry().signalForKey(RKEY_ROTATION_PIVOT).connect(
        sigc::mem_fun(this, &RadiantSelectionSystem::keyChanged)
    );

    // Pass a reference to self to the global event manager
    GlobalEventManager().connectSelectionSystem(this);

    // Connect the bounds changed caller
    GlobalSceneGraph().signal_boundsChanged().connect(
        sigc::mem_fun(this, &RadiantSelectionSystem::onSceneBoundsChanged)
    );

    GlobalRenderSystem().attachRenderable(*this);
}
void RadiantSelectionSystem::onSceneBoundsChanged()
{
    // The bounds of the scenegraph have (possibly) changed
    pivotChanged();

    _requestWorkZoneRecalculation = true;
    requestIdleCallback();
}
// Set the current manipulator mode to <mode>
void RadiantSelectionSystem::SetManipulatorMode(EManipulatorMode mode) {
    _manipulatorMode = mode;
    switch(_manipulatorMode) {
        case eTranslate: _manipulator = &_translateManipulator; break;
        case eRotate: _manipulator = &_rotateManipulator; break;
        case eScale: _manipulator = &_scaleManipulator; break;
        case eDrag: _manipulator = &_dragManipulator; break;
        case eClip: _manipulator = &_clipManipulator; break;
    }
    pivotChanged();
}
RadiantSelectionSystem::RadiantSelectionSystem() :
	_requestWorkZoneRecalculation(true), _undoBegun(false), _mode(ePrimitive), _componentMode(eDefault), _countPrimitive(0),
			_countComponent(0),
			_translateManipulator(*this, 2, 64), // initialise the Manipulators with a pointer to self
			_rotateManipulator(*this, 8, 64), _scaleManipulator(*this, 0, 64), _pivotChanged(false),
			_pivotMoving(false)
{
	SetManipulatorMode(eTranslate);
	pivotChanged();
	addSelectionChangeCallback(PivotChangedSelectionCaller(*this));
	GlobalGrid().addGridChangeCallback(PivotChangedCaller(*this));

	// Pass a reference to self to the global event manager
	GlobalEventManager().connectSelectionSystem(this);
}
// End the move, this freezes the current transforms
void RadiantSelectionSystem::endMove() {
    freezeTransforms();

    // greebo: Deselect all faces if we are in brush and drag mode
    if ((Mode() == ePrimitive || Mode() == eGroupPart) &&
        ManipulatorMode() == eDrag)
    {
        SelectAllComponentWalker faceSelector(false, SelectionSystem::eFace);
        Node_traverseSubgraph(GlobalSceneGraph().root(), faceSelector);
    }

    // Remove all degenerated brushes from the scene graph (should emit a warning)
    foreachSelected(RemoveDegenerateBrushWalker());

    _pivotMoving = false;
    pivotChanged();

    // Update the views
    SceneChangeNotify();

    // If we started an undoable operation, end it now and tell the console what happened
    if (_undoBegun)
    {
        std::ostringstream command;

        if (ManipulatorMode() == eTranslate) {
            command << "translateTool";
            outputTranslation(command);
        }
        else if (ManipulatorMode() == eRotate) {
            command << "rotateTool";
            outputRotation(command);
        }
        else if (ManipulatorMode() == eScale) {
            command << "scaleTool";
            outputScale(command);
        }
        else if (ManipulatorMode() == eDrag) {
            command << "dragTool";
        }

        _undoBegun = false;

        // Finish the undo move
        GlobalUndoSystem().finish(command.str());
    }
}
void RadiantSelectionSystem::pivotChangedSelection(const Selectable& selectable) {
    pivotChanged();
}
// greebo: Callback for the selectionSystem event: onBoundsChanged
void RadiantSelectionSystem::onBoundsChanged() {
	pivotChanged();

	_requestWorkZoneRecalculation = true;
	requestIdleCallback();
}