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 "actions/OE_actionsCurves.h"
#include "actions/OE_actionsStitchs.h"
#include "actions/OE_actionsLineStitchs.h"
#include "actions/OE_actionsBirailStitchs.h"
3dsman
committed
#include "actions/OE_actionsLinkStitchs.h"
#include "actions/OE_actionsSelection.h"
#include "actions/OE_actionsThreads.h"
OE_interfaceDisplay::OE_interfaceDisplay(QWidget *parent, Qt::WindowFlags f) : OE_display(parent, f)
{
editStyle = new OE_display::OE_displayStyle();
commandStyle = new OE_display::OE_displayStyle();
commandStyle->drawGrid = false;
commandStyle->drawCurves = false;
commandStyle->drawStitches = false;
commandStyle->drawCommands = true;
setDisplayStyle(editStyle);
modState = Qt::KeyboardModifier::NoModifier;
}
OE_interfaceDisplay::~OE_interfaceDisplay()
{
//delete curDisplay;
}
bool OE_interfaceDisplay::setDocument(OE_document* document)
{
this->document = document;
}
bool OE_interfaceDisplay::setController(OE_controller* controller)
{
this->controller = controller;
}
void OE_interfaceDisplay::showAll()
{
OE_display::showAll();
}
{
bool redraw = false;
redraw |= OE_display::mouse_Pos(x, y);
vector_2dt oldClosestPoint = editClosestPoint;
vector_2d absMove = vector_2d((mouse.x - clicOldMouse.x)*zoom*2, (mouse.y - clicOldMouse.y)*zoom*2);
if (editionState == MoveSelection) //if the move action is enabled
controller->editActionMoveSelection(vector_2d((mouse.x - clicOldMouse.x)*zoom*2,
(mouse.y - clicOldMouse.y)*zoom*2));
if (editionState == ScaleSelection) //if the scale action is enabled
{
vector_2d bbCenter = controller->getSelectionBoundingBox().getCenter();
float scale = (absMouse-bbCenter).len()/(screenToDocument(clicOldMouse)-bbCenter).len();
controller->editActionScaleSelection(vector_2d(scale,scale));
if (editionState == NewSubcurve) //if we must find the closest subcurve (get the closest point on it too)
{
closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
redraw = true;
}
else if (editSubcurve) //if we are working on a defined subcurve get the closest point on it
{
editClosestPoint = controller->getClosestPoint(editSubcurve->getCurve(), absMouse);
if (editionState == MovePointcurve && selControlCurve && selControlType==0) //if we're moving a curve control point
controller->editActionMovePointCurve(vector_2d((mouse.x - clicOldMouse.x)*zoom*2,
(mouse.y - clicOldMouse.y)*zoom*2));
3dsman
committed
if (editionState == MovePointstitch) //if we're moving a linkstitch control point
{
controller->editActionMovePointLinkStitch(absMove);
controller->editActionMoveGridPointFillStitch(absMove);
3dsman
committed
}
//if we're editing the scaleWidth of a linestitch
if (editionState == OffsetWidthLinestitch)
controller->editActionSetLinestitchWidth((mouse.x - clicOldMouse.x)/100.0f, true);
//if we're define a new subcurve and the reference curve is already picked
if ((editionState == NewSubcurve)&&(selControlStitch))
{
editionState = TraceSubcurve;
if (oldClosestPoint.t>editClosestPoint.t) controller->editActionAddSubcurvePosSwitchDir();
}
if (editionState == TraceSubcurve)
{
controller->editActionAddSubcurvePosEnd(editClosestPoint.t);
}
else if (editionState == MoveSubcurve)
{
controller->editActionSetSubcurvePos(editClosestPoint.t);
}
{
bool redraw = false;
redraw |= OE_display::mouse_Button(event);
if (curScreen == edit && event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress)
if (editionState == NewSubcurve)
{
if (!closestCurve)
{
editionState = None;
}
controller->addAction(new OE_actionJoincurveAddSubCurve(document, curJoincurve, subcurve_id, closestCurve,
selControlStitch = controller->getStitch(-1);
selControlType = 0;
//editSubcurve = curJoincurve->getCurve(-1);
editSubcurve = curJoincurve->getCurve(subcurve_id);
editionState = Selection;
if (curScreen == edit && event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonRelease)
selControlCurve = nullptr;
selControlStitch = nullptr;
if (editionState == AddSubcurve)
{
//curJoincurve = controller->getLineStitch(-1)->getJoincurve();
//closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
editionState = NewSubcurve;
joincurve_id = 0;
{
if ((mouse-clicOldMouse).len()>5)
selectBox();
selectApply(selectedCurves, selectedStitches);
editionState = None;
}
if ((editionState == NewSubcurve)||(editionState == TraceSubcurve))
if (joincurve_id == 0)
{
editionState = None;
}
else
{
editionState = NewSubcurve;
curJoincurve = controller->getBirailStitch(-1)->getJoincurve2();
closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
joincurve_id -= 1;
}
editionState = None;
}
}
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);
}
{
static QString writeFilters = QString::fromStdString(OE_document::getWriteDialogFilters());
static QString readFilters = QString::fromStdString(OE_document::getReadDialogFilters());
if (event->type() == QEvent::KeyPress)
modState = event->modifiers();
else
modState = Qt::KeyboardModifier::NoModifier;
if (event->type() == QEvent::KeyPress && curScreen == edit)
if (event->key() == Qt::Key_R && event->modifiers() == Qt::NoModifier)
if (editionState == TraceSubcurve)
controller->editActionAddSubcurvePosSwitchDir();
update();
else if (editionState == MoveSubcurve)
controller->editActionSetSubcurvePosSwitchDir();
update();
if(editionState==None)
if (event->key() == Qt::Key_Z && event->modifiers() == Qt::ControlModifier)
controller->undoAction();
update();
else if (event->key() == Qt::Key_S && event->modifiers() == Qt::ControlModifier)
if (document)
QString fileName = QFileDialog::getSaveFileName(this, "Save design", "", writeFilters);
if (!fileName.isEmpty())
{
document->saveToFile(fileName.toStdString());
}
else if (event->key() == Qt::Key_O && event->modifiers() == Qt::ControlModifier)
QString fileName = QFileDialog::getOpenFileName(this, "Open design", "", readFilters, &type);
loadFile(fileName.toStdString());
update();
else if (event->key() == Qt::Key_Z && event->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier))
if (controller)
{
controller->redoAction();
update();
else if (event->modifiers() == Qt::NoModifier)
if (controller)
controller->toggleCloseSelectedCurve();
update();
{
//TODO create an action to delete all selected stitches
std::list<OE_stitchs*>::iterator it=selectedStitches.begin();
controller->addAction(new OE_actionDelStitch(document, *it));
update();
{
std::list<OE_stitchs*>::iterator it=selectedStitches.begin();
if (it != selectedStitches.end())
{
it = std::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);
update();
}
}
}
std::list<OE_stitchs*>::iterator it=selectedStitches.begin();
if (it != selectedStitches.end())
it = std::find (document->stitchs.begin(), document->stitchs.end(), *it);
if (it != document->stitchs.begin())
{
it--;
selectedStitches.clear();
selectedStitches.push_back(*it);
controller->clearSelection();
controller->selectStitches(selectedStitches,true);
update();
}
}
}
{
if (editionState == TraceSubcurve)
{
controller->editActionAddSubcurvePosSwitchDir();
update();
}
else if (editionState == MoveSubcurve)
{
controller->editActionSetSubcurvePosSwitchDir();
update();
update();
if (curScreen == edit)
{
curScreen = command;
setDisplayStyle(commandStyle);
update();
}
else
{
curScreen = edit;
setDisplayStyle(editStyle);
update();
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;
subcurve_id = -1;
update();
controller->newBirailStitch(false, false, 0, 0, 0.7f);
document->selectedStitchs.push_back(controller->getBirailStitch(-1));
curJoincurve = controller->getBirailStitch(-1)->getJoincurve1();
closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
editionState = NewSubcurve;
joincurve_id = 1;
subcurve_id = -1;
update();
controller->newFillStitch(1.5f, 0.3f, controller->getPattern(0));
document->selectedStitchs.push_back(controller->getFillStitch(-1));
curJoincurve = controller->getFillStitch(-1)->getJoincurve();
closestCurve = controller->getClosestCurve(absMouse, editClosestPoint);
editionState = NewSubcurve;
joincurve_id = 0;
update();
{
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 (event->key() == Qt::Key_Plus && event->modifiers() & Qt::KeypadModifier)
if (event->modifiers() & Qt::ControlModifier)
controller->addAction(new OE_actionScaleSelectedStitchLen(document, 1.1f));
update();
controller->addAction(new OE_actionScaleSelectedStitchWidth(document, 1.1f));
update();
else if (event->key() == Qt::Key_Minus && event->modifiers() & Qt::KeypadModifier)
if (event->modifiers() & Qt::ControlModifier)
controller->addAction(new OE_actionScaleSelectedStitchLen(document, 1.f/1.1f));
update();
controller->addAction(new OE_actionScaleSelectedStitchWidth(document, 1.f/1.1f));
update();
else if (event->key() == Qt::Key_1 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(0)));
update();
else if (event->key() == Qt::Key_2 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(1)));
update();
else if (event->key() == Qt::Key_3 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(2)));
update();
else if (event->key() == Qt::Key_4 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(3)));
update();
else if (event->key() == Qt::Key_5 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(4)));
update();
else if (event->key() == Qt::Key_6 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(5)));
update();
else if (event->key() == Qt::Key_7 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(6)));
update();
else if (event->key() == Qt::Key_8 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(7)));
update();
else if (event->key() == Qt::Key_9 && event->modifiers() & Qt::KeypadModifier)
controller->addAction(new OE_actionSetSelectedStitchPattern(document, controller->getPattern(8)));
update();
3dsman
committed
update();
3dsman
committed
}
}
selectedCurves.clear();
selectedStitches.clear();
vector_2d clicAbsMouse = viewPos+(clicOldMouse-vector_2d(width,height)/2)*zoom*2;
std::list<OE_pointcurve*>::iterator curve = document->curves.begin();
while (curve != document->curves.end())
{
BoundingBox box = (*curve)->getBound();
if ((box.getMin().x > std::min(clicAbsMouse.x, absMouse.x))
&&(box.getMax().x < std::max(clicAbsMouse.x, absMouse.x))
&&(box.getMin().y > std::min(clicAbsMouse.y, absMouse.y))
&&(box.getMax().y < std::max(clicAbsMouse.y, absMouse.y)))
{
selectedCurves.push_back(*curve);
}
curve++;
}
std::list<OE_stitchs*>::iterator stitch = document->stitchs.begin();
while (stitch != document->stitchs.end())
{
if ((box.getMin().x > std::min(clicAbsMouse.x, absMouse.x))
&&(box.getMax().x < std::max(clicAbsMouse.x, absMouse.x))
&&(box.getMin().y > std::min(clicAbsMouse.y, absMouse.y))
&&(box.getMax().y < std::max(clicAbsMouse.y, absMouse.y)))
{
selectedStitches.push_back(*stitch);
}
stitch++;
}
bool OE_interfaceDisplay::checkJoinCurveControl(OE_joincurve* joinCurve, int &index)
{
if (selControlType == index)
{
// get the corresponding subcurve
editSubcurve = joinCurve->getCurve(selControlIndex/2);
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(document, editSubcurve, selControlIndex%2, pos.t));
return true;
}
return false;
}
index++;
if (selControlType == index)
{
editionState = AddSubcurve;
subcurve_id = selControlIndex;
curJoincurve = joinCurve;
return true;
}
index++;
return false;
}
bool OE_interfaceDisplay::pickingTool(int toolType, int toolIndex)
if (toolType == ZEROID) //zero
{
}
if (toolType == TRANSTOOLID) //one of the transform selection tools
{
if (toolIndex == MOVETOOLID) //move selection tools
{
return pickingMoveTool();
}
if (toolIndex == SCALETOOLID) //scale selection tools
{
return pickingScaleTool();
}
}
return false;
}
bool OE_interfaceDisplay::pickingMoveTool()
{
editionState = MoveSelection;
controller->addAction(new OE_actionMoveSelection(document, vector_2d(0,0)));
return true;
}
bool OE_interfaceDisplay::pickingScaleTool()
{
editionState = ScaleSelection;
controller->addAction(new OE_actionScaleSelection(document, vector_2d(1,1), controller->getSelectionBoundingBox().getCenter()));
return true;
}
bool OE_interfaceDisplay::pickingStitch(int stitchIndex)
{
if (stitchIndex >= document->stitchs.size())
{
return false;
}
std::list<OE_stitchs*>::iterator it = document->stitchs.begin();
std::advance(it, stitchIndex);
selectedStitches.push_back(*it);
return true;
}
3dsman
committed
bool OE_interfaceDisplay::pickingStitchControl(int stitchIndex, int ctrlType, int ctrlIndex)
{
if (stitchIndex >= document->selectedStitchs.size())
{
return false;
}
std::list<OE_stitchs*>::iterator it = document->selectedStitchs.begin();
std::advance(it, stitchIndex);
selControlStitch = *it;
selControlType = ctrlType;
selControlIndex = ctrlIndex;
int ControlTypeIndex = 0;
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
OE_linestitch* tmpLineStitch = dynamic_cast<OE_linestitch*>(selControlStitch);
if (tmpLineStitch)
{
// check generic joinCurve controls
if (checkJoinCurveControl(tmpLineStitch->getJoincurve(), ControlTypeIndex)) return true;
//check picking for linestitch width controller
if (selControlType == ControlTypeIndex && selControlIndex == 0)
{
editionState = OffsetWidthLinestitch;
controller->addAction(new OE_actionSetLineStitchWidth(document, tmpLineStitch, tmpLineStitch->getWidth()));
return true;
}
}
OE_birailstitch* tmpBirailStitch = dynamic_cast<OE_birailstitch*>(selControlStitch);
if (tmpBirailStitch)
{
// check generic joinCurve controls for each birail's joincurve
if (checkJoinCurveControl(tmpBirailStitch->getJoincurve1(), ControlTypeIndex)) return true;
if (checkJoinCurveControl(tmpBirailStitch->getJoincurve2(), ControlTypeIndex)) return true;
return false;
}
OE_fillstitch* tmpFillStitch = dynamic_cast<OE_fillstitch*>(selControlStitch);
if (tmpFillStitch)
{
// check generic joinCurve controls
if (checkJoinCurveControl(tmpFillStitch->getJoincurve(), ControlTypeIndex)) return true;
// check picking for grid's controller points
else if (selControlType == ControlTypeIndex)
{
editionState = MovePointstitch;
//edit gridpoint
controller->addAction(new OE_actionMovePointFillStitch(document, tmpFillStitch, selControlIndex, vector_2d(0,0)));
return true;
}
return false;
}
OE_linkstitch* tmpLinkStitch = dynamic_cast<OE_linkstitch*>(selControlStitch);
if (tmpLinkStitch)
{
//check picking of control point, add or delete
if (selControlType == 0)
{
editionState = MovePointstitch;
controller->addAction(new OE_actionMovePointLinkStitch(document, tmpLinkStitch, selControlIndex, vector_2d()));
return true;
}
else if (selControlType == 1)
{
editionState = MovePointstitch;
controller->addAction(new OE_actionAddPointLinkStitch(document, tmpLinkStitch, selControlIndex, absMouse));
return true;
}
else if (selControlType == 2)
{
editionState = DelPointstitch;
controller->addAction(new OE_actionDelPointLinkStitch(document, tmpLinkStitch, selControlIndex));
return true;
}
return false;
}
selControlStitch = nullptr;
return false;
}
bool OE_interfaceDisplay::pickingCurve(int curveIndex)
{
if (curveIndex >= document->curves.size())
{
return false;
}
std::list<OE_pointcurve*>::iterator it = document->curves.begin();
std::advance(it, curveIndex);
selectedCurves.push_back(*it);
return true;
}
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
bool OE_interfaceDisplay::pickingCurveControl(int curveIndex, int ctrlType, int ctrlIndex)
{
if (curveIndex >= document->selectedCurves.size())
{
return false;
}
std::list<OE_pointcurve*>::iterator it = document->selectedCurves.begin();
std::advance(it, curveIndex);
selControlCurve = *it;
selControlType = ctrlType;
selControlIndex = ctrlIndex;
OE_pointcurve* tmpPointCurve = dynamic_cast<OE_pointcurve*>(selControlCurve);
if (tmpPointCurve && selControlType == 0)
{
editionState = MovePointcurve;
controller->addAction(new OE_actionMovePointCurve(document, tmpPointCurve,
selControlIndex+1,
vector_2d(0,0)));
return true;
}
selControlCurve = nullptr;
return false;
/** \brief set selection
*
* \return true if all is ok
*
*/
bool OE_interfaceDisplay::drawPicking()
GLuint selectBuf[64];
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
selectedCurves.clear();
ptr = static_cast<GLuint*>(selectBuf);
for (GLint i=0; i<hits; i++) // for each hit
{
GLuint names = *ptr;
ptr+=3; //skip nearZ and farZ info (we don't use it) and goto first index
//in *ptr we got "item type", "item id" then, if we picked a control "control type" and at last "control id"
switch(*ptr) {
case TOOLSSELID :
return pickingTool(*(ptr+1), *(ptr+2));
break;
case STITCHSSELID :
if (names==2) //we picked an item
return pickingStitch(*(ptr+1));
else if (names==4) //we've got a control
return pickingStitchControl(*(ptr+1), *(ptr+2), *(ptr+3));
break;
case CURVESSELID:
if (names==2)
return pickingCurve(*(ptr+1));
else if (names==4)
return pickingCurveControl(*(ptr+1), *(ptr+2), *(ptr+3));
break;
}
}
return true;
3dsman
committed
bool OE_interfaceDisplay::selectApply(std::list<OE_pointcurve*> selectedCurves, std::list<OE_stitchs*> selectedStitches)
{
controller->unselectCurves(selectedCurves);
}
else
{
controller->selectCurves(selectedCurves, !modState.testFlag(Qt::ShiftModifier));
{
controller->unselectStitches(selectedStitches);
}
else
{
controller->selectStitches(selectedStitches, !modState.testFlag(Qt::ShiftModifier));
3dsman
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()
{
if (!document)
{
return false;
}
//TODO remove controller->sendInstPoint();
OE_display::draw();
//draw the closest point
if (editionState==NewSubcurve)
// Points
glPointSize(5.0f);
glBegin(GL_POINTS);
if (joincurve_id == 0)
glVertex2f(editClosestPoint.v.x,editClosestPoint.v.y);
glEnd();
// draw the cursor cross
glLineWidth(1.5);
glBegin(GL_LINES);
if (editionState)
glColor4f(0.8f, 0.0f, 0.0f, 0.5f);
glColor4f(0.0f, 0.8f, 0.0f, 0.5f);
glColor4fv(style->cursorColor.rgba);
}
glVertex2f(absMouse.x,-10000);
glVertex2f(absMouse.x,10000);
glVertex2f(-10000,absMouse.y);
glVertex2f(10000,absMouse.y);
glEnd();
// draw the cursor picking zone
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glColor4fv(style->cursorColor.rgba);
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();
if (editionState == Selection)
{
vector_2d clicAbsMouse = viewPos+(clicOldMouse-vector_2d(width,height)/2)*zoom*2;
glBegin(GL_LINE_STRIP);
glColor4fv(style->cursorColor.rgba);
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);
return true;
}