PeakMarker2D.cpp 4.03 KB
Newer Older
1
2
3
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4
5
//   NScD Oak Ridge National Laboratory, European Spallation Source,
//   Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6
// SPDX - License - Identifier: GPL - 3.0 +
7
#include "MantidDataObjects/Peak.h"
Roman Tolchenov's avatar
Roman Tolchenov committed
8
9
#include "MantidQtWidgets/InstrumentView/PeakMarker2D.h"
#include "MantidQtWidgets/InstrumentView/PeakOverlay.h"
10
11
12

#include <QFontMetrics>
#include <QMouseEvent>
LamarMoore's avatar
LamarMoore committed
13
14
#include <QPainter>
#include <QPainterPath>
15
16
17
18
#include <QWheelEvent>

#include <algorithm>
#include <cmath>
LamarMoore's avatar
LamarMoore committed
19
#include <stdexcept>
20

21
22
23
namespace MantidQt {
namespace MantidWidgets {

24
using Mantid::DataObjects::Peak;
25
using Mantid::Geometry::IPeak;
26
27
28
29
/// Default size in screen pixels of the marker's symbol
const int PeakMarker2D::g_defaultMarkerSize = 5;

/**
LamarMoore's avatar
LamarMoore committed
30
31
32
33
34
35
 * Constructor.
 * @param peakOverlay :: shape for the overlay
 * @param u :: x screen coordinate of peak center
 * @param v :: y screen coordinate of peak center
 * @param style :: marker symbol style
 */
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
PeakMarker2D::PeakMarker2D(PeakOverlay &peakOverlay, double u, double v,
                           const Style &style)
    : m_peakOverlay(peakOverlay), m_symbol(style.symbol), m_h(-99.0),
      m_k(-99.0), m_l(-99.0), m_detID(-99), m_row(-1) {
  setColor(style.color);
  if (style.size > 0) {
    m_markerSize = style.size;
  } else {
    m_markerSize = g_defaultMarkerSize;
  }
  const QPointF &centre = QPointF(u, v);
  m_boundingRect =
      RectF(centre - QPointF((qreal)m_markerSize / 2, (qreal)m_markerSize / 2),
            QSizeF((qreal)m_markerSize, (qreal)m_markerSize));
  setScalable(false);
}

/**
LamarMoore's avatar
LamarMoore committed
54
55
 * Return the style of the marker.
 */
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
PeakMarker2D::Style PeakMarker2D::getStyle() const {
  return Style(m_symbol, getColor(), m_markerSize);
}

bool PeakMarker2D::selectAt(const QPointF &p) const { return contains(p); }

void PeakMarker2D::drawShape(QPainter &painter) const {
  // draw the symbol
  switch (m_symbol) {
  case Circle:
    drawCircle(painter);
    break;
  case Diamond:
    drawDiamond(painter);
    break;
  case Square:
    drawSquare(painter);
    break;
  default:
    drawCircle(painter);
  }
  // calculate label's area on the screen
  QFontMetrics fm(painter.font());
  QRect r = fm.boundingRect(m_label);
  m_labelRect = QRectF(r);
  m_labelRect.moveTo(m_boundingRect.x1() + m_markerSize,
                     m_boundingRect.y1() - m_markerSize);
}

void PeakMarker2D::addToPath(QPainterPath &path) const {
  path.addRect(m_boundingRect.toQRectF());
}

/// Set new marker size to s
void PeakMarker2D::setMarkerSize(const int &s) {
  if (s > 0) {
    m_markerSize = s;
  }
}

/// Draw marker as a circle
void PeakMarker2D::drawCircle(QPainter &painter) const {
  QPainterPath path;
  path.addEllipse(m_boundingRect.toQRectF());
  painter.fillPath(path, m_color);
}

/// Draw marker as a diamond
void PeakMarker2D::drawDiamond(QPainter &painter) const {
  QPointF dp = origin();
  QPointF mdp(-dp.x(), -dp.y());
  // draw a diamond as a square rotated by 45 degrees
  painter.save();
  painter.translate(dp);
  painter.rotate(45);
  painter.translate(mdp);
  QPainterPath path;
  path.addRect(m_boundingRect.toQRectF());
  painter.fillPath(path, m_color);
  painter.restore();
}

/// Draw marker as a square
void PeakMarker2D::drawSquare(QPainter &painter) const {
  QPainterPath path;
  path.addRect(m_boundingRect.toQRectF());
  painter.fillPath(path, m_color);
}

/**
LamarMoore's avatar
LamarMoore committed
126
127
 * Save some peak information.
 */
128
129
130
131
void PeakMarker2D::setPeak(const IPeak &ipeak, int row) {
  m_h = ipeak.getH();
  m_k = ipeak.getK();
  m_l = ipeak.getL();
132
133
134
  m_label = QString("%1 %2 %3")
                .arg(QString::number(m_h, 'g', 2), QString::number(m_k, 'g', 2),
                     QString::number(m_l, 'g', 2));
135
136
  auto peak = dynamic_cast<const Peak *>(&ipeak);
  if (peak)
137
    m_detID = peak->getDetectorID();
138
139
140
141
  m_row = row;
}

/**
LamarMoore's avatar
LamarMoore committed
142
143
 * Return reference to the peak.
 */
144
145
146
147
const Mantid::Geometry::IPeak &PeakMarker2D::getPeak() const {
  return m_peakOverlay.getPeak(m_row);
}

LamarMoore's avatar
LamarMoore committed
148
149
} // namespace MantidWidgets
} // namespace MantidQt