From: Dimitrios Eftaxiopoulos Date: Tue, 27 Jan 2015 13:54:34 +0000 (+0200) Subject: Merge tag 'upstream/2.3.1' into experimental X-Git-Tag: archive/raspbian/2.5-2+rpi1^2~117 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=60ca4b7ec04e0f52ed7e6901168820fa99626788;p=mathgl.git Merge tag 'upstream/2.3.1' into experimental Upstream version 2.3.1 Conflicts: widgets/qt.cpp --- 60ca4b7ec04e0f52ed7e6901168820fa99626788 diff --cc widgets/qt.cpp.orig index 0000000,0000000..3c0d741 new file mode 100644 --- /dev/null +++ b/widgets/qt.cpp.orig @@@ -1,0 -1,0 +1,1295 @@@ ++/*************************************************************************** ++ * qt.cpp is part of Math Graphic Library * ++ * Copyright (C) 2007-2014 Alexey Balakin * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU Library General Public License as * ++ * published by the Free Software Foundation; either version 3 of the * ++ * License, or (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU Library General Public * ++ * License along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ++ ***************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mgl2/canvas_wnd.h" ++#include "mgl2/qmathgl.h" ++#include "mgl2/qt.h" ++//----------------------------------------------------------------------------- ++#define MGL_MAX_LINES (INT_MAX-1000) ++#if !defined(WIN32) && !defined(__APPLE__) ++#include ++<<<<<<< HEAD ++//#include ++======= ++>>>>>>> upstream/2.3.1 ++#endif ++//----------------------------------------------------------------------------- ++/// Base class for windows containing MathGL graphics ++class mglCanvasQT : public mglCanvasWnd ++{ ++public: ++using mglCanvasWnd::Window; ++ int sshow; ///< Current state of animation switch (toggle button) ++ QMathGL *QMGL; ///< Control which draw graphics ++ QMainWindow *Wnd; ///< Pointer to window ++ ++ mglCanvasQT(); ++ virtual ~mglCanvasQT() { if(Wnd) delete Wnd; } ++ ++ /// Create a window for plotting. Now implemeted only for GLUT. ++ void Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p),const char *title, ++ void *par=NULL, void (*reload)(void *p)=NULL, bool maximize=false); ++ /// Switch on/off transparency (do not overwrite switches in user drawing function) ++ void ToggleAlpha(); ++ /// Switch on/off lighting (do not overwrite switches in user drawing function) ++ void ToggleLight(); ++ void ToggleRotate();///< Switch on/off rotation by mouse ++ void ToggleZoom(); ///< Switch on/off zooming by mouse ++ void ToggleNo(); ///< Switch off all zooming and rotation ++ void Update(); ///< Update picture by calling user drawing function ++ void Adjust(); ///< Adjust size of bitmap to window size ++ void GotoFrame(int d); ///< Show arbitrary frame (use relative step) ++ void Animation(); ///< Run slideshow (animation) of frames ++ ++protected: ++ QScrollArea *scroll; ///< Scrolling area ++ QMenu *popup; ///< Popup menu ++ QSpinBox *tet, *phi; ///< Spin box for angles ++}; ++//----------------------------------------------------------------------------- ++void MGL_EXPORT mgl_ask_qt(const wchar_t *quest, wchar_t *res) ++{ QInputDialog::getText(QApplication::activeWindow(), "MathGL", ++ QString::fromWCharArray(quest)).toWCharArray(res); } ++//----------------------------------------------------------------------------- ++// ++// class QMathGL ++// ++//----------------------------------------------------------------------------- ++/// Internal class to be used for multi-threading plotting ++/*class mglTask : public QObject ++{ ++ Q_OBJECT ++public: ++ mglCanvas *gr; ///< Built-in mglCanvasQT-er instance (used by default) ++ void *draw_par; ///< Parameters for drawing function mglCanvasWnd::DrawFunc. ++ /// Drawing function for window procedure. It should return the number of frames. ++ int (*draw_func)(mglBase *gr, void *par); ++ mglDraw *draw; ///< Class for drawing -- need to call directly due to inheritance mechanism ++public slots: ++ void doWork(); ++signals: ++ void plotDone(); ++}; ++//----------------------------------------------------------------------------- ++void mglTask::doWork() ++{ ++ setlocale(LC_NUMERIC, "C"); ++ if(mgl_is_frames(gr)) mgl_new_frame(gr); ++ if(draw_func) draw_func(gr, draw_par); ++ else if(draw) { mglGraph g(gr); draw->Draw(&g); } ++ if(mgl_is_frames(gr)) mgl_end_frame(gr); ++ setlocale(LC_NUMERIC, ""); ++ gr->Finish(); ++ emit plotDone(); ++}*/ ++//----------------------------------------------------------------------------- ++QMathGL::QMathGL(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) ++{ ++ autoResize = false; draw_par = 0; draw_func = 0; ++ dotsRefr = true; ++ gr = new mglCanvas; appName = "MathGL"; ++ popup = 0; grBuf = 0; draw = 0; ++ phi = tet = per = 0; ++ x1 = y1 = ax1 = ay1 = 0; x2 = y2 = ax2 = ay2 = 1; ++ alpha = light = zoom = rotate = grid = viewYZ = custZoom = custDraw = false; ++ resize(600, 400); mgl_set_flag(gr, true, MGL_CLF_ON_UPD); ++ timer = new QTimer(this); ++ timerRefr = new QTimer(this); timerRefr->setInterval(100); ++ timerRefr->setSingleShot(true); ++ enableWheel = enableMouse = true; ++ connect(timer, SIGNAL(timeout()), this, SLOT(nextSlide())); ++ connect(timerRefr, SIGNAL(timeout()), this, SLOT(refreshHQ())); ++ ++/* thread = new QThread(); ++ task = new mglTask(); task->moveToThread(thread); ++ connect(thread, SIGNAL(started()), task, SLOT(doWork())); ++ connect(task, SIGNAL(plotDone()), thread, SLOT(quit())); ++ connect(thread, SIGNAL(finished()), this, SLOT(afterPlot()));*/ ++} ++//----------------------------------------------------------------------------- ++QMathGL::~QMathGL() ++{ ++ timer->stop(); timerRefr->stop(); ++ if(mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr); ++ if(grBuf) delete []grBuf; ++ if(draw) delete draw; ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setDotsPreview(bool d) ++{ dotsRefr = d; } ++//----------------------------------------------------------------------------- ++void QMathGL::setDraw(int (*func)(mglBase *gr, void *par), void *par) ++{ ++ if(draw) delete draw; draw = 0; ++ draw_func = func; draw_par = par; ++ emit usePrimChanged(draw_func || draw); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setDraw(mglDraw *dr) ++{ ++ if(draw) delete draw; ++ draw = dr; draw_func = 0; ++ emit usePrimChanged(draw_func || draw); ++} ++//----------------------------------------------------------------------------- ++double QMathGL::getRatio() { return double(mgl_get_width(gr))/mgl_get_height(gr); } ++void mgl_qt_event_func(void *) { QApplication::processEvents(); } ++//----------------------------------------------------------------------------- ++void QMathGL::setGraph(HMGL GR) ///< Set grapher object ++{ ++ mglCanvas *gg = dynamic_cast(GR); ++ if(!gg) return; ++ if(mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr); ++ gr=gg; mgl_use_graph(gg,1); ++ gr->SetEventFunc(mgl_qt_event_func, NULL); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::paintEvent(QPaintEvent *) ++{ ++ QPainter paint; ++ paint.begin(this); ++ paint.drawPixmap(0,0,pic); ++ if(zoom) paint.drawRect(x0,y0,xe-x0,ye-y0); ++ if(mgl_get_flag(gr,MGL_SHOW_POS) && !mousePos.isEmpty()) ++ paint.drawText(0,12,mousePos); ++ if(grid) ++ { ++ long i, d, h=pic.height(), w=pic.width(); ++ paint.setPen(QColor(192,192,192)); ++ for(i=1;i<10;i++) ++ { ++ paint.drawText(0,i*h/10,QString::number(1-i*0.1)); ++ paint.drawLine(0,i*h/10,w,i*h/10); ++ paint.drawText(i*w/10,h,QString::number(i*0.1)); ++ paint.drawLine(i*w/10,0,i*w/10,h); ++ } ++ paint.setPen(QColor(0,0,0)); ++ d = (h>w?w:h)/100; ++ if(mgl_is_frames(gr)) ++ for(i=0;i<(long)gr->Act.size();i++) ++ { ++ const mglActivePos &p=gr->Act[i]; ++ QRect rf(p.x-d/2,p.y-d/2-1,d,d); ++ paint.drawRect(rf); ++ paint.fillRect(rf,QBrush(QColor(127,255,63))); ++ } ++ } ++ paint.end(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::resizeEvent(QResizeEvent *ev) ++{ ++ if(autoResize && ev->size().width()>0 && ev->size().height()>0) ++ { mgl_set_size(gr, ev->size().width(), ev->size().height()); update(); } ++// else resize(graph->GetWidth(), graph->GetHeight()); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setPer(int p) ++{ ++ if(per!=p && p>=0 && p<100) ++ { per = 100*p; emit perChanged(p); refresh(); } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setPhi(int p) ++{ if(phi!=p) { phi = p; emit phiChanged(p); refresh(); } } ++//----------------------------------------------------------------------------- ++void QMathGL::setTet(int t) ++{ if(tet!=t) { tet = t; emit tetChanged(t); refresh(); } } ++//----------------------------------------------------------------------------- ++void QMathGL::setAlpha(bool a) ++{ if(alpha!=a) { alpha = a; emit alphaChanged(a); update(); } } ++//----------------------------------------------------------------------------- ++void QMathGL::setLight(bool l) ++{ if(light!=l) { light = l; emit lightChanged(l); update(); } } ++//----------------------------------------------------------------------------- ++void QMathGL::setGrid(bool g) ++{ if(grid!=g) { grid = g; emit gridChanged(g); refresh(); } } ++//----------------------------------------------------------------------------- ++void QMathGL::setViewYZ(bool a) ++{ if(viewYZ!=a) { viewYZ = a; emit viewYZChanged(a); refresh(); } } ++//----------------------------------------------------------------------------- ++void QMathGL::setRotate(bool r) ++{ ++ if(rotate!=r) ++ { zoom=false; rotate=r; refresh(); emit rotateChanged(r); } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setZoom(bool z) ++{ ++ if(zoom!=z) ++ { zoom=z; rotate=false; refresh(); ++ emit zoomChanged(z); emit rotateChanged(false); } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setCustZoom(bool z) { custZoom = z; } ++//----------------------------------------------------------------------------- ++void QMathGL::setCustDraw(bool z) { custDraw = z; } ++//----------------------------------------------------------------------------- ++void QMathGL::shiftDown() ++{ mreal d=(y2-y1)/4; y1+=d; y2+=d; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::shiftUp() ++{ mreal d=(y2-y1)/4; y1-=d; y2-=d; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::shiftRight() ++{ mreal d=(x2-x1)/4; x1-=d; x2-=d; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::shiftLeft() ++{ mreal d=(x2-x1)/4; x1+=d; x2+=d; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::zoomIn() ++{ ++ mreal d,c; ++ d = (y2-y1)/4; c = (y2+y1)/2; y1 = c-d; y2 = c+d; ++ d = (x2-x1)/4; c = (x2+x1)/2; x1 = c-d; x2 = c+d; ++ refresh(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::zoomOut() ++{ ++ mreal d,c; ++ d = (y2-y1); c = (y2+y1)/2; y1 = c-d; y2 = c+d; ++ d = (x2-x1); c = (x2+x1)/2; x1 = c-d; x2 = c+d; ++ refresh(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::restore() ++{ ++ setPhi(0); setTet(0); setPer(0); ++ x1=y1=0; x2=y2=1; zoom=rotate=false; ++ emit zoomChanged(false); emit rotateChanged(false); ++ if(ax1!=0 || ay1!=0 || ax2!=1 || ay2!=1) ++ { ++ ax1=ay1=0; ax2=ay2=1; ++ mgl_zoom_axis(gr,0,0,0,0,1,1,1,1); ++ update(); ++ } ++ else refresh(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::stop() { gr->AskStop(true); } ++//----------------------------------------------------------------------------- ++void QMathGL::update() ++{ ++ if(draw_func || draw) ++ { ++ mgl_reset_frames(gr); // remove previous frames ++ if(mgl_get_flag(gr,MGL_CLF_ON_UPD)) mgl_set_def_param(gr); ++ mgl_set_alpha(gr,alpha); mgl_set_light(gr,light); ++ // use frames for quickly redrawing while adding/changing primitives ++ if(custDraw) emit customDraw(x1,y1,x2,y2,true); ++ ++ if(!isHidden()) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); ++/* task->gr = gr; task->draw = draw; ++ task->draw_func = draw_func; ++ task->draw_par = draw_par; ++ thread->start();*/ ++ setlocale(LC_NUMERIC, "C"); ++ if(mgl_is_frames(gr)) mgl_new_frame(gr); ++ if(draw_func) draw_func(gr, draw_par); ++ else if(draw) { mglGraph g(gr); draw->Draw(&g); } ++ if(mgl_is_frames(gr)) mgl_end_frame(gr); ++ setlocale(LC_NUMERIC, ""); ++ gr->AskStop(false); afterPlot(); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::afterPlot() ++{ ++ emit refreshData(); ++ emit showWarn(mgl_get_mess(gr)); ++ mousePos=""; ++ if(!isHidden()) QApplication::restoreOverrideCursor(); ++ refresh(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::drawPrim() ++{ ++// mgl_clf_nfog(gr); ++ mglCanvasWnd *g = dynamic_cast(gr); ++ mgl_get_frame(gr, g?g->GetCurFig():mgl_get_num_frame(gr)-1); ++ mglParse pr; ++ long i, n=primitives.count('\n'); ++ mglGraph gg(gr); ++ setlocale(LC_NUMERIC, "C"); ++ gg.Push(); gg.SubPlot(1,1,0,"#"); ++ mglPoint ox1=gr->Min, ox2=gr->Max; ++ gg.SetRanges(mglPoint(-1,-1,-1),mglPoint(1,1,1)); ++ for(i=0;istart(); ++ int q = gr->GetQuality(); ++ prevQuality = q!=MGL_DRAW_DOTS?q:prevQuality; ++ gr->SetQuality(MGL_DRAW_DOTS); ++ } ++ if(mgl_is_frames(gr) && mgl_get_num_frame(gr)>0) ++ { ++ drawPrim(); ++ if(custZoom) emit customZoom(x1,y1,x2,y2,tet,phi,per); ++ else ++ { mgl_zoom(gr,x1,y1,x2,y2); ++ mgl_ask_perspective(gr,per); ++ if(viewYZ) mgl_view(gr,0,-tet,-phi); ++ else mgl_view(gr,-phi,-tet,0); ++ } ++ } ++ mglConvertFromGraph(pic, gr, &grBuf); ++ if(pic.size()!=size()) setSize(pic.width(), pic.height()); ++ repaint(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::refreshHQ() ++{ ++ gr->SetQuality(prevQuality); ++ if(mgl_is_frames(gr) && mgl_get_num_frame(gr)>0) ++ { ++ drawPrim(); ++ if(custZoom) emit customZoom(x1,y1,x2,y2,tet,phi,per); ++ else ++ { mgl_zoom(gr,x1,y1,x2,y2); ++ mgl_ask_perspective(gr,per); ++ if(viewYZ) mgl_view(gr,0,-tet,-phi); ++ else mgl_view(gr,-phi,-tet,0); ++ } ++ } ++ mglConvertFromGraph(pic, gr, &grBuf); ++ if(pic.size()!=size()) setSize(pic.width(), pic.height()); ++ repaint(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::mousePressEvent(QMouseEvent *ev) ++{ ++ if(!zoom && !rotate && ev->button()&Qt::LeftButton) ++ { ++ mglPoint p = gr->CalcXYZ(ev->x(), ev->y()); ++ mglCanvasWnd *g=dynamic_cast(gr); ++ if(g) g->LastMousePos = p; ++ if(g && g->ClickFunc) g->ClickFunc(draw_par); ++ emit mouseClick(p.x,p.y,p.z); ++ int id = mgl_get_obj_id(gr,ev->x(),ev->y()); ++ if(idCalcXYZ(ev->x(), ev->y(), true); ++ if(mgl_isnan(p.x)) mousePos = ""; ++ else mousePos.sprintf("x=%g, y=%g, z=%g",p.x,p.y,p.z); ++ emit posChanged(mousePos); ++ repaint(); ++ } ++ xe=x0=ev->x(); ye=y0=ev->y(); ev->accept(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::mouseReleaseEvent(QMouseEvent *ev) ++{ ++ if(ev->button()&Qt::LeftButton && enableMouse) ++ { ++ if(zoom) ++ { ++ int w1=width(),h1=height(); ++ mreal _x1,_x2,_y1,_y2; ++ _x1 = x1+(x2-x1)*(x0-x())/mreal(w1); _y1 = y2-(y2-y1)*(ye-y())/mreal(h1); ++ _x2 = x1+(x2-x1)*(xe-x())/mreal(w1); _y2 = y2-(y2-y1)*(y0-y())/mreal(h1); ++ x1=_x1; x2=_x2; y1=_y1; y2=_y2; ++ if(x1>x2) { _x1=x1; x1=x2; x2=_x1; } ++ if(y1>y2) { _x1=y1; y1=y2; y2=_x1; } ++ x0 = xe; y0 = ye; ++ if(custDraw) ++ { ++ emit customDraw(x1,y1,x2,y2,false); ++ update(); ++ } ++ else refresh(); ++ } ++ } ++ if(ev->button()&Qt::RightButton && popup && !rotate) // popup menu ++ popup->popup(QCursor::pos()); ++ ev->accept(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::mouseMoveEvent(QMouseEvent *ev) ++{ ++ if(!enableMouse) { ev->ignore(); return; } ++ xe=ev->x(); ye=ev->y(); ++ if(rotate) ++ { ++ if(ev->buttons()&Qt::LeftButton) // rotate ++ { ++ mreal ff = 240/sqrt(mreal(width()*height())); ++ phi += int((x0-xe)*ff); ++ tet -= int((y0-ye)*ff); ++ if(phi>180) phi-=360; if(phi<-180) phi+=360; ++ if(tet>180) tet-=360; if(tet<-180) tet+=360; ++ emit tetChanged(int(tet)); emit phiChanged(int(phi)); ++ refresh(); ++ } ++ if(ev->buttons()&Qt::RightButton) // zoom and perspective ++ { ++ mreal ff = 2.*(y0-ye)/width(), gg = 0.5*(xe-x0)/height(); ++ mreal cx = (x1+x2)/2, cy = (y1+y2)/2; ++ x1 = cx+(x1-cx)*exp(-ff); x2 = cx+(x2-cx)*exp(-ff); ++ y1 = cy+(y1-cy)*exp(-ff); y2 = cy+(y2-cy)*exp(-ff); ++ per = per + gg; ++ if(per<0) per = 0; if(per>=1) per = 0.9999; ++ if(gg) emit perChanged(int(per)); ++ refresh(); ++ } ++ if(ev->buttons()&Qt::MidButton) // shift ++ { ++ mreal ff = 1./sqrt(mreal(width()*height())); ++ mreal dx = (x0-xe)*ff*(x2-x1), dy = (y0-ye)*ff*(y2-y1); ++ x1 += dx; x2 += dx; y1 -= dy; y2 -= dy; ++ } ++ x0 = xe; y0 = ye; ++ refresh(); ++ } ++ else if(zoom) refresh(); ++ else if(ev->buttons()&Qt::MidButton) // shift axis ++ { ++ mreal ff = 1./sqrt(mreal(width()*height())); ++ mreal dx = (x0-xe)*ff*(ax2-ax1), dy = (y0-ye)*ff*(ay2-ay1); ++ ax1 += dx; ax2 += dx; ay1 -= dy; ay2 -= dy; ++ mgl_zoom_axis(gr,ax1,ay1,0,0,ax2,ay2,0,0); ++ update(); x0 = xe; y0 = ye; ++ } ++ else if(ev->buttons()&Qt::LeftButton) // move primitives ++ { ++ long h=pic.height(), w=pic.width(), d=(h>w?w:h)/100; ++ long pos = mgl_is_active(gr,x0,y0,d); ++ long id = long(mgl_get_obj_id(gr,x0,y0))-MGL_MAX_LINES; ++ if(grid && pos>=0) // this active point ++ { ++ const mglActivePos &p = gr->Act[pos]; ++ id = long(p.id)-MGL_MAX_LINES; ++ if(id>=0) // this is our primitive ++ { ++ // try "attract" mouse ++ register size_t i; ++ register int tt; ++ for(i=0;i<=10;i++) ++ { ++ tt = i*(w/10); if(abs(xe-tt)<2*d) xe = tt; ++ tt = i*(h/10); if(abs(ye-tt)<2*d) ye = tt; ++ } ++ for(i=0;iAct.size();i++) ++ { ++ const mglActivePos &q = gr->Act[i]; ++ if(abs(xe-q.x)<2*d && abs(ye-q.y)<2*d) { xe=q.x; ye=q.y; } ++ } ++ // now move point ++ QString tst = primitives.section('\n',id,id), cmd=tst.section(' ',0,0), res; ++ float dx = 2*(xe-x0)/float(w), dy = 2*(y0-ye)/float(h); ++ float xx=tst.section(' ',1,1).toFloat(), yy=tst.section(' ',2,2).toFloat(); ++ if(p.n==0) ++ res = cmd+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',3); ++ else if(cmd=="rect") ++ { ++ float x_=tst.section(' ',3,3).toFloat(), y_=tst.section(' ',4,4).toFloat(); ++ if(p.n==1) { xx+=dx; y_+=dy; } ++ if(p.n==2) { x_+=dx; yy+=dy; } ++ if(p.n==3) { x_+=dx; y_+=dy; } ++ res = "rect "+QString::number(xx)+" "+QString::number(yy)+" "+ ++ QString::number(x_)+" "+QString::number(y_)+" "+tst.section(' ',5); ++ } ++ else if(p.n==1) ++ { ++ xx=tst.section(' ',3,3).toFloat(); yy=tst.section(' ',4,4).toFloat(); ++ res = tst.section(' ',0,2)+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',5); ++ } ++ else if(cmd=="rhomb" || cmd=="ellipse") ++ { ++ float x_=tst.section(' ',3,3).toFloat()-xx, y_=tst.section(' ',4,4).toFloat()-yy, dr=0; ++ if(x_*x_+y_*y_>0) ++ { ++ dr = (dx*x_+dy*y_)/(x_*x_+y_*y_); ++ dr = hypot(dx-dr*x_,dy-dr*y_); ++ } ++ else dr = hypot(dx,dy); ++ res = tst.section(' ',0,4)+" "+QString::number(tst.section(' ',5,5).toFloat()+dr)+" "+tst.section(' ',6); ++ } ++ else if(cmd=="arc") ++ { ++ double x_=tst.section(' ',3,3).toFloat()-xx, y_=tst.section(' ',4,4).toFloat()-yy, a_=tst.section(' ',5,5).toFloat(); ++ double c=cos(M_PI*a_/180), s=sin(M_PI*a_/180); ++ double a = atan2(x_,y_) - atan2(x_*c-y_*s+dx,x_*s+y_*c+dy); ++ res = tst.section(' ',0,4)+" "+QString::number(a*180/M_PI)+" "+tst.section(' ',6); ++ } ++ else if(p.n==2) ++ { ++ xx=tst.section(' ',5,5).toFloat(); yy=tst.section(' ',6,6).toFloat(); ++ res = tst.section(' ',0,4)+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',7); ++ } ++ else if(p.n==3) ++ { ++ xx=tst.section(' ',7,7).toFloat(); yy=tst.section(' ',8,8).toFloat(); ++ if(cmd=="curve") { dx*=-1; dy*=-1; } ++ res = tst.section(' ',0,6)+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',9); ++ } ++ if(id>0) res = primitives.section('\n',0,id-1) + "\n" + res; ++ primitives = res + "\n" + primitives.section('\n',id+1); ++ refresh(); x0 = xe; y0 = ye; ++ } ++ } ++ else if(id>=0) // this is primitive ++ { ++ QString tst = primitives.section('\n',id,id), cmd=tst.section(' ',0,0), res; ++ float dx = 2*(xe-x0)/float(w), dy = 2*(y0-ye)/float(h); ++ float x1=tst.section(' ',1,1).toFloat(), y1=tst.section(' ',2,2).toFloat(),x2,y2; ++ if(cmd=="ball") ++ res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+tst.section(' ',3); ++ else if(cmd=="curve") ++ { ++ x2=tst.section(' ',5,5).toFloat(); y2=tst.section(' ',6,6).toFloat(); ++ res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+tst.section(' ',3,4)+ ++ " "+QString::number(x2+dx)+" "+QString::number(y2+dy)+" "+tst.section(' ',7); ++ } ++ else ++ { ++ x2=tst.section(' ',3,3).toFloat(); y2=tst.section(' ',4,4).toFloat(); ++ res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+ ++ QString::number(x2+dx)+" "+QString::number(y2+dy)+" "+tst.section(' ',5); ++ } ++ if(id>0) res = primitives.section('\n',0,id-1) + "\n" + res; ++ primitives = res + "\n" + primitives.section('\n',id+1); ++ refresh(); x0 = xe; y0 = ye; ++ } ++ } ++ ev->accept(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::mouseDoubleClickEvent(QMouseEvent *ev) ++{ ++ long h=pic.height(), w=pic.width(), d=(h>w?w:h)/100; ++ long pos = mgl_is_active(gr,x0,y0,d); ++ long id = long(mgl_get_obj_id(gr,x0,y0)); ++ if(grid && pos>=0) // this active point -> delete primitive ++ { ++ const mglActivePos &p = gr->Act[pos]; ++ id = long(p.id)-MGL_MAX_LINES; ++ QString res; ++ if(id>0) res = primitives.section('\n',0,id-1) + "\n"; ++ if(id>=0) primitives = res + primitives.section('\n',id+1); ++ refresh(); x0 = xe; y0 = ye; ++ } ++ else if(id>=MGL_MAX_LINES) // option for primitives ++ emit askStyle(id-MGL_MAX_LINES); ++ else emit doubleClick(id); ++ ev->accept(); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::setStyle(int id, QString stl) ++{ ++ QString tst = primitives.section('\n',id,id), res; ++ res = tst.section(' ',0,-2) + " " + stl; ++ if(id>0) res = primitives.section('\n',0,id-1) + "\n" + res; ++ primitives = res + "\n" + primitives.section('\n',id+1); ++ refresh(); x0 = xe; y0 = ye; ++} ++//----------------------------------------------------------------------------- ++void QMathGL::wheelEvent(QWheelEvent *ev) ++{ ++ if(!enableWheel) { ev->ignore(); return; } ++ if(rotate) // zoom ++ { ++ mreal d,c,f=exp(0.001*ev->delta())/2; ++ d = (y2-y1)*f; c = (y2+y1)/2; y1 = c-d; y2 = c+d; ++ d = (x2-x1)*f; c = (x2+x1)/2; x1 = c-d; x2 = c+d; ++ refresh(); ev->accept(); ++ } ++ else // zoom axis ++ { ++ mreal d,c,f=exp(0.001*ev->delta())/2; ++ d = (ay2-ay1)*f; c = (ay2+ay1)/2; ay1 = c-d; ay2 = c+d; ++ d = (ax2-ax1)*f; c = (ax2+ax1)/2; ax1 = c-d; ax2 = c+d; ++ mgl_zoom_axis(gr,ax1,ay1,0,0,ax2,ay2,0,0); ++ update(); ev->accept(); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::imgSize(int w, int h) ++{ if(w>0 && h>0) { mgl_set_size(gr,w,h); update(); } } ++//----------------------------------------------------------------------------- ++QString setExtension(QString &fname, const char *ext) ++{ ++ QString oname; ++ if(fname.right(4)!="."+QString(ext)) oname = fname+"."+QString(ext); ++ return oname; ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportGIF(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else mgl_write_gif(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str()); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportPNG(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else mgl_write_png(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str()); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportPNGs(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else mgl_write_png_solid(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str()); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportJPG(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else mgl_write_jpg(gr,setExtension(fname,"jpg").toStdString().c_str(), appName.toStdString().c_str()); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportBPS(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_bps(gr,setExtension(fname,"eps").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportEPS(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_eps(gr,setExtension(fname,"eps").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportSVG(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_svg(gr,setExtension(fname,"svg").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportXYZ(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_xyz(gr,setExtension(fname,"xyz").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportTEX(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_tex(gr,setExtension(fname,"tex").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportOFF(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_off(gr,setExtension(fname,"off").toStdString().c_str(), appName.toStdString().c_str(),0); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportOBJ(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_obj(gr,setExtension(fname,"obj").toStdString().c_str(), appName.toStdString().c_str(),1); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportSTL(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_stl(gr,setExtension(fname,"stl").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++/*void QMathGL::exportX3D(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_x3d(gr,setExtension(fname,"x3d").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++}*/ ++//----------------------------------------------------------------------------- ++void QMathGL::exportTGA(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_tga(gr,setExtension(fname,"tga").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportPRC(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_write_prc(gr,setExtension(fname,"prc").toStdString().c_str(), appName.toStdString().c_str(),1); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::exportMGLD(QString fname) ++{ ++ if(fname.isEmpty()) fname = mgl_get_plotid(gr); ++ if(fname.isEmpty()) QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0); ++ else ++ { ++ setlocale(LC_NUMERIC, "C"); ++ mgl_export_mgld(gr,setExtension(fname,"mgld").toStdString().c_str(), appName.toStdString().c_str()); ++ setlocale(LC_NUMERIC, ""); ++ } ++} ++//----------------------------------------------------------------------------- ++void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf) ++{ ++ const uchar *bb = mgl_get_rgb(gr); ++ register long i,w=mgl_get_width(gr), h=mgl_get_height(gr); ++ if(*buf) delete [](*buf); ++ *buf = new uchar[4*w*h]; ++ for(i=0;isetPixmap(pic, QClipboard::Clipboard); } ++//----------------------------------------------------------------------------- ++void QMathGL::copyClickCoor() ++{ QApplication::clipboard()->setText(mousePos); } ++//----------------------------------------------------------------------------- ++void QMathGL::setMGLFont(QString path) ++{ if(path.isEmpty()) mgl_restore_font(gr); ++ else mgl_load_font(gr,path.toStdString().c_str(),0); } ++//----------------------------------------------------------------------------- ++void QMathGL::setSize(int w, int h) ++{ ++ resize(w, h); ++ if(w!=pic.width() || h!=pic.height()) // update only when image size is changed ++ { mgl_set_size(gr,w,h); update(); } ++} ++//----------------------------------------------------------------------------- ++void QMathGL::about() ++{ ++ QString s = tr("MathGL v. 2.") + QString::number(MGL_VER2) + tr("\n(c) Alexey Balakin, 2007\nhttp://mathgl.sourceforge.net/"); ++ QMessageBox::about(this, tr("MathGL - about"), s); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::aboutQt() { QMessageBox::aboutQt(this, tr("About Qt")); } ++//----------------------------------------------------------------------------- ++void QMathGL::print() ++{ ++ QPrinter *printer = new QPrinter; ++ printer->setOrientation(getRatio()>1 ? QPrinter::Landscape : QPrinter::Portrait); ++ QPrintDialog printDlg(printer, this); ++ if (printDlg.exec() == QDialog::Accepted) ++ { ++ QRectF r = printer->pageRect(QPrinter::Inch); ++ int d1 = int(pic.width()/r.width()), d2 = int(pic.height()/r.height()); ++ int dpi = printer->resolution(); ++ if(dpisetResolution(dpi); ++ ++ QPainter p; ++ if(!p.begin(printer)) return; // paint on printer ++ p.drawPixmap(0,0,pic); ++ } ++ delete printer; ++} ++//----------------------------------------------------------------------------- ++void QMathGL::nextSlide() ++{ ++ mglCanvasWnd *g = dynamic_cast(gr); ++ if(g && g->GetNumFig()>1) g->NextFrame(); ++ emit frameChanged(+1); ++} ++void QMathGL::prevSlide() ++{ ++ mglCanvasWnd *g = dynamic_cast(gr); ++ if(g && g->GetNumFig()>1) g->PrevFrame(); ++ emit frameChanged(-1); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::animation(bool st) ++{ ++ if(st) timer->stop(); ++ else timer->start(int(mgl_wnd_get_delay(gr)*1000)); ++} ++//----------------------------------------------------------------------------- ++void QMathGL::adjust() ++{ ++ mgl_set_size(gr, parentWidget()->width()-3, parentWidget()->height()-3); ++ setSize(parentWidget()->width()-3, parentWidget()->height()-3); ++ update(); // TODO replace to refresh ?!? ++} ++//----------------------------------------------------------------------------- ++void QMathGL::addMark() ++{ primitives += "ball 0 0 'r*'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addLine() ++{ primitives += "line -0.2 0 0.2 0 'r2'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addRect() ++{ primitives += "rect -0.2 -0.2 0.2 0.2 'r'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addCurve() ++{ primitives += "curve -0.2 0 0 0.5 0.2 0 0 0.5 'r2'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addRhomb() ++{ primitives += "rhomb -0.2 0 0.2 0 0.1 'r'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addEllipse() ++{ primitives += "ellipse -0.2 0 0.2 0 0.1 'r'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addArc() ++{ primitives += "arc 0 0 0.2 0 60 'r2'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addPolygon(int n) ++{ ++ if(n<3) ++ n = QInputDialog::getText(QApplication::activeWindow(), "MathGL", tr("Enter number of vertexes")).toInt(); ++ if(n>=3) ++ { primitives += "polygon 0 0 0 0.2 "+QString::number(n)+" 'r'\n"; refresh(); } ++} ++//{ primitives += "arc -0.2 0 0.2 0 0.1 'r'\n"; refresh(); } ++//----------------------------------------------------------------------------- ++void QMathGL::addText(QString txt) ++{ ++ if(txt.isEmpty()) ++ txt = QInputDialog::getText(QApplication::activeWindow(), "MathGL", tr("Enter text")); ++ if(!txt.isEmpty()) ++ { primitives += "text 0 0 0.1 0 '"+txt+"' ''\n"; refresh(); } ++} ++//----------------------------------------------------------------------------- ++// ++// class mglCanvasQT ++// ++//----------------------------------------------------------------------------- ++mglCanvasQT::mglCanvasQT() : mglCanvasWnd() ++{ Wnd = 0; } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::GotoFrame(int d) ++{ ++ int f = GetCurFig()+d; ++ if(f>=GetNumFig()) f = 0; ++ if(f<0) f = GetNumFig()-1; ++ if(GetNumFig()>0 && d) { SetCurFig(f); QMGL->refresh(); } ++} ++//----------------------------------------------------------------------------- ++void mglCanvasQT::Animation() { QMGL->animation(true); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::ToggleAlpha() { QMGL->setAlpha(!QMGL->getAlpha()); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::ToggleLight() { QMGL->setLight(!QMGL->getLight()); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::ToggleNo() { QMGL->restore(); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::ToggleZoom() { QMGL->setZoom(!QMGL->getZoom()); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::ToggleRotate(){ QMGL->setRotate(!QMGL->getRotate());} ++//----------------------------------------------------------------------------- ++void mglCanvasQT::Update() { SetCurFig(0); QMGL->update(); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::Adjust() { QMGL->adjust(); } ++//----------------------------------------------------------------------------- ++void mglCanvasQT::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title, void *par, void (*reload)(void *p), bool maximize) ++{ ++ SetDrawFunc(draw, par, reload); ++ if(Wnd) ++ { ++ Wnd->setWindowTitle(title); ++ if(maximize) ++ { Wnd->showMaximized(); } ++ else Wnd->show(); ++ return; ++ } ++ ++ if(!qApp) ++ { ++#if !defined(WIN32) && !defined(__APPLE__) ++ // try to fix possible multi-threading errors ++ // must be placed before ANY window creation ++ XInitThreads(); ++#endif ++// static char buf=0, *tmp=&buf; ++// if(!argv) { argc = 1; argv = &tmp; } ++ if(!argv) argc = 0; ++ QApplication *a = new QApplication(argc, argv); ++ a->connect(a, SIGNAL(lastWindowClosed()), a, SLOT(quit())); ++ } ++ ++ Wnd = new QMainWindow; Wnd->resize(850,680); ++ Wnd->setWindowTitle(title); ++ scroll = new QScrollArea(Wnd); ++ ++ QMGL = new QMathGL(Wnd); ++ popup = mglMakeMenu(Wnd, QMGL, tet, phi); ++ QMGL->setPopup(popup); QMGL->setGraph(this); ++ QMGL->setDraw(draw, par); ++ QMGL->appName = title; ++ qApp->processEvents(); ++ scroll->setWidget(QMGL); ++ Wnd->setCentralWidget(scroll); ++ QMGL->refresh(); ++ if(!maximize) Wnd->show(); ++ else Wnd->showMaximized(); ++} ++//----------------------------------------------------------------------------- ++#include "xpm/alpha.xpm" ++#include "xpm/arc.xpm" ++#include "xpm/copy.xpm" ++#include "xpm/curve.xpm" ++#include "xpm/down_1.xpm" ++#include "xpm/fileprint.xpm" ++#include "xpm/left_1.xpm" ++#include "xpm/light.xpm" ++#include "xpm/line.xpm" ++#include "xpm/mark_a.xpm" ++#include "xpm/mark_d.xpm" ++#include "xpm/mark_o.xpm" ++#include "xpm/mark_s.xpm" ++#include "xpm/right_1.xpm" ++#include "xpm/next_sl.xpm" ++#include "xpm/norm_1.xpm" ++#include "xpm/ok.xpm" ++#include "xpm/prev_sl.xpm" ++#include "xpm/rotate.xpm" ++#include "xpm/show_sl.xpm" ++#include "xpm/text.xpm" ++#include "xpm/polygon.xpm" ++#include "xpm/zoom_1.xpm" ++#include "xpm/zoom_in.xpm" ++#include "xpm/zoom_out.xpm" ++#include "xpm/up_1.xpm" ++#include "xpm/stop.xpm" ++//----------------------------------------------------------------------------- ++#define TR QObject::tr ++MGL_EXPORT QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&phi) ++{ ++ QAction *a; ++ QMenu *o, *oo; ++ QToolBar *bb; ++ ++ QMenu *popup = new QMenu(Wnd); ++ // file menu ++ { ++ o = Wnd->menuBar()->addMenu(TR("&File")); ++ oo = new QMenu(TR("&Export as 2D ..."),Wnd); ++ oo->addAction(TR("PNG"), QMGL, SLOT(exportPNG()),Qt::ALT+Qt::Key_P); ++ oo->addAction(TR("solid PNG"), QMGL, SLOT(exportPNGs()),Qt::ALT+Qt::Key_F); ++ oo->addAction(TR("JPEG"), QMGL, SLOT(exportJPG()),Qt::ALT+Qt::Key_J); ++ oo->addAction(TR("bitmap EPS"), QMGL, SLOT(exportBPS())); ++ oo->addAction(TR("vector EPS"), QMGL, SLOT(exportEPS()),Qt::ALT+Qt::Key_E); ++ oo->addAction(TR("SVG"), QMGL, SLOT(exportSVG()),Qt::ALT+Qt::Key_S); ++ oo->addAction(TR("LaTeX"), QMGL, SLOT(exportTEX()),Qt::ALT+Qt::Key_L); ++ o->addMenu(oo); popup->addMenu(oo); ++ oo = new QMenu(TR("&Export as 3D ..."),Wnd); ++ oo->addAction(TR("MGLD"), QMGL, SLOT(exportMGLD()),Qt::ALT+Qt::Key_M); ++ oo->addAction(TR("PRC"), QMGL, SLOT(exportPRC()),Qt::ALT+Qt::Key_D); ++ oo->addAction(TR("OBJ"), QMGL, SLOT(exportOBJ()),Qt::ALT+Qt::Key_O); ++ oo->addAction(TR("STL"), QMGL, SLOT(exportSTL())); ++ oo->addAction(TR("XYZ"), QMGL, SLOT(exportXYZ())); ++// oo->addAction(TR("X3D"), QMGL, SLOT(exportX3D()),Qt::ALT+Qt::Key_X); ++ o->addMenu(oo); popup->addMenu(oo); ++ ++ o->addSeparator(); ++ a = new QAction(QPixmap(fileprint), TR("Print &graphics"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(print())); ++ a->setToolTip(TR("Open printer dialog and print graphics\t(CTRl+P)")); ++ a->setShortcut(Qt::CTRL+Qt::Key_P); o->addAction(a); ++ o->addSeparator(); ++ o->addAction(TR("&Close"), Wnd, SLOT(close()), Qt::CTRL+Qt::Key_W); ++ } ++ // graphics menu ++ { ++ bb = new QToolBar(TR("Graphics"),Wnd); ++ Wnd->addToolBar(Qt::TopToolBarArea, bb); ++ o = Wnd->menuBar()->addMenu(TR("&Graphics")); ++ a = new QAction(QPixmap(alpha_xpm), TR("&Alpha"), Wnd); ++ a->setShortcut(Qt::ALT+Qt::Key_T); a->setCheckable(true); ++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setAlpha(bool))); ++ Wnd->connect(QMGL, SIGNAL(alphaChanged(bool)), a, SLOT(setChecked(bool))); ++ a->setToolTip(TR("Switch on/off TRansparency for the graphics (Alt+T).")); ++ o->addAction(a); bb->addAction(a); ++ a = new QAction(QPixmap(light_xpm), TR("&Light"), Wnd); ++ a->setShortcut(Qt::ALT+Qt::Key_L); a->setCheckable(true); ++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setLight(bool))); ++ Wnd->connect(QMGL, SIGNAL(lightChanged(bool)), a, SLOT(setChecked(bool))); ++ a->setToolTip(TR("Switch on/off lightning for the graphics (Alt+L).")); ++ o->addAction(a); bb->addAction(a); ++ a = new QAction(QPixmap(rotate_xpm), TR("&Rotate by mouse"), Wnd); ++ a->setCheckable(true); ++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setRotate(bool))); ++ Wnd->connect(QMGL, SIGNAL(rotateChanged(bool)), a, SLOT(setChecked(bool))); ++ a->setToolTip(TR("Switch on/off mouse handling of the graphics\n(rotation, shifting, zooming and perspective).")); ++ bb->addAction(a); ++ a = new QAction(QPixmap(zoom_in_xpm), TR("&Zoom by mouse"), Wnd); ++ a->setCheckable(true); ++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setZoom(bool))); ++ Wnd->connect(QMGL, SIGNAL(zoomChanged(bool)), a, SLOT(setChecked(bool))); ++ a->setToolTip(TR("Switch on/off mouse zoom of selected region.")); ++ bb->addAction(a); ++ o->addSeparator(); ++ a = new QAction(QPixmap(zoom_out_xpm), TR("Res&tore"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(restore())); ++ a->setToolTip(TR("Restore default graphics rotation, zoom and perspective (Alt+Space).")); ++ a->setShortcut(Qt::ALT+Qt::Key_Space); ++ o->addAction(a); bb->addAction(a); popup->addAction(a); ++ bb->addSeparator(); ++ o->addAction(a); bb->addAction(a); popup->addAction(a); ++ a = new QAction(QPixmap(ok_xpm), TR("Re&draw"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(update())); ++ a->setToolTip(TR("Execute script and redraw graphics (F5).")); ++ a->setShortcut(Qt::Key_F5); ++ o->addAction(a); bb->addAction(a); popup->addAction(a); ++ a = new QAction(QPixmap(stop_xpm), TR("Stop"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(stop())); ++ a->setToolTip(TR("Ask to stop plot drawing (F7).")); ++ a->setShortcut(Qt::Key_F7); ++ a = new QAction(TR("&Adjust size"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(adjust())); ++ a->setToolTip(TR("Change canvas size to fill whole region (F6).")); ++ a->setShortcut(Qt::Key_F6); o->addAction(a); ++ a = new QAction(QPixmap(copy_xpm), TR("&Copy plot"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(copy())); ++ a->setToolTip(TR("Copy graphics to clipboard (CTRl+Shift+G).")); ++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_G); ++ o->addAction(a); bb->addAction(a); popup->addAction(a); ++ ++ bb->addSeparator(); ++ oo = new QMenu(TR("Primitives ..."),Wnd); ++ a = new QAction(QPixmap(line_xpm), TR("Add line"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addLine())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add line which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(arc_xpm), TR("Add arc"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addArc())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add arc which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(curve_xpm), TR("Add curve"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addCurve())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add curve which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(mark_s_xpm), TR("Add rect"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addRect())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add rectangle which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(mark_d_xpm), TR("Add rhombus"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addRhomb())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add rhombus which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(mark_o_xpm), TR("Add ellipse"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addEllipse())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add ellipse which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(polygon_xpm), TR("Add polygon"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addPolygon())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add polygon which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(mark_a_xpm), TR("Add mark"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addMark())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add marker which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(text_xpm), TR("Add text"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addText())); ++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool))); ++ a->setToolTip(TR("Add text which properties can be changed later by mouse.")); ++ bb->addAction(a); oo->addAction(a); ++ o->addMenu(oo); ++ ++ bb->addSeparator(); ++ tet = new QSpinBox(Wnd); tet->setWrapping(true); ++ bb->addWidget(tet); tet->setRange(-180, 180); tet->setSingleStep(10); ++ Wnd->connect(tet, SIGNAL(valueChanged(int)), QMGL, SLOT(setTet(int))); ++ Wnd->connect(QMGL, SIGNAL(tetChanged(int)), tet, SLOT(setValue(int))); ++ tet->setToolTip(TR("Set value of \\theta angle.")); ++ bb->addSeparator(); ++ phi = new QSpinBox(Wnd); phi->setWrapping(true); ++ bb->addWidget(phi); phi->setRange(-180, 180); phi->setSingleStep(10); ++ Wnd->connect(phi, SIGNAL(valueChanged(int)), QMGL, SLOT(setPhi(int))); ++ Wnd->connect(QMGL, SIGNAL(phiChanged(int)), phi, SLOT(setValue(int))); ++ phi->setToolTip(TR("Set value of \\phi angle.")); ++// bb->addSeparator(); ++ } ++ // zooming menu ++ { ++ oo = o->addMenu(TR("Zoom/move")); ++ bb = new QToolBar(TR("Zoom graphics"),Wnd); ++ Wnd->addToolBar(Qt::LeftToolBarArea, bb); ++ a = new QAction(QPixmap(left_1_xpm), TR("Move &left"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftLeft())); ++ a->setToolTip(TR("Move graphics left by 1/3 of its width.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(up_1_xpm), TR("Move &up"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftUp())); ++ a->setToolTip(TR("Move graphics up by 1/3 of its height.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(zoom_1_xpm), TR("Zoom &in"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(zoomIn())); ++ a->setToolTip(TR("Zoom in graphics.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(norm_1_xpm), TR("Zoom &out"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(zoomOut())); ++ a->setToolTip(TR("Zoom out graphics.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(down_1_xpm), TR("Move &down"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftDown())); ++ a->setToolTip(TR("Move graphics up down 1/3 of its height.")); ++ bb->addAction(a); oo->addAction(a); ++ a = new QAction(QPixmap(right_1_xpm), TR("Move &right"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftRight())); ++ a->setToolTip(TR("Move graphics right by 1/3 of its width.")); ++ bb->addAction(a); oo->addAction(a); ++ } ++ // animation menu ++ { ++ o = Wnd->menuBar()->addMenu(TR("&Animation")); ++ bb = new QToolBar(TR("Animation"),Wnd); ++ Wnd->addToolBar(Qt::LeftToolBarArea, bb); ++ a = new QAction(QPixmap(next_sl_xpm), TR("&Next slide"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(nextSlide())); ++ a->setToolTip(TR("Show next slide (Ctrl+.).")); ++ a->setShortcut(Qt::CTRL+Qt::Key_Period); o->addAction(a); bb->addAction(a); ++ a = new QAction(QPixmap(show_sl_xpm), TR("&Slideshow"), Wnd); ++ a->setCheckable(true); ++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(animation(bool))); ++ a->setToolTip(TR("Run slideshow (CTRl+F5).")); ++ a->setShortcut(Qt::CTRL+Qt::Key_F5); o->addAction(a); bb->addAction(a); ++ a = new QAction(QPixmap(prev_sl_xpm), TR("&Prev slide"), Wnd); ++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(prevSlide())); ++ a->setToolTip(TR("Show previous slide (Ctrl+,).")); ++ a->setShortcut(Qt::CTRL+Qt::Key_Comma); o->addAction(a); bb->addAction(a); ++ } ++ ++ Wnd->menuBar()->addSeparator(); ++ o = Wnd->menuBar()->addMenu(TR("&Help")); ++ o->addAction(TR("About"), QMGL, SLOT(about())); ++ o->addAction(TR("About &Qt"), QMGL, SLOT(aboutQt())); ++ return popup; ++} ++//----------------------------------------------------------------------------- ++HMGL MGL_EXPORT mgl_create_graph_qt(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p)) ++{ ++ mglCanvasQT *g = new mglCanvasQT; ++ g->Window(0,0,draw,title,par,load); ++ return g; ++} ++int MGL_EXPORT mgl_qt_run() { return (qApp)?qApp->exec():-1; } ++//----------------------------------------------------------------------------- ++uintptr_t MGL_EXPORT mgl_create_graph_qt_(const char *title, int l) ++{ ++ char *s = new char[l+1]; memcpy(s,title,l); s[l]=0; ++ uintptr_t t = uintptr_t(mgl_create_graph_qt(0,s,0,0)); ++ delete []s; return t; ++} ++int MGL_EXPORT mgl_qt_run_() { return mgl_qt_run(); } ++//-----------------------------------------------------------------------------