// Hub function for "deselect all", this passes the deselect call to the according functions
void RadiantSelectionSystem::deselectAll() {
    if (Mode() == eComponent) {
        setSelectedAllComponents(false);
    }
    else {
        setSelectedAll(false);
    }
}
void RadiantSelectionSystem::shutdownModule() 
{
    // greebo: Unselect everything so that no references to scene::Nodes
    // are kept after shutdown, causing destruction issues.
    setSelectedAll(false);
    setSelectedAllComponents(false);

    GlobalRenderSystem().detachRenderable(*this);

    destroyStatic();
}
/* greebo: This gets called by the SelectObserver if the user drags a box and holds down
 * any of the selection modifiers. Possible selection candidates are determined and selected/deselected
 */
void RadiantSelectionSystem::SelectArea(const View& view,
                                        const Vector2& device_point,
                                        const Vector2& device_delta,
                                        SelectionSystem::EModifier modifier, bool face)
{
    // If we are in replace mode, deselect all the components or previous selections
    if (modifier == SelectionSystem::eReplace) {
        if (face) {
            setSelectedAllComponents(false);
        }
        else {
            deselectAll();
        }
    }

    {
        // Construct the selection test according to the area the user covered with his drag
        View scissored(view);
        ConstructSelectionTest(scissored, Rectangle::ConstructFromArea(device_point, device_delta));

        SelectionVolume volume(scissored);
        // The posssible candidates go here
        SelectionPool pool;

        SelectablesList candidates;

        if (face)
        {
            ComponentSelector selectionTester(pool, volume, eFace);
            GlobalSceneGraph().foreachVisibleNodeInVolume(scissored, selectionTester);

            // Load them all into the vector
            for (SelectionPool::iterator i = pool.begin(); i != pool.end(); ++i)
            {
                candidates.push_back(i->second);
            }
        }
        else {
            testSelectScene(candidates, volume, scissored, Mode(), ComponentMode());
        }

        // Cycle through the selection pool and toggle the candidates, but only if we are in toggle mode
        for (SelectablesList::iterator i = candidates.begin(); i != candidates.end(); i++) {
            (*i)->setSelected(!(modifier == SelectionSystem::eToggle && (*i)->isSelected()));
        }
    }
}
Ejemplo n.º 4
0
/* greebo: This gets called by the SelectObserver if the user drags a box and holds down
 * any of the selection modifiers. Possible selection candidates are determined and selected/deselected
 */
void RadiantSelectionSystem::SelectArea(const View& view,
										const float device_point[2],
										const float device_delta[2],
										SelectionSystem::EModifier modifier, bool face)
{
	// If we are in replace mode, deselect all the components or previous selections
	if (modifier == SelectionSystem::eReplace) {
		if (face) {
			setSelectedAllComponents(false);
		}
		else {
			deselectAll();
		}
	}

#if defined (DEBUG_SELECTION)
	g_render_clipped.destroy();
#endif

	{
		// Construct the selection test according to the area the user covered with his drag
		View scissored(view);
		ConstructSelectionTest(scissored, SelectionBoxForArea(device_point, device_delta));

		SelectionVolume volume(scissored);
		// The posssible candidates go here
		SelectionPool pool;
		if (face) {
			Scene_TestSelect_Component(pool, volume, scissored, eFace);
		}
		else {
			Scene_TestSelect(pool, volume, scissored, Mode(), ComponentMode());
		}

		// Cycle through the selection pool and toggle the candidates, but only if we are in toggle mode
		for (SelectionPool::iterator i = pool.begin(); i != pool.end(); ++i) {
			(*i).second->setSelected(!(modifier == SelectionSystem::eToggle && (*i).second->isSelected()));
		}
	}
}
/* greebo: This gets called by SelectObserver if the user just clicks into the scene (without dragging)
 * It checks for any possible targets (in the "line of click") and takes the actions according
 * to the modifiers that are held down (Alt-Shift, etc.)
 */
void RadiantSelectionSystem::SelectPoint(const View& view,
                                         const Vector2& device_point,
                                         const Vector2& device_epsilon,
                                         SelectionSystem::EModifier modifier,
                                         bool face)
{
    ASSERT_MESSAGE(fabs(device_point[0]) <= 1.0f && fabs(device_point[1]) <= 1.0f, "point-selection error");
    // If the user is holding the replace modifiers (default: Alt-Shift), deselect the current selection
    if (modifier == SelectionSystem::eReplace) {
        if (face) {
            setSelectedAllComponents(false);
        }
        else {
            deselectAll();
        }
    }

    {
        View scissored(view);
        // Construct a selection test according to a small box with 2*epsilon edge length
        ConstructSelectionTest(scissored, Rectangle::ConstructFromPoint(device_point, device_epsilon));

        // Create a new SelectionPool instance and fill it with possible candidates
        SelectionVolume volume(scissored);
        // The possible candidates are stored in the SelectablesSet
        SelectablesList candidates;

        if (face)
        {
            SelectionPool selector;

            ComponentSelector selectionTester(selector, volume, eFace);
            GlobalSceneGraph().foreachVisibleNodeInVolume(scissored, selectionTester);

            // Load them all into the vector
            for (SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i)
            {
                candidates.push_back(i->second);
            }
        }
        else {
            testSelectScene(candidates, volume, scissored, Mode(), ComponentMode());
        }

        // Was the selection test successful (have we found anything to select)?
        if (candidates.size() > 0) {
            // Yes, now determine how we should interpret the click
            switch (modifier) {
                // If we are in toggle mode (Shift-Left-Click by default), just toggle the
                // selection of the "topmost" item
                case SelectionSystem::eToggle: {
                    Selectable* best = *candidates.begin();
                    // toggle selection of the object with least depth (=first in the list)
                    best->setSelected(!best->isSelected());
                }
                break;
                // greebo: eReplace mode gets active as soon as the user holds the replace modifiers down
                // and clicks (by default: Alt-Shift). eReplace is only active during the first click
                // afterwards we are in cycle mode.
                // if cycle mode not enabled, enable it
                case SelectionSystem::eReplace: {
                    // select closest (=first in the list)
                    (*candidates.begin())->setSelected(true);
                }
                break;
                // select the next object in the list from the one already selected
                // greebo: eCycle is set if the user keeps holding the replace modifiers (Alt-Shift)
                // and does NOT move the mouse between the clicks, otherwise we fall back into eReplace mode
                // Note: The mode is set in SelectObserver::testSelect()
                case SelectionSystem::eCycle: {
                    // Cycle through the selection pool and activate the item right after the currently selected
                    SelectablesList::iterator i = candidates.begin();

                    while (i != candidates.end()) {
                        if ((*i)->isSelected()) {
                            // unselect the currently selected one
                            (*i)->setSelected(false);
                            // check if there is a "next" item in the list, if not: select the first item
                            ++i;
                            if (i != candidates.end()) {
                                (*i)->setSelected(true);
                            }
                            else {
                                (*candidates.begin())->setSelected(true);
                            }
                            break;
                        }
                        ++i;
                    } // while
                } // case
                break;
                default:
                break;
            } // switch
        }
    }
}
Ejemplo n.º 6
0
/* greebo: This gets called by SelectObserver if the user just clicks into the scene (without dragging)
 * It checks for any possible targets (in the "line of click") and takes the actions according
 * to the modifiers that are held down (Alt-Shift, etc.)
 */
void RadiantSelectionSystem::SelectPoint(const View& view,
										 const float device_point[2],
										 const float device_epsilon[2],
										 SelectionSystem::EModifier modifier,
										 bool face)
{
	ASSERT_MESSAGE(fabs(device_point[0]) <= 1.0f && fabs(device_point[1]) <= 1.0f, "point-selection error");
	// If the user is holding the replace modifiers (default: Alt-Shift), deselect the current selection
	if (modifier == SelectionSystem::eReplace) {
		if (face) {
			setSelectedAllComponents(false);
		}
		else {
			deselectAll();
		}
	}

#if defined (DEBUG_SELECTION)
	g_render_clipped.destroy();
#endif

	{
		View scissored(view);
		// Construct a selection test according to a small box with 2*epsilon edge length
		ConstructSelectionTest(scissored, SelectionBoxForPoint(device_point, device_epsilon));

		// Create a new SelectionPool instance and fill it with possible candidates
		SelectionVolume volume(scissored);
		// The possible candidates are stored in the SelectionPool
		SelectionPool selector;
		if (face) {
			Scene_TestSelect_Component(selector, volume, scissored, eFace);
		}
		else {
			Scene_TestSelect(selector, volume, scissored, Mode(), ComponentMode());
		}

		// Was the selection test successful (have we found anything to select)?
		if (!selector.failed()) {
			// Yes, now determine how we should interpret the click
			switch (modifier) {
				// If we are in toggle mode (Shift-Left-Click by default), just toggle the
				// selection of the "topmost" item
				case SelectionSystem::eToggle: {
					SelectableSortedSet::iterator best = selector.begin();
					// toggle selection of the object with least depth (=first in the list)
					if ((*best).second->isSelected())
						(*best).second->setSelected(false);
					else
						(*best).second->setSelected(true);
				}
				break;
				// greebo: eReplace mode gets active as soon as the user holds the replace modifiers down
				// and clicks (by default: Alt-Shift). eReplace is only active during the first click
				// afterwards we are in cycle mode.
				// if cycle mode not enabled, enable it
				case SelectionSystem::eReplace: {
					// select closest (=first in the list)
					(*selector.begin()).second->setSelected(true);
				}
				break;
				// select the next object in the list from the one already selected
				// greebo: eCycle is set if the user keeps holding the replace modifiers (Alt-Shift)
				// and does NOT move the mouse between the clicks, otherwise we fall back into eReplace mode
				// Note: The mode is set in SelectObserver::testSelect()
				case SelectionSystem::eCycle: {
					// Cycle through the selection pool and activate the item right after the currently selected
					SelectionPool::iterator i = selector.begin();
					while (i != selector.end()) {
						if ((*i).second->isSelected()) {
							// unselect the currently selected one
							(*i).second->setSelected(false);
							// check if there is a "next" item in the list, if not: select the first item
							++i;
							if (i != selector.end()) {
								i->second->setSelected(true);
							}
							else {
								selector.begin()->second->setSelected(true);
							}
							break;
						}
						++i;
					} // while
				} // case
				break;
				default:
				break;
			} // switch
		}
	}
}