/* * 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 #include #include #include #include #include #include #include "actions/OE_actionsCurves.h" #include "actions/OE_actionsStitchs.h" #include "actions/OE_actionsLineStitchs.h" #include "actions/OE_actionsMetaLineStitchs.h" #include "actions/OE_actionsBirailStitchs.h" #include "actions/OE_actionsSelection.h" #include "actions/OE_actionsThreads.h" OE_interfaceDisplay::OE_interfaceDisplay(OE_document* document) { editDisplay = new OE_editDisplay(); commandDisplay = new OE_commandDisplay(); curDisplay = editDisplay; setDocument(document); } OE_interfaceDisplay::~OE_interfaceDisplay() { delete editDisplay; delete commandDisplay; } bool OE_interfaceDisplay::setDocument(OE_document * document) { this->document = document; if(document) { editDisplay->setDocument(document); commandDisplay->setDocument(document); } return true; } bool OE_interfaceDisplay::setController(OE_controller* controller) { this->controller = controller; if(controller) { if (editDisplay) editDisplay->setController(controller); if (commandDisplay) commandDisplay->setController(controller); } return true; } void OE_interfaceDisplay::showAll() { if (curDisplay) curDisplay->showAll(); } void OE_interfaceDisplay::mouse_Pos(double x, double y) { OE_display::mouse_Pos( x, y); if (curDisplay) curDisplay->mouse_Pos(x, y); if ((selControlCurve)&&(selControlType == 0)) controller->editLastAction(vector_2d((mouseX - clicOldMouseX)*zoom*2,(mouseY - clicOldMouseY)*zoom*2)); if ((selControlStitch)&&(selControlType == 0)) { OE_metaLinestitch* tmpMetaLineStitch = dynamic_cast(selControlStitch); vector_2dt pos = tmpMetaLineStitch->getSubCurve(selControlIndex/2)->getCurve()->closestPoint(vector_2d(absMouseX,absMouseY)); controller->editLastAction(pos.t); } } void OE_interfaceDisplay::mouse_Button(int button, int action, int mods) { modState = mods; if (curDisplay) curDisplay->mouse_Button(button, action, mods); if((curDisplay == editDisplay)&&(button == GLFW_MOUSE_BUTTON_LEFT)&&(action==GLFW_PRESS)) { clicOldMouseX = mouseX; clicOldMouseY = mouseY; selection = true; select(); } if((curDisplay == editDisplay)&&(button == GLFW_MOUSE_BUTTON_LEFT)&&(action==GLFW_RELEASE)) { if(selection) { if ((abs(mouseX-clicOldMouseX)>5)||(abs(mouseY-clicOldMouseY)>5)) selectBox(); selectApply(selectedCurves, selectedStitches); selection = false; } if(selControlCurve)selControlCurve = 0; if(selControlStitch)selControlStitch = 0; } } void OE_interfaceDisplay::scroll(double xoffset, double yoffset) { if (curDisplay) curDisplay->scroll(xoffset, yoffset); } void OE_interfaceDisplay::resize(int width, int height) { if (curDisplay) curDisplay->resize(width, height); } void OE_interfaceDisplay::key(int key, int scancode, int action, int mods) { modState = mods; if((action == GLFW_PRESS)&&(curDisplay == editDisplay)) { if ((key == GLFW_KEY_Z)&&(mods == GLFW_MOD_CONTROL)) { if (controller) controller->undoAction(); } if ((key == GLFW_KEY_Z)&&(mods == GLFW_MOD_CONTROL+GLFW_MOD_SHIFT)) { if (controller) controller->redoAction(); } if (mods == 0) { if (key == GLFW_KEY_C) { if (controller) controller->toggleCloseSelectedCurve(); } } } if((action == GLFW_RELEASE)&&(key == GLFW_KEY_F5)) { if(curDisplay == editDisplay) { if (controller) controller->generateInstructions(); curDisplay = commandDisplay; } else curDisplay = editDisplay; } curDisplay->key( key, scancode, action, mods); } bool OE_interfaceDisplay::selectBox() { selectedCurves.clear(); selectedStitches.clear(); float clicAbsMouseX = cx+(clicOldMouseX-width/2)*zoom*2; float clicAbsMouseY = cy+(clicOldMouseY-height/2)*zoom*2; float tmpXMin, tmpYMin, tmpXMax, tmpYMax; std::list::iterator curve = document->curves.begin(); while (curve != document->curves.end()) { (*curve)->getBound(&tmpXMin, &tmpYMin, &tmpXMax, &tmpYMax); if ((tmpXMin>minf(clicAbsMouseX,absMouseX)) &&(tmpXMaxminf(clicAbsMouseY,absMouseY)) &&(tmpYMax::iterator stitch = document->stitchs.begin(); while (stitch != document->stitchs.end()) { (*stitch)->getBound(&tmpXMin, &tmpYMin, &tmpXMax, &tmpYMax); if ((tmpXMin>minf(clicAbsMouseX,absMouseX)) &&(tmpXMaxminf(clicAbsMouseY,absMouseY)) &&(tmpYMax(selControlStitch); selection = false; if ((tmpMetaLineStitch)&&(selControlType == 0)) { OE_subcurve* tmpcurve = tmpMetaLineStitch->getSubCurve(selControlIndex/2); vector_2dt pos = tmpcurve->getCurve()->closestPoint(vector_2d(absMouseX,absMouseY)); controller->addAction(new OE_actionSetSubcurvePos( tmpcurve, selControlIndex%2, pos.t)); return true; } selControlStitch = 0; } if(selControlCurve) { OE_pointcurve* tmpPointCurve = dynamic_cast(selControlCurve); selection = false; if ((tmpPointCurve)&&(selControlType == 0)) { 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::select() { GLuint selectBuf[64]; GLint hits; glSelectBuffer(64, selectBuf); draw(true); hits = glRenderMode(GL_RENDER); selectedCurves.clear(); selectedStitches.clear(); GLuint i, nb_names, name, *ptr; std::cout<<"hits : "<selectedStitchs.size()) { std::list::iterator it = document->selectedStitchs.begin(); std::advance(it, *ptr++); selControlStitch = *it; selControlType = *ptr++; selControlIndex = *ptr++; checkPicking(); /* OE_metaLinestitch* tmpMetaLineStitch = dynamic_cast(selControlStitch); selection = false; if ((tmpMetaLineStitch)&&(selControlType == 0)) { return controller->addAction(new OE_actionSetMetaLineStitchSub( tmpMetaLineStitch, selControlIndex, vector_2d(absMouseX,absMouseY))); } selControlStitch = 0; */ return true; }else ptr+=4; }else if (*ptr == 2) //curves index { ptr++; if(*ptr < document->selectedCurves.size()) { std::list::iterator it = document->selectedCurves.begin(); std::advance(it, *ptr++); selControlCurve = *it; selControlType = *ptr++; selControlIndex = *ptr++; checkPicking(); /* OE_pointcurve* tmpPointCurve = dynamic_cast(selControlCurve); selection = false; if ((tmpPointCurve)&&(selControlType == 0)) { return controller->addAction(new OE_actionMovePointCurve( tmpPointCurve, selControlIndex + 1, vector_2d(0,0))); } selControlCurve = 0; */ return true; }else ptr+=4; } }else if (names==2) //if name count correspond to a simple element { ptr+=3; //jump near and far info and goto first index if (*ptr == 0) //tools index { ptr++; if(*ptr == 0) std::cout<<" zero "; ptr++; }else if (*ptr == 1) //stitches index { ptr++; std::cout<<" stitch "<<*ptr; if (document->stitchs.size() > *ptr) { std::list::iterator it = document->stitchs.begin(); std::advance(it, *ptr); selectedStitches.push_back(*it); } ptr++; }else if (*ptr == 2) //curves index { ptr++; std::cout<<" curve "<<*ptr; if (document->curves.size() > *ptr) { std::list::iterator it = document->curves.begin(); std::advance(it, *ptr); selectedCurves.push_back(*it); } ptr++; }else { ptr++; std::cout<<" unrecognized item "<<*ptr;ptr++; } std::cout< selectedCurves, std::list selectedStitches) { 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)); return true; } /** \brief draw the document on screen * * \return true if all is ok * */ bool OE_interfaceDisplay::draw() { draw(false); } /** \brief draw the document on screen * * \return true if all is ok * */ bool OE_interfaceDisplay::draw(bool select) { if (select) { glRenderMode(GL_SELECT); //Init of name stack glInitNames(); glPushName(0); } float wzoom, hzoom; glViewport(0, 0, width, height); glClearColor(220.0f/255.0f, 220.0f/255.0f, 220.0f/255.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glEnd(); wzoom = (float)width*zoom; hzoom = (float)height*zoom; if(select) glOrtho(absMouseX-5*zoom, absMouseX+5*zoom, absMouseY+5*zoom, absMouseY-5*zoom, -1, 1); else glOrtho(cx-wzoom, cx+wzoom, cy+hzoom, cy-hzoom, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glColor4ub(255,255,255,255); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); if (document && curDisplay) { if(select && (curDisplay == editDisplay)) editDisplay->select(document->selectedCurves, document->selectedStitchs); else curDisplay->draw(); } if(!select) { // cursor cross glLineWidth(1.5); glBegin(GL_LINES); glColor4d(0.0f, 0.0f, 0.0f, 0.3f); glVertex2f(absMouseX,-10000); glVertex2f(absMouseX,10000); glVertex2f(-10000,absMouseY); glVertex2f(10000,absMouseY); glEnd(); //cursor select zone glLineWidth(2); glBegin(GL_LINE_STRIP); glColor4d(0.0f, 0.0f, 0.0f, 0.3f); glVertex2f(absMouseX-5*zoom,absMouseY+5*zoom); glVertex2f(absMouseX-5*zoom,absMouseY-5*zoom); glVertex2f(absMouseX+5*zoom,absMouseY-5*zoom); glVertex2f(absMouseX+5*zoom,absMouseY+5*zoom); glVertex2f(absMouseX-5*zoom,absMouseY+5*zoom); glEnd(); if(selection) { float clicAbsMouseX = cx+(clicOldMouseX-width/2)*zoom*2; float clicAbsMouseY = cy+(clicOldMouseY-height/2)*zoom*2; glLineWidth(2); glBegin(GL_LINE_STRIP); glColor4d(0.0f, 0.0f, 0.0f, 0.3f); glVertex2f(absMouseX,clicAbsMouseY); glVertex2f(absMouseX,absMouseY); glVertex2f(clicAbsMouseX,absMouseY); glVertex2f(clicAbsMouseX,clicAbsMouseY); glVertex2f(absMouseX,clicAbsMouseY); glEnd(); } } return true; }