Skip to content
OE_interfaceDisplay.cpp 25.1 KiB
Newer Older
/*
 * Copyright (c) 2015 Tricoire Sebastien 3dsman@free.fr
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 */

#include "OE_interfaceDisplay.h"
#include "OE_utils.h"

#include "OE_controller.h"

#include <iostream>

#include <GL/gl.h>
#include <cstdlib>
#include <math.h>
#include <cstdio>
#include <cstring>
#include <algorithm> 

#include "actions/OE_actionsCurves.h"
#include "actions/OE_actionsStitchs.h"
#include "actions/OE_actionsLineStitchs.h"
#include "actions/OE_actionsBirailStitchs.h"
3dsman's avatar
3dsman committed
#include "actions/OE_actionsFillStitchs.h"
#include "actions/OE_actionsSelection.h"
#include "actions/OE_actionsThreads.h"

raoul's avatar
raoul committed
static const GLuint TOOLSSELID = 0;
static const GLuint STITCHSSELID  = 1;
static const GLuint CURVESSELID = 2;
raoul's avatar
raoul committed
static const GLuint ZEROID  = 0;
static const GLuint TRANSTOOLID = 1;
static const GLuint MOVETOOLID = 0;
static const GLuint SCALETOOLID = 1;
raoul's avatar
raoul committed
OE_interfaceDisplay::OE_interfaceDisplay(OE_document* document)
	editStyle = new OE_display::OE_displayStyle();
	commandStyle = new OE_display::OE_displayStyle();
	commandStyle->drawGrid = false;
	commandStyle->drawCurves = false;
	commandStyle->drawStitches = false;
	commandStyle->drawCommands = true;
raoul's avatar
raoul committed
	setDocument(document);
}

OE_interfaceDisplay::~OE_interfaceDisplay()
{
raoul's avatar
raoul committed
bool OE_interfaceDisplay::setDocument(OE_document* document)
raoul's avatar
raoul committed
	return true;
}


bool OE_interfaceDisplay::setController(OE_controller* controller)
{
raoul's avatar
raoul committed
	return true;
}

void OE_interfaceDisplay::mouse_Pos(double x, double y)
{
raoul's avatar
raoul committed
	OE_display::mouse_Pos(x, y);
	vector_2dt oldClosestPoint = editClosestPoint;
raoul's avatar
raoul committed
	vector_2d absMove = vector_2d((mouse.x - clicOldMouse.x)*zoom*2, (mouse.y - clicOldMouse.y)*zoom*2);
raoul's avatar
raoul committed
	if (editionState == MoveSelection) //if the move action is enabled
raoul's avatar
raoul committed
		controller->editActionMoveSelection(vector_2d((mouse.x - clicOldMouse.x)*zoom*2,
		                                              (mouse.y - clicOldMouse.y)*zoom*2));
		return;
raoul's avatar
raoul committed
	if (editionState == ScaleSelection) //if the scale action is enabled
	{
		vector_2d bbCenter = controller->getSelectionBoundingBox().getCenter();
		float scale = (absMouse-bbCenter).len()/(screenToDocument(clicOldMouse)-bbCenter).len();
raoul's avatar
raoul committed
		controller->editActionScaleSelection(vector_2d(scale,scale));
		return;
	}

	if (editSubcurve) //if we are working on a defined subcurve get the closest point on it
raoul's avatar
raoul committed
	{
		editClosestPoint = controller->getClosestPoint(editSubcurve->getCurve(), absMouse);
	}
raoul's avatar
raoul committed
	if (editionState == NewSubcurve) //if we must find the closest subcurve (get the closest point on it too)
3dsman's avatar
3dsman committed
        closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
raoul's avatar
raoul committed
	if (selControlCurve && selControlType==0) //if we're moving a curve control point
raoul's avatar
raoul committed
		controller->editActionMovePointCurve(vector_2d((mouse.x - clicOldMouse.x)*zoom*2,
		                                               (mouse.y - clicOldMouse.y)*zoom*2));
	if (editionState == MovePointstitch) //if we're moving a linkstitch control point
	{
		controller->editActionMovePointLinkStitch(absMove);
		controller->editActionMoveGridPointFillStitch(absMove);
	if (selControlStitch) //if we're working on a stitch
raoul's avatar
raoul committed
	{
		OE_linestitch* tmpLineStitch = dynamic_cast<OE_linestitch*>(selControlStitch);
		OE_birailstitch* tmpBirailStitch = dynamic_cast<OE_birailstitch*>(selControlStitch);
3dsman's avatar
3dsman committed
		OE_fillstitch* tmpFillStitch = dynamic_cast<OE_fillstitch*>(selControlStitch);
raoul's avatar
raoul committed
		if (tmpLineStitch && editionState == OffsetWidthLinestitch) //if this is a linestitch and we're picking the scaleWidth controler
raoul's avatar
raoul committed
			controller->editActionSetLinestitchWidth((mouse.x - clicOldMouse.x)/100.0f, true);
			return;
		//if we're define control curves for linestitch or birailstitch
raoul's avatar
raoul committed
		if ((tmpLineStitch && selControlType == 0)||
		    (tmpFillStitch && selControlType == 0)||
		    (tmpBirailStitch && (selControlType == 0 || selControlType == 1)))
		{
			if (editionState == NewSubcurve)
			{
				editionState = TraceSubcurve;
				if (oldClosestPoint.t>editClosestPoint.t) controller->editActionAddSubcurvePosSwitchDir();
			}
raoul's avatar
raoul committed
			if (editionState == TraceSubcurve)
			{
				controller->editActionAddSubcurvePosEnd(editClosestPoint.t);
			}
			else
			{
				controller->editActionSetSubcurvePos(editClosestPoint.t);
			}
		}
	}
}

void OE_interfaceDisplay::mouse_Button(int button, int action, int mods)
{
raoul's avatar
raoul committed
	modState = mods;
	OE_display::mouse_Button(button, action, mods);
raoul's avatar
raoul committed
	if (curScreen == edit && button == GLFW_MOUSE_BUTTON_LEFT && action==GLFW_PRESS)
raoul's avatar
raoul committed
		if (editionState == NewSubcurve)
		{
			if (!closestCurve)
raoul's avatar
raoul committed
			else
			{
				controller->addAction(new OE_actionJoincurveAddSubCurve(curJoincurve, -1, closestCurve,
				                                                        editClosestPoint.t, editClosestPoint.t,
				                                                        false));
				selControlStitch = controller->getStitch(-1);
				selControlType = 0;
				editSubcurve = curJoincurve->getCurve(-1);
raoul's avatar
raoul committed
			}
		}
		else
		{
			clicOldMouse = mouse;
raoul's avatar
raoul committed
			if (editionState == None)
			{
raoul's avatar
raoul committed
			}
			if (editionState == None)
			{
raoul's avatar
raoul committed
			}
raoul's avatar
raoul committed
		}
	}
raoul's avatar
raoul committed
	if (curScreen == edit && button == GLFW_MOUSE_BUTTON_LEFT && action==GLFW_RELEASE)
raoul's avatar
raoul committed
		//if (selControlCurve)selControlCurve = 0;
		//if (selControlStitch)selControlStitch = 0;
		selControlCurve = 0;
		selControlStitch = 0;
raoul's avatar
raoul committed
		if (editionState == Selection)
		{
			if ((mouse-clicOldMouse).len()>5)
raoul's avatar
raoul committed
			{
raoul's avatar
raoul committed
			}
			selectApply(selectedCurves, selectedStitches);
			editionState = None;
		}
raoul's avatar
raoul committed
		if (editionState == TraceSubcurve)
		{
			editionState = NewSubcurve;
			editSubcurve = 0;
raoul's avatar
raoul committed
		if (editionState == MoveSubcurve ||
		    editionState == MovePointcurve ||
		    editionState == MovePointstitch ||
		    editionState == DelPointstitch ||
		    editionState == MoveSelection ||
		    editionState == ScaleSelection)
		{
raoul's avatar
raoul committed
		}
}

void OE_interfaceDisplay::scroll(double xoffset, double yoffset)
{
	OE_display::scroll(xoffset, yoffset);
}

void OE_interfaceDisplay::resize(int width, int height)
{
	OE_display::resize(width, height);
}

void OE_interfaceDisplay::key(int key, int scancode, int action, int mods)
{
3dsman's avatar
3dsman committed
	const char* key_name = glfwGetKeyName(key, 0);
raoul's avatar
raoul committed
	if (!key_name)
	{
		key_name = " ";
	}
raoul's avatar
raoul committed
	modState = mods;
	if (action == GLFW_PRESS && curScreen == edit)
	{
		if (!strcmp(key_name, "z") && mods == GLFW_MOD_CONTROL)
		{
			if (controller)
			{
				controller->undoAction();
			}
		}
		else if (!strcmp(key_name, "s") && mods == GLFW_MOD_CONTROL)
		{
			if (document)
			{
				document->saveToFile("../roger.oe");
			}
		}
		else if (!strcmp(key_name, "o") && mods == GLFW_MOD_CONTROL)
		{
			if (document)
			{
				document->loadFromFile("../roger.oe");
			}
		}
		else if (!strcmp(key_name, "z") && mods == (GLFW_MOD_CONTROL|GLFW_MOD_SHIFT))
		{
			if (controller)
			{
				controller->redoAction();
			}
		}
		else if (mods == 0)
		{
3dsman's avatar
3dsman committed
			if (!strcmp(key_name, "c"))
raoul's avatar
raoul committed
			{
				if (controller)
				{
					controller->toggleCloseSelectedCurve();
				}
			}
			else if (!strcmp(key_name, "r"))
			{
				if (editionState == TraceSubcurve)
				{
					controller->editActionAddSubcurvePosSwitchDir();
raoul's avatar
raoul committed
				}
				else if (editionState == MoveSubcurve)
				{
					controller->editActionSetSubcurvePosSwitchDir();
				}
raoul's avatar
raoul committed
			}
			else if (key == GLFW_KEY_DELETE)
				//TODO create an action to delete all selected stitches
				std::list<OE_stitchs*>::iterator it=selectedStitches.begin();
				controller->addAction(new OE_actionDelStitch(*it));
raoul's avatar
raoul committed
			}
			else if (key == GLFW_KEY_RIGHT)
				std::list<OE_stitchs*>::iterator it=selectedStitches.begin();
				if (it != selectedStitches.end())
				{
					it = find (document->stitchs.begin(), document->stitchs.end(), *it);
					it++;
					if (it != document->stitchs.end())
					{
						selectedStitches.clear();
						selectedStitches.push_back(*it);
						controller->clearSelection();
						controller->selectStitches(selectedStitches,true);
					}
				}
raoul's avatar
raoul committed
	if (action == GLFW_RELEASE)
raoul's avatar
raoul committed
		if (curScreen == command && key == GLFW_KEY_SPACE)
		{
			run=true;
		}
		if (key == GLFW_KEY_F5)
		{
			if (curScreen == edit)
raoul's avatar
raoul committed
			}
raoul's avatar
raoul committed
		}
		else if (!strcmp(key_name, "l"))
		{
			if (controller)
			{
				controller->newLineStitch(2.5, 2.5, controller->getPattern(0));
				document->selectedStitchs.push_back(controller->getLineStitch(-1));
				curJoincurve = controller->getLineStitch(-1)->getJoincurve();
				closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);

				editionState = NewSubcurve;
				joincurve_id = 0;
			}
		}
		else if (!strcmp(key_name, "b"))
		{
			if (controller)
			{
				controller->newBirailStitch(false, false, 0,0,0.7);
				document->selectedStitchs.push_back(controller->getBirailStitch(-1));
				curJoincurve = controller->getBirailStitch(-1)->getJoincurve1();
				closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);

				editionState = NewSubcurve;
				joincurve_id = 1;
			}
		}
		else if (!strcmp(key_name, "f"))
3dsman's avatar
3dsman committed
		{
			if (controller)
			{
3dsman's avatar
3dsman committed
				controller->newFillStitch(1.5,0.3,controller->getPattern(0));
3dsman's avatar
3dsman committed
				document->selectedStitchs.push_back(controller->getFillStitch(-1));
				curJoincurve = controller->getFillStitch(-1)->getJoincurve();
				closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);

				editionState = NewSubcurve;
				joincurve_id = 0;
			}
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_ENTER)
		{
			if (editionState == NewSubcurve)
			{
				if (joincurve_id == 0)
				{
					editionState = None;
					curJoincurve = 0;
				}
				else
				{
					curJoincurve = controller->getBirailStitch(-1)->getJoincurve2();
					closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
					joincurve_id -= 1;
				}
			}
		}
		else if (!strcmp(key_name, "r"))
		{
			if (editionState == TraceSubcurve)
			{
				controller->editActionAddSubcurvePosSwitchDir();
			}
			else if (editionState == MoveSubcurve)
			{
				controller->editActionSetSubcurvePosSwitchDir();
			}
		}
		else if (key == GLFW_KEY_KP_ADD)
		{
			if (mods == GLFW_MOD_CONTROL)
				controller->addAction(new OE_actionScaleSelectedLineStitchLen(1.1));
				controller->addAction(new OE_actionScaleSelectedBirailStitchLen(1.1));
				controller->addAction(new OE_actionScaleSelectedFillStitchLen(1.1));
raoul's avatar
raoul committed
			{
				controller->addAction(new OE_actionScaleSelectedLineStitchWidth(1.1));
				controller->addAction(new OE_actionScaleSelectedFillStitchWidth(1.1));
raoul's avatar
raoul committed
			}
		}
		else if (key == GLFW_KEY_KP_SUBTRACT)
raoul's avatar
raoul committed
			if (mods == GLFW_MOD_CONTROL)
				controller->addAction(new OE_actionScaleSelectedLineStitchLen(1/1.1));
				controller->addAction(new OE_actionScaleSelectedBirailStitchLen(1/1.1));
				controller->addAction(new OE_actionScaleSelectedFillStitchLen(1/1.1));
raoul's avatar
raoul committed
			{
				controller->addAction(new OE_actionScaleSelectedLineStitchWidth(1/1.1));
				controller->addAction(new OE_actionScaleSelectedFillStitchWidth(1/1.1));
raoul's avatar
raoul committed
			}
		}
		else if (key == GLFW_KEY_KP_1)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(0)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(0)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_2)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(1)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(1)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_3)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(2)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(2)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_4)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(3)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(3)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_5)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(4)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(4)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_6)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(5)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(5)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_7)
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(6)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(6)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_8)
		{
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(7)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(7)));
raoul's avatar
raoul committed
		}
		else if (key == GLFW_KEY_KP_9)
		{
			controller->addAction(new OE_actionSetSelectedLineStitchPattern(controller->getPattern(8)));
			controller->addAction(new OE_actionSetSelectedFillStitchPattern(controller->getPattern(8)));
raoul's avatar
raoul committed
		if (key == GLFW_KEY_HOME)
raoul's avatar
raoul committed
	}
	//OE_display::key( key,  scancode,  action,  mods);
3dsman's avatar
3dsman committed

bool OE_interfaceDisplay::selectBox()
{
raoul's avatar
raoul committed
	selectedCurves.clear();
	selectedStitches.clear();
	vector_2d clicAbsMouse = viewPos+(clicOldMouse-vector_2d(width,height)/2)*zoom*2;
	float tmpXMin, tmpYMin, tmpXMax, tmpYMax;
3dsman's avatar
3dsman committed

raoul's avatar
raoul committed
	std::list<OE_pointcurve*>::iterator curve = document->curves.begin();
	while (curve != document->curves.end())
	{
		BoundingBox box = (*curve)->getBound();
		if ((box.getMin().x>minf(clicAbsMouse.x,absMouse.x))
			 &&(box.getMax().x<maxf(clicAbsMouse.x,absMouse.x))
			 &&(box.getMin().y>minf(clicAbsMouse.y,absMouse.y))
			 &&(box.getMax().y<maxf(clicAbsMouse.y,absMouse.y)))
		{
			selectedCurves.push_back(*curve);
		}
		curve++;
	}
3dsman's avatar
3dsman committed

raoul's avatar
raoul committed
	std::list<OE_stitchs*>::iterator stitch = document->stitchs.begin();
	while (stitch != document->stitchs.end())
	{
raoul's avatar
raoul committed
		BoundingBox box = (*stitch)->getBound();
		if ((box.getMin().x>minf(clicAbsMouse.x,absMouse.x))
			 &&(box.getMax().x<maxf(clicAbsMouse.x,absMouse.x))
			 &&(box.getMin().y>minf(clicAbsMouse.y,absMouse.y))
			 &&(box.getMax().y<maxf(clicAbsMouse.y,absMouse.y)))
raoul's avatar
raoul committed
		{
			selectedStitches.push_back(*stitch);
		}
		stitch++;
	}
bool OE_interfaceDisplay::checkPicking()
{
raoul's avatar
raoul committed
	if (toolAction)
raoul's avatar
raoul committed
		if (toolAction == 1)
		{
			editionState = MoveSelection;
			return controller->addAction(new OE_actionMoveSelection(vector_2d(0,0)));
		}
raoul's avatar
raoul committed
		if (toolAction == 2)
		{
			editionState = ScaleSelection;
			return controller->addAction(new OE_actionScaleSelection(vector_2d(1,1), controller->getSelectionBoundingBox().getCenter()));
		}
raoul's avatar
raoul committed
	if (selControlStitch)
raoul's avatar
raoul committed
		OE_linestitch* tmpLineStitch = dynamic_cast<OE_linestitch*>(selControlStitch);
raoul's avatar
raoul committed
			if (selControlType == 0)
			{
				// get the corresponding subcurve
				editSubcurve = tmpLineStitch->getJoincurve()->getCurve(selControlIndex/2);
				if (editSubcurve)
				{
					// get the closest point t value
					vector_2dt pos = editSubcurve->getCurve()->closestPoint(absMouse);
					// and add an action to move the point
raoul's avatar
raoul committed
					controller->addAction(new OE_actionSetSubcurvePos(editSubcurve, selControlIndex%2, pos.t));
raoul's avatar
raoul committed
			if (selControlType == 1 && selControlIndex==0)
				editionState = OffsetWidthLinestitch;
raoul's avatar
raoul committed
				controller->addAction(new OE_actionSetLineStitchWidth(tmpLineStitch, tmpLineStitch->getWidth()));
raoul's avatar
raoul committed
		OE_birailstitch* tmpBirailStitch = dynamic_cast<OE_birailstitch*>(selControlStitch);
raoul's avatar
raoul committed
		if (tmpBirailStitch && (selControlType == 0 || selControlType == 1))
		{
			// get the corresponding subcurve
			if (selControlType == 0)
			{
				editSubcurve = tmpBirailStitch->getJoincurve1()->getCurve(selControlIndex/2);
			}
			else if (selControlType == 1)
			{
				editSubcurve = tmpBirailStitch->getJoincurve2()->getCurve(selControlIndex/2);
			}
			if (editSubcurve)
			{
raoul's avatar
raoul committed
				// get the closest point t value
				vector_2dt pos = editSubcurve->getCurve()->closestPoint(absMouse);
				// and add an action to move the point
				controller->addAction(new OE_actionSetSubcurvePos(editSubcurve, selControlIndex%2, pos.t));
				return true;
			}
			return false;
		}

		OE_fillstitch* tmpFillStitch = dynamic_cast<OE_fillstitch*>(selControlStitch);

		if (tmpFillStitch && (selControlType == 0 || selControlType == 1))
		{
			// get the corresponding subcurve
			if (selControlType == 0)
			{
				editSubcurve = tmpFillStitch->getJoincurve()->getCurve(selControlIndex/2);
			}
			else if (selControlType == 1)
			{
				editionState = MovePointstitch;
				//edit gridpoint
				controller->addAction(new OE_actionMovePointFillStitch(tmpFillStitch, selControlIndex, absMouse));
				return true;
			}
			if (editSubcurve)
			{
				editionState = MoveSubcurve;
				// get the closest point t value
				vector_2dt pos = editSubcurve->getCurve()->closestPoint(absMouse);
				// and add an action to move the point
				controller->addAction(new OE_actionSetSubcurvePos(editSubcurve, selControlIndex%2, pos.t));
				return true;
			}
			return false;
		}

		OE_linkstitch* tmpLinkStitch = dynamic_cast<OE_linkstitch*>(selControlStitch);

raoul's avatar
raoul committed
		if (tmpLinkStitch && (selControlType == 0 || selControlType == 1 || selControlType == 2))
		{
			if (selControlType == 0)
			{
				editionState = MovePointstitch;
				controller->addAction(new OE_actionMovePointLinkStitch(tmpLinkStitch, selControlIndex, vector_2d()));
raoul's avatar
raoul committed
			}
			else if (selControlType == 1)
			{
				editionState = MovePointstitch;
				controller->addAction(new OE_actionAddPointLinkStitch(tmpLinkStitch, selControlIndex, absMouse));
raoul's avatar
raoul committed
			}
			else if (selControlType == 2)
			{
				editionState = DelPointstitch;
				controller->addAction(new OE_actionDelPointLinkStitch(tmpLinkStitch, selControlIndex));
raoul's avatar
raoul committed
	if (selControlCurve)
raoul's avatar
raoul committed
		OE_pointcurve* tmpPointCurve = dynamic_cast<OE_pointcurve*>(selControlCurve);
raoul's avatar
raoul committed
		if (tmpPointCurve && selControlType == 0)
		{
			editionState = MovePointcurve;
raoul's avatar
raoul committed
			return controller->addAction(new OE_actionMovePointCurve(tmpPointCurve,
			                                                         selControlIndex+1,
			                                                         vector_2d(0,0)));
		}
		selControlCurve = 0;
/** \brief set selection
 *
 * \return true if all is ok
 *
 */
bool OE_interfaceDisplay::drawPicking()
	GLuint selectBuf[64];
	GLint hits;
	glSelectBuffer(64, selectBuf);
	OE_display::pick(document->selectedCurves, document->selectedStitchs);

	//get the hits of the picking
	//hits are represented by an array of GLuint*
	// first value give us the number of items on the name stack at the time of the hit
	// next 2 values are deep value of the picked object (we don't use it)
	// then the items we need arrived
	// we format it like that:
	// - type of the picked object (tool, stitch or curve)
	// - index of the picked object (list index for stitch or curve, index of the tool for the tools)
	// - if we picked a sub element of a curve, stich or tool here come his type (handle, startpoint,...)
	// - then his index
	//
	// so a hit can be defined by
	// 2 values in case a curve of a stitch was picked directly
	// 3 values in case of picking a transform tool like move
	// or 4 values if we picked a sub element of a curve or stitch

	hits = glRenderMode(GL_RENDER);
	selectedCurves.clear();
	selectedStitches.clear();
raoul's avatar
raoul committed
	GLuint i, nb_names, name, *ptr;
	//std::cout<<"hits : "<<"\r\n";
	ptr = (GLuint *) selectBuf;
raoul's avatar
raoul committed
	for (GLuint i=0; i<hits; i++)  //  for each hit
	{
		bool recognized = false;
		GLuint names = *ptr;
		ptr+=3; //skip nearZ and farZ info (we don't use it) and goto first index
		if (*ptr == TOOLSSELID) //tools picking
		{
			ptr++;
raoul's avatar
raoul committed
			if (*ptr == ZEROID) //zero
raoul's avatar
raoul committed
			if (*ptr == TRANSTOOLID) //one of the transform selection tools
raoul's avatar
raoul committed
				if (*ptr == MOVETOOLID) //move selection tools
				{
					toolAction = 1;
					checkPicking();
					return true;
				}
raoul's avatar
raoul committed
				if (*ptr == SCALETOOLID) //scale selection tools
				{
					toolAction = 2;
					checkPicking();
					return true;
				}
raoul's avatar
raoul committed
		}
		else if (*ptr == STITCHSSELID) //stitch picking
		{
			ptr++;
			if (names==2) //if name count correspond to an object (we picked a stitch, not one of his sub element)
raoul's avatar
raoul committed
				if (*ptr >= document->stitchs.size())
				{
					return false;
				}
				std::list<OE_stitchs*>::iterator it = document->stitchs.begin();
				std::advance(it, *ptr);
				selectedStitches.push_back(*it);
				return true;
raoul's avatar
raoul committed
			}
			else if (names==4) //if name count correspond to a stitch sub element (like control point)
raoul's avatar
raoul committed
				if (*ptr >= document->selectedStitchs.size())
				{
					return false;
				}

				std::list<OE_stitchs*>::iterator it = document->selectedStitchs.begin();
				std::advance(it, *ptr++);
				selControlStitch = *it;
				selControlType = *ptr++;
				selControlIndex = *ptr++;

				checkPicking();
				return true;
raoul's avatar
raoul committed
		}
		else if (*ptr == CURVESSELID) //curves picking
		{
			ptr++;
			if (names==2) //if name count correspond to an object (we picked a curve, not one of his sub element)
			{
raoul's avatar
raoul committed
				if (*ptr >= document->curves.size())
				{
					return false;
				}

				std::list<OE_pointcurve*>::iterator it = document->curves.begin();
				std::advance(it, *ptr);
				selectedCurves.push_back(*it);
				return true;
raoul's avatar
raoul committed
			}
			else if (names==4) //if name count correspond to a sub element of curve (like control point)
raoul's avatar
raoul committed
				if (*ptr >= document->selectedCurves.size())
				{
					return false;
				}
				//in *ptr we got "curve id" then "control type" and at last "control id"
				std::list<OE_pointcurve*>::iterator it = document->selectedCurves.begin();
				std::advance(it, *ptr++);
				selControlCurve = *it;
				selControlType = *ptr++;
				selControlIndex = *ptr++;

				checkPicking();

				return true;
			}
bool OE_interfaceDisplay::selectApply(std::list<OE_pointcurve*> selectedCurves, std::list<OE_stitchs*> selectedStitches)
raoul's avatar
raoul committed
	if (selectedCurves.size())
	{
		if (modState&GLFW_MOD_CONTROL)
		{
			controller->unselectCurves(selectedCurves);
		}
		else
		{
			controller->selectCurves(selectedCurves, !(modState&GLFW_MOD_SHIFT));
		}
	}

	if (selectedStitches.size())
	{
		if (modState&GLFW_MOD_CONTROL)
		{
			controller->unselectStitches(selectedStitches);
		}
		else
		{
			controller->selectStitches(selectedStitches, !(modState&GLFW_MOD_SHIFT));
		}
	}
raoul's avatar
raoul committed
	if (!selectedStitches.size() && !selectedCurves.size())
	{
		controller->clearSelection();
	}

	return true;

/** \brief draw the document on screen
 *
 * \return true if all is ok
 *
 */
bool OE_interfaceDisplay::draw()
{
raoul's avatar
raoul committed
	if (run)
	{
		controller->sendInstPoint();
	}

	//draw the closest point
	if (editionState==NewSubcurve)
raoul's avatar
raoul committed
	{
		// Points
		glPointSize(5.0f);

		glBegin(GL_POINTS);
		if (joincurve_id == 0)
raoul's avatar
raoul committed
		{
			glColor4d(0.8f, 0.0f, 0.0f, 1.0f);
raoul's avatar
raoul committed
		}
		else
		{
			glColor4d(0.0f, 0.8f, 0.0f, 1.0f);
raoul's avatar
raoul committed
		}
		glVertex2f(editClosestPoint.v.x,editClosestPoint.v.y);
		glEnd();
raoul's avatar
raoul committed
	}
	// draw the cursor cross
	glLineWidth(1.5);
	glBegin(GL_LINES);
		if (editionState)
raoul's avatar
raoul committed
		{
			if (joincurve_id == 0)
			{
				glColor4d(0.8f, 0.0f, 0.0f, 0.5f);
raoul's avatar
raoul committed
			}
			else
			{
				glColor4d(0.0f, 0.8f, 0.0f, 0.5f);
raoul's avatar
raoul committed
			}
		}
		else
		{
			style->cursorColor.gl();
		}
		glVertex2f(absMouse.x,-10000);
		glVertex2f(absMouse.x,10000);
raoul's avatar
raoul committed

		glVertex2f(-10000,absMouse.y);
		glVertex2f(10000,absMouse.y);
	glEnd();
raoul's avatar
raoul committed

	// draw the cursor picking zone
	glLineWidth(2);
	glBegin(GL_LINE_LOOP);
		style->cursorColor.gl();
		glVertex2f(absMouse.x-5*zoom,absMouse.y+5*zoom);
		glVertex2f(absMouse.x-5*zoom,absMouse.y-5*zoom);
		glVertex2f(absMouse.x+5*zoom,absMouse.y-5*zoom);
		glVertex2f(absMouse.x+5*zoom,absMouse.y+5*zoom);
	glEnd();
raoul's avatar
raoul committed

	if (editionState == Selection)
	{
		vector_2d clicAbsMouse = viewPos+(clicOldMouse-vector_2d(width,height)/2)*zoom*2;
raoul's avatar
raoul committed
		glLineWidth(2);
		glBegin(GL_LINE_STRIP);
			style->cursorColor.gl();
			glVertex2f(absMouse.x,clicAbsMouse.y);
			glVertex2f(absMouse.x,absMouse.y);
			glVertex2f(clicAbsMouse.x,absMouse.y);
			glVertex2f(clicAbsMouse.x,clicAbsMouse.y);
			glVertex2f(absMouse.x,clicAbsMouse.y);
raoul's avatar
raoul committed
		glEnd();
	}