1
/***************************************************************************
2
* Copyright (c) 2007 Jļæ½rgen Riegel <juergen.riegel@web.de> *
4
* This file is Drawing of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A DrawingICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
24
#include "PreCompiled.h"
30
#include "DrawingView.h"
31
#include <Gui/FileDialog.h>
32
#include <Base/gzstream.h>
34
using namespace DrawingGui;
36
class DrawingScrollArea : public QScrollArea
39
DrawingScrollArea(QWidget* parent)
48
void wheelEvent(QWheelEvent* e)
50
#if QT_VERSION >= 0x040200
56
/* TRANSLATOR DrawingGui::DrawingView */
58
DrawingView::DrawingView(QWidget* parent)
61
// enable mouse tracking when moving even if no buttons are pressed
62
setMouseTracking(true);
64
// enable the mouse events
65
_mouseEventsEnabled = true;
67
// Create the default status bar for displaying messages
68
//EnableStatusBar(true);
70
// Create an OpenGL widget for displaying Drawings
71
//_pGLDrawingBox = new GLDrawingBox(this);
72
_scroll = new DrawingScrollArea(this);
73
_drawingView = new QSvgWidget(_scroll);
74
_drawingView->setBackgroundRole(QPalette::Base);
75
//this->_drawingView->setFocus();
76
//scroll->setFocusProxy(_drawingView);
77
// _drawingView->setFocusProxy(scroll);
78
_scroll->setWidget(_drawingView);
79
//_drawingView->resize(20, 20);
80
setCentralWidget(_scroll);
82
//setCentralWidget(_pGLDrawingBox);
88
// Create the actions, menus and toolbars
91
// connect other slots
92
//connect(_pGLDrawingBox, SIGNAL(drawGraphics()), this, SLOT(drawGraphics()));
95
DrawingView::~DrawingView()
97
// No need to delete _pGLDrawingBox or other widgets as this gets done automatically by QT
100
bool DrawingView::onMsg(const char* pMsg, const char** ppReturn)
102
if(strcmp("ViewFit",pMsg) == 0 ){
105
// comment out on older Inventor
106
} /*else if(strcmp("Example1",pMsg) == 0 ){
107
SoSeparator * root = new SoSeparator;
109
_viewer->setSceneGraph(root);
111
}else if(strcmp("Example2",pMsg) == 0 ){
112
SoSeparator * root = new SoSeparator;
114
_viewer->setSceneGraph(root);
116
}else if(strcmp("Example3",pMsg) == 0 ){
117
SoSeparator * root = new SoSeparator;
118
AnimationTexture(root);
119
_viewer->setSceneGraph(root);
121
}else if(strcmp("GetCamera",pMsg) == 0 ){
122
SoCamera * Cam = _viewer->getCamera();
123
*ppReturn = writeNodesToString(Cam).c_str();
125
}else if(strncmp("SetCamera",pMsg,9) == 0 ){
126
return setCamera(pMsg+10);
127
}else if(strncmp("Dump",pMsg,4) == 0 ){
130
}else if(strcmp("ViewBottom",pMsg) == 0 ){
131
SoCamera* cam = _viewer->getCamera();
132
cam->orientation.setValue(-1, 0, 0, 0);
135
}else if(strcmp("ViewFront",pMsg) == 0 ){
136
float root = (float)(sqrt(2.0)/2.0);
137
SoCamera* cam = _viewer->getCamera();
138
cam->orientation.setValue(-root, 0, 0, -root);
141
}else if(strcmp("ViewLeft",pMsg) == 0 ){
142
SoCamera* cam = _viewer->getCamera();
143
cam->orientation.setValue(0.5, 0.5, 0.5, 0.5);
146
}else if(strcmp("ViewRear",pMsg) == 0 ){
147
float root = (float)(sqrt(2.0)/2.0);
148
SoCamera* cam = _viewer->getCamera();
149
cam->orientation.setValue(0, root, root, 0);
152
}else if(strcmp("ViewRight",pMsg) == 0 ){
153
SoCamera* cam = _viewer->getCamera();
154
cam->orientation.setValue(-0.5, 0.5, 0.5, -0.5);
157
}else if(strcmp("ViewTop",pMsg) == 0 ){
158
SoCamera* cam = _viewer->getCamera();
159
cam->orientation.setValue(0, 0, 0, 1);
162
}else if(strcmp("ViewAxo",pMsg) == 0 ){
163
float root = (float)(sqrt(3.0)/4.0);
164
SoCamera* cam = _viewer->getCamera();
165
cam->orientation.setValue(-0.333333f, -0.166666f, -0.333333f, -root);
168
}else if(strcmp("OrthographicCamera",pMsg) == 0 ){
169
_viewer->setCameraType(SoOrthographicCamera::getClassTypeId());
171
}else if(strcmp("PerspectiveCamera",pMsg) == 0 ){
172
_viewer->setCameraType(SoPerspectiveCamera::getClassTypeId());
174
}else if(strcmp("Undo",pMsg) == 0 ){
175
getGuiDocument()->undo(1);
177
}else if(strcmp("Redo",pMsg) == 0 ){
178
getGuiDocument()->redo(1);
186
bool DrawingView::onHasMsg(const char* pMsg) const
188
if(strcmp("ViewFit",pMsg) == 0 ){
190
}/*else if(strcmp("Redo",pMsg) == 0 ){
191
return getAppDocument()->getAvailableRedos() > 0;
192
}else if(strcmp("SetStereoRedGreen",pMsg) == 0 ){
194
}else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ){
196
}else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ){
198
}else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ){
200
}else if(strcmp("SetStereoOff",pMsg) == 0 ){
202
}else if(strcmp("Example1",pMsg) == 0 ){
204
}else if(strcmp("Example2",pMsg) == 0 ){
206
}else if(strcmp("Example3",pMsg) == 0 ){
208
}else if(strcmp("Undo",pMsg) == 0 ){
209
return getAppDocument()->getAvailableUndos() > 0;
210
}else if(strcmp("ViewBottom",pMsg) == 0 ){
212
}else if(strcmp("ViewFront",pMsg) == 0 ){
214
}else if(strcmp("ViewLeft",pMsg) == 0 ){
216
}else if(strcmp("ViewRear",pMsg) == 0 ){
218
}else if(strcmp("ViewRight",pMsg) == 0 ){
220
}else if(strcmp("ViewTop",pMsg) == 0 ){
222
}else if(strcmp("ViewAxo",pMsg) == 0 ){
224
}else if(strcmp("GetCamera",pMsg) == 0 ){
226
}else if(strncmp("SetCamera",pMsg,9) == 0 ){
228
}else if(strncmp("Dump",pMsg,4) == 0 ){
234
void DrawingView::viewAll()
239
void DrawingView::load (const QString & file)
242
QString suffix = fi.suffix().toLower();
243
if (suffix == QLatin1String("svg")) {
244
this->_drawingView->load(file);
245
} else if (suffix == QLatin1String("svgz")) {
247
Gui::ByteArrayStream buf(contents);
248
Base::igzstream gzip(file.toUtf8());
251
this->_drawingView->load(contents);
254
QSize size = this->_drawingView->renderer()->defaultSize();
255
this->aspectRatio = (float)size.width() / (float)size.height();
256
this->_drawingView->resize(size);
259
// Create the action groups, actions, menus and toolbars
260
void DrawingView::createActions()
271
// Slot function to fit (stretch/shrink) the Drawing to the view size
272
void DrawingView::fitDrawing()
274
QSize DrawSize = this->_drawingView->size();
275
QSize ScrollSize = this->_scroll->size();
276
float ratio = DrawSize.width()/float(DrawSize.height());
277
if(ratio < ScrollSize.width()/float(ScrollSize.height()))
279
float height = ScrollSize.height() - 2.0;
280
float width = ratio * height;
281
DrawSize.setWidth ((int)width);
282
DrawSize.setHeight((int)height);
284
float width = ScrollSize.width()- 2.0;
285
float height = width / ratio;
286
DrawSize.setWidth ((int)width);
287
DrawSize.setHeight((int)height);
290
//float height = std::max<float>(factor * (float)size.height(),10.0f);
291
//float width = this->aspectRatio * height;
292
//size.setWidth ((int)width);
293
//size.setHeight((int)height);
294
this->_drawingView->resize(DrawSize);
299
// Slot function to display the Drawing at a 1:1 scale"
300
void DrawingView::oneToOneDrawing()
304
// Slot function to handle the color actions
305
void DrawingView::handleColorAct( QAction* act)
307
if (act == _pShowOrigAct)
309
_pSliderBrightAdj->setEnabled(false);
310
showOriginalColors();
312
else if (act == _pShowBrightAct)
314
_pSliderBrightAdj->setEnabled(true);
319
// Show the original colors (no enhancement)
320
// but Drawing will be scaled for the number of significant bits
321
// (i.e if 12 significant bits (in 16-bit Drawing) a value of 4095 will be shown as white)
322
void DrawingView::showOriginalColors()
326
// Show the Drawing with a brightness adjustment
327
void DrawingView::showBrightened()
331
// Slot function to adjust the brightness slider's value
332
void DrawingView::sliderValueAdjusted(int NewValue)
334
_sliderBrightAdjVal = NewValue;
335
if (_pShowBrightAct->isChecked() == true)
344
void DrawingView::mousePressEvent(QMouseEvent* cEvent)
346
if (_mouseEventsEnabled == true)
348
// Mouse event coordinates are relative to top-left of Drawing view (including toolbar!)
349
// Get current cursor position relative to top-left of Drawing box
350
QPoint offset;// = _pGLDrawingBox->pos();
351
int box_x = cEvent->x() - offset.x();
352
int box_y = cEvent->y() - offset.y();
355
switch(cEvent->buttons())
361
//case Qt::LeftButton | Qt::MidButton:
362
// _currMode = zooming;
365
if (cEvent->modifiers() & Qt::ShiftModifier)
366
_currMode = addselection;
368
_currMode = selection;
370
case Qt::RightButton:
371
// _pContextMenu->exec(cEvent->globalPos());
379
void DrawingView::mouseDoubleClickEvent(QMouseEvent* cEvent)
381
if (_mouseEventsEnabled == true)
383
// Mouse event coordinates are relative to top-left of Drawing view (including toolbar!)
384
// Get current cursor position relative to top-left of Drawing box
385
QPoint offset;// = _pGLDrawingBox->pos();
386
int box_x = cEvent->x() - offset.x();
387
int box_y = cEvent->y() - offset.y();
390
if(cEvent->button() == Qt::MidButton)
392
// double icX = _pGLDrawingBox->WCToIC_X(_currX);
393
// double icY = _pGLDrawingBox->WCToIC_Y(_currY);
394
//int pixX = (int)floor(icX + 0.5);
395
//int pixY = (int)floor(icY + 0.5);
396
// _pGLDrawingBox->setZoomFactor(_pGLDrawingBox->getZoomFactor(), true, (int)floor(icX + 0.5), (int)floor(icY + 0.5));
397
// _pGLDrawingBox->redraw();
403
void DrawingView::mouseMoveEvent(QMouseEvent* cEvent)
405
QApplication::flush();
407
// Mouse event coordinates are relative to top-left of Drawing view (including toolbar!)
408
// Get current cursor position relative to top-left of Drawing box
409
QPoint offset ;//= _pGLDrawingBox->pos();
410
int box_x = cEvent->x() - offset.x();
411
int box_y = cEvent->y() - offset.y();
412
if (_mouseEventsEnabled == true)
419
//_pGLDrawingBox->relMoveWC(box_x - dragStartWCx, box_y - dragStartWCy);
422
zoom(_currX, _currY, box_x, box_y);
431
// Update the status bar
435
// Mouse release event
436
void DrawingView::mouseReleaseEvent(QMouseEvent* cEvent)
438
if (_mouseEventsEnabled == true)
440
// Mouse event coordinates are relative to top-left of Drawing view (including toolbar!)
441
// Get current cursor position relative to top-left of Drawing box
442
QPoint offset;// = _pGLDrawingBox->pos();
443
int box_x = cEvent->x() - offset.x();
444
int box_y = cEvent->y() - offset.y();
448
select(box_x, box_y);
451
addSelect(box_x, box_y);
461
void DrawingView::wheelEvent(QWheelEvent * cEvent)
463
if (_mouseEventsEnabled == true)
465
// Mouse event coordinates are relative to top-left of Drawing view (including toolbar!)
466
// Get current cursor position relative to top-left of Drawing box
467
QPoint offset;// = _pGLDrawingBox->pos();
468
int box_x = cEvent->x() - offset.x();
469
int box_y = cEvent->y() - offset.y();
471
// Zoom around centrally displayed Drawing point
472
float numTicks = (float)(-cEvent->delta())/240.0;
473
float factor = pow(2.0f, numTicks);
474
QSize size = this->_drawingView->size();
475
float height = std::max<float>(factor * (float)size.height(),10.0f);
476
float width = this->aspectRatio * height;
477
size.setWidth ((int)width);
478
size.setHeight((int)height);
479
this->_drawingView->resize(size);
481
//_pGLDrawingBox->getCentrePoint(ICx, ICy);
482
//_pGLDrawingBox->setZoomFactor(_pGLDrawingBox->getZoomFactor() / pow(2.0, (double)numTicks), true, ICx, ICy);
483
//_pGLDrawingBox->redraw();
487
// Update the status bar
492
// Update the status bar with the Drawing parameters for the current mouse position
493
void DrawingView::updateStatusBar()
495
if (_statusBarEnabled == true)
497
// Create the text string to display in the status bar
498
QString txt = createStatusBarText();
500
// Update status bar with new text
501
statusBar()->showMessage(txt);
505
// Create the text to display in the status bar.
506
// Gets called by updateStatusBar()
507
// Override this function in a derived class to add your own text
508
QString DrawingView::createStatusBarText()
511
/* // Get some Drawing parameters
512
//unsigned short numDrawingSamples = _pGLDrawingBox->getDrawingNumSamplesPerPix();
513
double zoomFactor = _pGLDrawingBox->getZoomFactor();
514
double icX = _pGLDrawingBox->WCToIC_X(_currX);
515
double icY = _pGLDrawingBox->WCToIC_Y(_currY);
516
int pixX = (int)floor(icX + 0.5);
517
int pixY = (int)floor(icY + 0.5);
518
int colorFormat = _pGLDrawingBox->getDrawingFormat();
520
// Create text for status bar
521
if ((colorFormat == IB_CF_GREY8) ||
522
(colorFormat == IB_CF_GREY16) ||
523
(colorFormat == IB_CF_GREY32))
526
if (_pGLDrawingBox->getDrawingSample(pixX, pixY, 0, grey_value) == 0)
527
txt.sprintf("x,y = %0.2lf,%0.2lf | %s = %d | %s = %0.1lf",
528
icX, icY, (const char*)tr("grey").toAscii(), (int)grey_value, (const char*)tr("zoom").toAscii(), zoomFactor);
530
txt.sprintf("x,y = %s | %s = %0.1lf", (const char*)tr("outside Drawing").toAscii(), (const char*)tr("zoom").toAscii(), zoomFactor);
532
else if ((colorFormat == IB_CF_RGB24) ||
533
(colorFormat == IB_CF_RGB48))
535
double red, green, blue;
536
if ((_pGLDrawingBox->getDrawingSample(pixX, pixY, 0, red) != 0) ||
537
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 1, green) != 0) ||
538
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 2, blue) != 0))
539
txt.sprintf("x,y = %s | %s = %0.1lf", (const char*)tr("outside Drawing").toAscii(), (const char*)tr("zoom").toAscii(), zoomFactor);
541
txt.sprintf("x,y = %0.2lf,%0.2lf | rgb = %d,%d,%d | %s = %0.1lf",
542
icX, icY, (int)red, (int)green, (int)blue, (const char*)tr("zoom").toAscii(), zoomFactor);
544
else if ((colorFormat == IB_CF_BGR24) ||
545
(colorFormat == IB_CF_BGR48))
547
double red, green, blue;
548
if ((_pGLDrawingBox->getDrawingSample(pixX, pixY, 0, blue) != 0) ||
549
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 1, green) != 0) ||
550
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 2, red) != 0))
551
txt.sprintf("x,y = %s | %s = %0.1lf", (const char*)tr("outside Drawing").toAscii(), (const char*)tr("zoom").toAscii(), zoomFactor);
553
txt.sprintf("x,y = %0.2lf,%0.2lf | rgb = %d,%d,%d | %s = %0.1lf",
554
icX, icY, (int)red, (int)green, (int)blue, (const char*)tr("zoom").toAscii(), zoomFactor);
556
else if ((colorFormat == IB_CF_RGBA32) ||
557
(colorFormat == IB_CF_RGBA64))
559
double red, green, blue, alpha;
560
if ((_pGLDrawingBox->getDrawingSample(pixX, pixY, 0, red) != 0) ||
561
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 1, green) != 0) ||
562
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 2, blue) != 0) ||
563
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 3, alpha) != 0))
564
txt.sprintf("x,y = %s | %s = %0.1lf", (const char*)tr("outside Drawing").toAscii(), (const char*)tr("zoom").toAscii(), zoomFactor);
566
txt.sprintf("x,y = %0.2lf,%0.2lf | rgba = %d,%d,%d,%d | %s = %0.1lf",
567
icX, icY, (int)red, (int)green, (int)blue, (int)alpha, (const char*)tr("zoom").toAscii(), zoomFactor);
569
else if ((colorFormat == IB_CF_BGRA32) ||
570
(colorFormat == IB_CF_BGRA64))
572
double red, green, blue, alpha;
573
if ((_pGLDrawingBox->getDrawingSample(pixX, pixY, 0, blue) != 0) ||
574
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 1, green) != 0) ||
575
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 2, red) != 0) ||
576
(_pGLDrawingBox->getDrawingSample(pixX, pixY, 3, alpha) != 0))
577
txt.sprintf("x,y = %s | %s = %0.1lf", (const char*)tr("outside Drawing").toAscii(), (const char*)tr("zoom").toAscii(), zoomFactor);
579
txt.sprintf("x,y = %0.2lf,%0.2lf | rgba = %d,%d,%d,%d | %s = %0.1lf",
580
icX, icY, (int)red, (int)green, (int)blue, (int)alpha, (const char*)tr("zoom").toAscii(), zoomFactor);
586
// Starts a mouse drag in the Drawing - stores some initial positions
587
void DrawingView::startDrag()
589
//_pGLDrawingBox->fixBasePosCurr(); // fixes current Drawing position as base position
590
dragStartWCx = _currX;
591
dragStartWCy = _currY;
594
// Zoom the Drawing using vertical mouse movement to define a zoom factor
595
void DrawingView::zoom(int prevX, int prevY, int currX, int currY)
597
// Check we have more of a vertical shift than a hz one
598
int dx = currX - prevX;
599
int dy = currY - prevY;
600
if (abs(dy) > abs(dx))
602
// Get centrally displayed Drawing point
604
//_pGLDrawingBox->getCentrePoint(ICx, ICy);
606
// Compute zoom factor multiplier
607
double zoomFactorMultiplier = 1.05;
609
zoomFactorMultiplier = 0.95;
611
// Zoom around centrally displayed Drawing point
612
//_pGLDrawingBox->setZoomFactor(_pGLDrawingBox->getZoomFactor() * zoomFactorMultiplier, true, ICx, ICy);
613
//_pGLDrawingBox->redraw();
617
// Select at the given position
618
void DrawingView::select(int currX, int currY)
620
// base class implementation does nothing
621
// override this method and implement selection capability if required
624
// Add selection at the given position
625
void DrawingView::addSelect(int currX, int currY)
627
// base class implementation does nothing
628
// override this method and implement selection capability if required
631
// Draw any 2D graphics necessary
632
// Use GLDrawingBox::ICToWC_X and ICToWC_Y methods to transform Drawing coordinates into widget coordinates (which
633
// must be used by the OpenGL vertex commands).
634
void DrawingView::drawGraphics()
636
// base class implementation does nothing
638
// override this method and implement OpenGL drawing commands to draw any needed graphics on top of the Drawing
640
/* Example: draw a red line from Drawing coordinates (100,100) to (120,120)
641
glColor3ub((GLubyte)255, (GLubyte)0, (GLubyte)0);
643
glVertex2d(_pGLDrawingBox->ICToWC_X(100.0), _pGLDrawingBox->ICToWC_Y(100.0));
644
glVertex2d(_pGLDrawingBox->ICToWC_X(120.0), _pGLDrawingBox->ICToWC_Y(120.0));
649
#include "moc_DrawingView.cpp"