9 #include "IndependentCubeViewport.h"
13 #include <QMouseEvent>
22 #include "Projection.h"
23 #include "RingPlaneProjection.h"
24 #include "TProjection.h"
25 #include "CubeStretch.h"
27 #include "StretchTool.h"
28 #include "ViewportBuffer.h"
35 IndependentCubeViewport::IndependentCubeViewport(Cube * cube,
36 CubeDataThread * cdt,
QWidget * parent) :
37 CubeViewport(cube, cdt, parent)
39 panningPrevPoint = NULL;
43 panningPrevPoint =
new QPoint;
44 bandingPoint1 =
new QPoint;
45 bandingPoint2 =
new QPoint;
51 viewport()->setMouseTracking(
true);
55 IndependentCubeViewport::~IndependentCubeViewport()
59 delete panningPrevPoint;
60 panningPrevPoint = NULL;
82 QMouseEvent *m = (QMouseEvent *) e;
83 QPoint currentPosition(m->pos());
84 Qt::MouseButton b = (Qt::MouseButton)(m->button() + m->modifiers());
94 case QEvent::MouseMove:
97 emit synchronize(
this);
99 handleMouseMove(currentPosition);
108 case QEvent::MouseButtonPress:
110 handleMousePress(currentPosition, b);
113 case QEvent::MouseButtonRelease:
115 handleMouseRelease(currentPosition);
116 emit synchronize(
this);
127 return QAbstractScrollArea::eventFilter(o, e);
137 QPainter painter(viewport());
138 painter.drawPixmap(0, 0, p_pixmap);
142 QPen pen(QColor(255, 0, 0));
143 pen.setStyle(Qt::SolidLine);
145 painter.drawRect(bandingRect());
156 stretchGray(globalStretch);
160 void IndependentCubeViewport::showEvent(QShowEvent * event)
162 QAbstractScrollArea::show();
165 restretch(grayBuffer());
169 void IndependentCubeViewport::resetKnownGlobal()
172 p_globalStretches->clear();
173 for (
int i = 0; i < cubeBands(); i++)
174 p_globalStretches->append(NULL);
177 grayBuffer()->addStretchAction();
181 void IndependentCubeViewport::cubeDataChanged(
int cubeId,
189 data->
Band() == grayBand() &&
193 Stretch *& globalStretch = (*p_globalStretches)[data->
Band() - 1];
197 delete globalStretch;
198 globalStretch = NULL;
202 Stretch newGlobal = grayStretch();
203 newGlobal.ClearPairs();
207 if (stats.ValidPixels() > 1 &&
208 fabs(stats.Minimum() - stats.Maximum()) > DBL_EPSILON)
210 Histogram hist(stats.BestMinimum(), stats.BestMaximum(), 65536);
213 if (fabs(hist.Percent(0.5) - hist.Percent(99.5)) > DBL_EPSILON)
215 newGlobal.AddPair(hist.Percent(0.5), 0.0);
216 newGlobal.AddPair(hist.Percent(99.5), 255.0);
220 if (newGlobal.Pairs() == 0)
222 newGlobal.AddPair(-DBL_MAX, 0.0);
223 newGlobal.AddPair(DBL_MAX, 255.0);
226 globalStretch =
new CubeStretch(newGlobal);
229 stretchGray(newGlobal);
236 void IndependentCubeViewport::handleMouseMove(QPoint p)
240 QPoint diff = *panningPrevPoint - p;
241 *panningPrevPoint = p;
242 scrollBy(diff.x(), diff.y());
249 viewport()->repaint();
257 void IndependentCubeViewport::handleMousePress(QPoint p, Qt::MouseButton b)
259 bool ctrlPressed = ((b & Qt::ControlModifier) == Qt::ControlModifier);
260 bool shiftPressed = ((b & Qt::ShiftModifier) == Qt::ShiftModifier);
261 bool ctrlShiftPressed = ctrlPressed && shiftPressed;
262 leftClick = ((b & Qt::LeftButton) == Qt::LeftButton);
266 if (ctrlPressed && !shiftPressed)
273 if (ctrlShiftPressed)
276 *panningPrevPoint = p;
287 void IndependentCubeViewport::handleMouseRelease(QPoint p)
310 stretchKnownGlobal();
317 void IndependentCubeViewport::handleSynchronization(
318 IndependentCubeViewport * other)
323 int deltaWidth = other->viewport()->width() - viewport()->width();
324 int deltaHeight = other->viewport()->height() - viewport()->height();
326 double offsetXToCenter = deltaWidth / 2.0 + viewport()->width() / 2.0;
327 double offsetYToCenter = deltaHeight / 2.0 + viewport()->height() / 2.0;
329 double offsetSampsToCenter = offsetXToCenter / other->scale();
330 double offsetLinesToCenter = offsetYToCenter / other->scale();
332 double otherSS, otherSL;
333 other->viewportToCube(0, 0, otherSS, otherSL);
335 double thisCenterSamp = otherSS + offsetSampsToCenter;
336 double thisCenterLine = otherSL + offsetLinesToCenter;
338 if (scale() == other->scale())
339 center(thisCenterSamp, thisCenterLine);
341 setScale(other->scale(), thisCenterSamp, thisCenterLine);
345 QRect IndependentCubeViewport::bandingRect()
348 rect.setTop(qMin(bandingPoint1->y(), bandingPoint2->y()));
349 rect.setLeft(qMin(bandingPoint1->x(), bandingPoint2->x()));
350 rect.setBottom(qMax(bandingPoint1->y(), bandingPoint2->y()));
351 rect.setRight(qMax(bandingPoint1->x(), bandingPoint2->x()));
357 void IndependentCubeViewport::stretch()
359 QRect rect(bandingRect());
360 if (rect.width() == 0 || rect.height() == 0)
365 newStretch = grayStretch();
368 stretchGray(newStretch);
371 void IndependentCubeViewport::track(
const QPoint & p)
373 if (grayBuffer()->working())
375 emit cantTrack(
"busy",
this);
380 viewportToCube(p.x(), p.y(), sample, line);
390 if (sample >= 0.5 && sample <= cubeSamples() + 0.5 &&
391 line >= 0.5 && line <= cubeLines() + 0.5 &&
392 trackBuffer(grayBuffer(), p, dn))
394 bool camSucceeds = camera() && camera()->SetImage(sample, line);
395 bool projSucceeds = !camSucceeds && projection() &&
396 projection()->SetWorld(sample, line);
400 if (projSucceeds) projType = projection()->projectionType();
402 if (camSucceeds || projSucceeds)
409 lat = camera()->UniversalLatitude();
410 lon = camera()->UniversalLongitude();
416 TProjection *tproj = (TProjection *) projection();
417 lat = tproj->Latitude();
418 lon = tproj->Longitude();
421 RingPlaneProjection *rproj = (RingPlaneProjection *) projection();
422 lat = rproj->RingRadius();
423 lon = rproj->RingLongitude();
427 emit trackingChanged(sample, line, lat, lon, dn,
this);
431 emit trackingChanged(sample, line, dn,
this);
436 emit cantTrack(
"n/a",
this);
441 bool IndependentCubeViewport::trackBuffer(ViewportBuffer * buffer,
442 const QPoint & p,
double & dn)
444 const QRect rect(buffer->bufferXYRect());
445 bool success = rect.contains(p,
true);
448 const int bufX = p.x() - rect.left();
449 const int bufY = p.y() - rect.top();
450 dn = buffer->getLine(bufY)[bufX];
457 void IndependentCubeViewport::zoom()
465 QRect rect = bandingRect();
473 if (rect.topLeft() == rect.bottomRight())
478 factor = 1.0 / factor;
480 scale = this->scale() * factor;
484 if ((rect.width() < 5) || (rect.height() < 5))
486 viewport()->repaint();
490 x += rect.width() / 2;
491 y += rect.height() / 2;
492 double xscale = (double) viewport()->width() / (double) rect.width();
493 double yscale = (double) viewport()->height() / (double) rect.height();
494 scale = xscale < yscale ? xscale : yscale;
499 scale *= this->scale();
503 setScale(scale, x, y);