qwt_compass.cpp 7.13 KB
Newer Older
pixhawk's avatar
pixhawk committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

// vim: expandtab

#include <math.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qevent.h>
#include "qwt_math.h"
#include "qwt_scale_draw.h"
#include "qwt_paint_buffer.h"
#include "qwt_painter.h"
#include "qwt_dial_needle.h"
#include "qwt_compass_rose.h"
#include "qwt_compass.h"

class QwtCompass::PrivateData
{
public:
    PrivateData():
28
        rose(NULL) {
pixhawk's avatar
pixhawk committed
29
30
    }

31
    ~PrivateData() {
pixhawk's avatar
pixhawk committed
32
33
34
35
36
37
38
39
40
41
42
        delete rose;
    }

    QwtCompassRose *rose;
    QMap<double, QString> labelMap;
};

/*!
  \brief Constructor
  \param parent Parent widget

43
  Create a compass widget with a scale, no needle and no rose.
pixhawk's avatar
pixhawk committed
44
45
46
  The default origin is 270.0 with no valid value. It accepts
  mouse and keyboard inputs and has no step size. The default mode
  is QwtDial::RotateNeedle.
47
*/
pixhawk's avatar
pixhawk committed
48
49
50
51
52
53
54
55
56
57
58
59
60
QwtCompass::QwtCompass(QWidget* parent):
    QwtDial(parent)
{
    initCompass();
}

#if QT_VERSION < 0x040000

/*!
  \brief Constructor
  \param parent Parent widget
  \param name Object name

61
  Create a compass widget with a scale, no needle and no rose.
pixhawk's avatar
pixhawk committed
62
63
64
  The default origin is 270.0 with no valid value. It accepts
  mouse and keyboard inputs and has no step size. The default mode
  is QwtDial::RotateNeedle.
65
*/
pixhawk's avatar
pixhawk committed
66
67
68
69
70
71
72
73
74
QwtCompass::QwtCompass(QWidget* parent, const char *name):
    QwtDial(parent, name)
{
    initCompass();
}

#endif

//!  Destructor
75
QwtCompass::~QwtCompass()
pixhawk's avatar
pixhawk committed
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
{
    delete d_data;
}

void QwtCompass::initCompass()
{
    d_data = new PrivateData;

    setScaleOptions(ScaleLabel); // Only labels, no backbone, no ticks

    setOrigin(270.0);
    setWrapping(true);


    d_data->labelMap.insert(0.0, QString::fromLatin1("N"));
    d_data->labelMap.insert(45.0, QString::fromLatin1("NE"));
    d_data->labelMap.insert(90.0, QString::fromLatin1("E"));
    d_data->labelMap.insert(135.0, QString::fromLatin1("SE"));
    d_data->labelMap.insert(180.0, QString::fromLatin1("S"));
    d_data->labelMap.insert(225.0, QString::fromLatin1("SW"));
    d_data->labelMap.insert(270.0, QString::fromLatin1("W"));
    d_data->labelMap.insert(315.0, QString::fromLatin1("NW"));

#if 0
    d_data->labelMap.insert(22.5, QString::fromLatin1("NNE"));
    d_data->labelMap.insert(67.5, QString::fromLatin1("NEE"));
    d_data->labelMap.insert(112.5, QString::fromLatin1("SEE"));
    d_data->labelMap.insert(157.5, QString::fromLatin1("SSE"));
    d_data->labelMap.insert(202.5, QString::fromLatin1("SSW"));
    d_data->labelMap.insert(247.5, QString::fromLatin1("SWW"));
    d_data->labelMap.insert(292.5, QString::fromLatin1("NWW"));
    d_data->labelMap.insert(337.5, QString::fromLatin1("NNW"));
#endif
}

//! Draw the contents of the scale
112
113
void QwtCompass::drawScaleContents(QPainter *painter,
                                   const QPoint &center, int radius) const
pixhawk's avatar
pixhawk committed
114
115
116
117
118
119
120
121
{
    QPalette::ColorGroup cg;
    if ( isEnabled() )
        cg = hasFocus() ? QPalette::Active : QPalette::Inactive;
    else
        cg = QPalette::Disabled;

    double north = origin();
122
    if ( isValid() ) {
pixhawk's avatar
pixhawk committed
123
        if ( mode() == RotateScale )
124
            north -= value();
pixhawk's avatar
pixhawk committed
125
126
127
128
129
130
131
132
    }

    const int margin = 4;
    drawRose(painter, center, radius - margin, 360.0 - north,  cg);
}

/*!
  Draw the compass rose
133

pixhawk's avatar
pixhawk committed
134
135
136
137
138
139
140
  \param painter Painter
  \param center Center of the compass
  \param radius of the circle, where to paint the rose
  \param north Direction pointing north, in degrees counter clockwise
  \param cg Color group
*/
void QwtCompass::drawRose(QPainter *painter, const QPoint &center,
141
                          int radius, double north, QPalette::ColorGroup cg) const
pixhawk's avatar
pixhawk committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
{
    if ( d_data->rose )
        d_data->rose->draw(painter, center, radius, north,  cg);
}

/*!
  Set a rose for the compass
  \param rose Compass rose
  \warning The rose will be deleted, when a different rose is
    set or in ~QwtCompass
  \sa rose()
*/
void QwtCompass::setRose(QwtCompassRose *rose)
{
156
    if ( rose != d_data->rose ) {
pixhawk's avatar
pixhawk committed
157
158
159
160
161
162
163
164
        if ( d_data->rose )
            delete d_data->rose;

        d_data->rose = rose;
        update();
    }
}

165
/*!
pixhawk's avatar
pixhawk committed
166
167
168
  \return rose
  \sa setRose()
*/
169
170
171
const QwtCompassRose *QwtCompass::rose() const
{
    return d_data->rose;
pixhawk's avatar
pixhawk committed
172
173
}

174
/*!
pixhawk's avatar
pixhawk committed
175
176
177
  \return rose
  \sa setRose()
*/
178
179
180
QwtCompassRose *QwtCompass::rose()
{
    return d_data->rose;
pixhawk's avatar
pixhawk committed
181
182
}

183
/*!
pixhawk's avatar
pixhawk committed
184
185
186
187
188
189
190
191
  Handles key events

  Beside the keys described in QwtDial::keyPressEvent numbers
  from 1-9 (without 5) set the direction according to their
  position on the num pad.

  \sa isReadOnly()
*/
192
void QwtCompass::keyPressEvent(QKeyEvent *kev)
pixhawk's avatar
pixhawk committed
193
{
194
    if (isReadOnly())
pixhawk's avatar
pixhawk committed
195
196
197
        return;

#if 0
198
    if ( kev->key() == Key_5 ) {
pixhawk's avatar
pixhawk committed
199
200
201
202
203
204
205
        invalidate(); // signal ???
        return;
    }
#endif

    double newValue = value();

206
    if ( kev->key() >= Qt::Key_1 && kev->key() <= Qt::Key_9 ) {
pixhawk's avatar
pixhawk committed
207
208
209
        if ( mode() != RotateNeedle || kev->key() == Qt::Key_5 )
            return;

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
        switch (kev->key()) {
        case Qt::Key_6:
            newValue = 180.0 * 0.0;
            break;
        case Qt::Key_3:
            newValue = 180.0 * 0.25;
            break;
        case Qt::Key_2:
            newValue = 180.0 * 0.5;
            break;
        case Qt::Key_1:
            newValue = 180.0 * 0.75;
            break;
        case Qt::Key_4:
            newValue = 180.0 * 1.0;
            break;
        case Qt::Key_7:
            newValue = 180.0 * 1.25;
            break;
        case Qt::Key_8:
            newValue = 180.0 * 1.5;
            break;
        case Qt::Key_9:
            newValue = 180.0 * 1.75;
            break;
pixhawk's avatar
pixhawk committed
235
236
237
        }
        newValue -= origin();
        setValue(newValue);
238
    } else {
pixhawk's avatar
pixhawk committed
239
240
241
242
243
244
245
246
        QwtDial::keyPressEvent(kev);
    }
}

/*!
  \return map, mapping values to labels
  \sa setLabelMap()
*/
247
248
249
const QMap<double, QString> &QwtCompass::labelMap() const
{
    return d_data->labelMap;
pixhawk's avatar
pixhawk committed
250
251
252
253
254
255
}

/*!
  \return map, mapping values to labels
  \sa setLabelMap()
*/
256
257
258
QMap<double, QString> &QwtCompass::labelMap()
{
    return d_data->labelMap;
pixhawk's avatar
pixhawk committed
259
260
261
262
263
264
265
266
267
268
269
270
271
272
}

/*!
  \brief Set a map, mapping values to labels
  \param map value to label map

  The values of the major ticks are found by looking into this
  map. The default map consists of the labels N, NE, E, SE, S, SW, W, NW.

  \warning The map will have no effect for values that are no major
           tick values. Major ticks can be changed by QwtScaleDraw::setScale

  \sa labelMap(), scaleDraw(), setScale()
*/
273
274
275
void QwtCompass::setLabelMap(const QMap<double, QString> &map)
{
    d_data->labelMap = map;
pixhawk's avatar
pixhawk committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
}

/*!
  Map a value to a corresponding label
  \param value Value that will be mapped
  \return Label, or QString::null

  label() looks in a map for a corresponding label for value
  or return an null text.
  \sa labelMap(), setLabelMap()
*/

QwtText QwtCompass::scaleLabel(double value) const
{
#if 0
    // better solution ???
    if ( value == -0 )
        value = 0.0;
#endif

    if ( value < 0.0 )
        value += 360.0;

    if ( d_data->labelMap.contains(value) )
        return d_data->labelMap[value];

    return QwtText();
}