]> git.zerfleddert.de Git - proxmark3-svn/blame - client/proxguiqt.cpp
CHG: Added PR #220 from PM3 Master. ref: https://github.com/Proxmark/proxmark3...
[proxmark3-svn] / client / proxguiqt.cpp
CommitLineData
a553f267 1//-----------------------------------------------------------------------------
212ef3a0 2// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
3//
a553f267 4// This code is licensed to you under the terms of the GNU GPL, version 2 or,
5// at your option, any later version. See the LICENSE.txt file for the text of
6// the license.
7//-----------------------------------------------------------------------------
8// GUI (QT)
9//-----------------------------------------------------------------------------
10
6658905f 11#include <iostream>
12#include <QPainterPath>
13#include <QBrush>
14#include <QPen>
15#include <QTimer>
16#include <QCloseEvent>
17#include <QMouseEvent>
18#include <QKeyEvent>
19#include <math.h>
20#include <limits.h>
c86cc308 21#include <stdio.h>
6658905f 22#include "proxguiqt.h"
23#include "proxgui.h"
24
7ddb9900 25int GridOffset= 0;
26bool GridLocked= 0;
27int startMax;
18856d88 28int PageWidth;
7ddb9900 29
6658905f 30void ProxGuiQT::ShowGraphWindow(void)
31{
32 emit ShowGraphWindowSignal();
33}
34
35void ProxGuiQT::RepaintGraphWindow(void)
36{
37 emit RepaintGraphWindowSignal();
38}
39
40void ProxGuiQT::HideGraphWindow(void)
41{
42 emit HideGraphWindowSignal();
43}
44
45void ProxGuiQT::_ShowGraphWindow(void)
46{
47 if(!plotapp)
48 return;
49
50 if (!plotwidget)
51 plotwidget = new ProxWidget();
52
53 plotwidget->show();
54}
55
56void ProxGuiQT::_RepaintGraphWindow(void)
57{
58 if (!plotapp || !plotwidget)
59 return;
60
61 plotwidget->update();
62}
63
64void ProxGuiQT::_HideGraphWindow(void)
65{
66 if (!plotapp || !plotwidget)
67 return;
68
69 plotwidget->hide();
70}
71
72void ProxGuiQT::MainLoop()
73{
74 plotapp = new QApplication(argc, argv);
75
76 connect(this, SIGNAL(ShowGraphWindowSignal()), this, SLOT(_ShowGraphWindow()));
77 connect(this, SIGNAL(RepaintGraphWindowSignal()), this, SLOT(_RepaintGraphWindow()));
78 connect(this, SIGNAL(HideGraphWindowSignal()), this, SLOT(_HideGraphWindow()));
79
80 plotapp->exec();
81}
82
6f79363d 83ProxGuiQT::ProxGuiQT(int argc, char **argv) : plotapp(NULL), plotwidget(NULL), argc(argc), argv(argv) {}
6658905f 84
85ProxGuiQT::~ProxGuiQT(void)
86{
87 if (plotwidget) {
88 delete plotwidget;
89 plotwidget = NULL;
90 }
91
92 if (plotapp) {
93 plotapp->quit();
94 delete plotapp;
95 plotapp = NULL;
96 }
97}
98
99void ProxWidget::paintEvent(QPaintEvent *event)
100{
101 QPainter painter(this);
a9eeb576 102 QPainterPath penPath, whitePath, greyPath, lightgreyPath, cursorAPath, cursorBPath, cursorCPath, cursorDPath;
6658905f 103 QRect r;
104 QBrush brush(QColor(100, 255, 100));
105 QPen pen(QColor(100, 255, 100));
106
107 painter.setFont(QFont("Arial", 10));
108
eb7eab85 109 if(GraphStart < 0)
6658905f 110 GraphStart = 0;
6658905f 111
0bf5872f 112 if (CursorAPos > GraphTraceLen)
113 CursorAPos= 0;
eb7eab85 114
0bf5872f 115 if(CursorBPos > GraphTraceLen)
116 CursorBPos= 0;
a9eeb576 117 if(CursorCPos > GraphTraceLen)
118 CursorCPos= 0;
119 if(CursorDPos > GraphTraceLen)
120 CursorDPos= 0;
0bf5872f 121
6658905f 122 r = rect();
123
124 painter.fillRect(r, QColor(0, 0, 0));
125
126 whitePath.moveTo(r.left() + 40, r.top());
127 whitePath.lineTo(r.left() + 40, r.bottom());
128
129 int zeroHeight = r.top() + (r.bottom() - r.top()) / 2;
130
131 greyPath.moveTo(r.left(), zeroHeight);
132 greyPath.lineTo(r.right(), zeroHeight);
133 painter.setPen(QColor(100, 100, 100));
134 painter.drawPath(greyPath);
f4434ad2 135
18856d88 136 PageWidth= (int)((r.right() - r.left() - 40) / GraphPixelsPerPoint);
137
f4434ad2 138 // plot X and Y grid lines
139 int i;
140 if ((PlotGridX > 0) && ((PlotGridX * GraphPixelsPerPoint) > 1)) {
3bc2349d 141 for(i = 40 + (GridOffset * GraphPixelsPerPoint); i < r.right(); i += (int)(PlotGridX * GraphPixelsPerPoint)) {
f4434ad2 142 //SelectObject(hdc, GreyPenLite);
143 //MoveToEx(hdc, r.left + i, r.top, NULL);
144 //LineTo(hdc, r.left + i, r.bottom);
145 lightgreyPath.moveTo(r.left()+i,r.top());
eb7eab85 146 lightgreyPath.lineTo(r.left()+i,r.bottom());
147 painter.drawPath(lightgreyPath);
18856d88 148 }
f4434ad2 149 }
150 if ((PlotGridY > 0) && ((PlotGridY * GraphPixelsPerPoint) > 1)){
151 for(i = 0; i < ((r.top() + r.bottom())>>1); i += (int)(PlotGridY * GraphPixelsPerPoint)) {
ff8216cb 152 lightgreyPath.moveTo(r.left() + 40,zeroHeight + i);
eb7eab85 153 lightgreyPath.lineTo(r.right(),zeroHeight + i);
154 painter.drawPath(lightgreyPath);
ff8216cb 155 lightgreyPath.moveTo(r.left() + 40,zeroHeight - i);
eb7eab85 156 lightgreyPath.lineTo(r.right(),zeroHeight - i);
157 painter.drawPath(lightgreyPath);
f4434ad2 158 }
18856d88 159 }
160
7ddb9900 161 startMax = (GraphTraceLen - (int)((r.right() - r.left() - 40) / GraphPixelsPerPoint));
eb7eab85 162
163 if(startMax < 0)
6658905f 164 startMax = 0;
eb7eab85 165
166 if(GraphStart > startMax)
6658905f 167 GraphStart = startMax;
6658905f 168
169 int absYMax = 1;
170
6658905f 171 for(i = GraphStart; ; i++) {
eb7eab85 172
173 if(i >= GraphTraceLen) break;
174
175 if(fabs((double)GraphBuffer[i]) > absYMax)
6658905f 176 absYMax = (int)fabs((double)GraphBuffer[i]);
eb7eab85 177
6658905f 178 int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
eb7eab85 179
180 if(x > r.right()) break;
6658905f 181 }
182
183 absYMax = (int)(absYMax*1.2 + 1);
184
185 // number of points that will be plotted
186 int span = (int)((r.right() - r.left()) / GraphPixelsPerPoint);
eb7eab85 187
6658905f 188 // one label every 100 pixels, let us say
189 int labels = (r.right() - r.left() - 40) / 100;
190 if(labels <= 0) labels = 1;
eb7eab85 191
6658905f 192 int pointsPerLabel = span / labels;
193 if(pointsPerLabel <= 0) pointsPerLabel = 1;
194
195 int yMin = INT_MAX;
196 int yMax = INT_MIN;
197 int yMean = 0;
198 int n = 0;
199
200 for(i = GraphStart; ; i++) {
eb7eab85 201 if(i >= GraphTraceLen) break;
202
6658905f 203 int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
eb7eab85 204 if(x > r.right() + GraphPixelsPerPoint) break;
6658905f 205
206 int y = GraphBuffer[i];
eb7eab85 207 if(y < yMin)
6658905f 208 yMin = y;
eb7eab85 209
210 if(y > yMax)
6658905f 211 yMax = y;
eb7eab85 212
6658905f 213 yMean += y;
214 n++;
215
216 y = (y * (r.top() - r.bottom()) / (2*absYMax)) + zeroHeight;
eb7eab85 217
218 if(i == GraphStart)
6658905f 219 penPath.moveTo(x, y);
eb7eab85 220 else
6658905f 221 penPath.lineTo(x, y);
eb7eab85 222
6658905f 223
224 if(GraphPixelsPerPoint > 10) {
225 QRect f(QPoint(x - 3, y - 3),QPoint(x + 3, y + 3));
226 painter.fillRect(f, brush);
227 }
228
229 if(((i - GraphStart) % pointsPerLabel == 0) && i != GraphStart) {
230 whitePath.moveTo(x, zeroHeight - 3);
231 whitePath.lineTo(x, zeroHeight + 3);
232
233 char str[100];
234 sprintf(str, "+%d", (i - GraphStart));
235
236 painter.setPen(QColor(255, 255, 255));
237 QRect size;
238 QFontMetrics metrics(painter.font());
239 size = metrics.boundingRect(str);
240 painter.drawText(x - (size.right() - size.left()), zeroHeight + 9, str);
241
242 penPath.moveTo(x,y);
243 }
244
a9eeb576 245 if(i == CursorAPos || i == CursorBPos || i == CursorCPos || i == CursorDPos) {
6658905f 246 QPainterPath *cursorPath;
247
a9eeb576 248 if (i == CursorAPos)
6658905f 249 cursorPath = &cursorAPath;
a9eeb576 250 else if (i == CursorBPos)
6658905f 251 cursorPath = &cursorBPath;
a9eeb576 252 else if (i == CursorCPos)
253 cursorPath = &cursorCPath;
254 else
255 cursorPath = &cursorDPath;
eb7eab85 256
6658905f 257 cursorPath->moveTo(x, r.top());
258 cursorPath->lineTo(x, r.bottom());
259 penPath.moveTo(x, y);
260 }
261 }
262
eb7eab85 263 if(n != 0)
6658905f 264 yMean /= n;
6658905f 265
266 painter.setPen(QColor(255, 255, 255));
267 painter.drawPath(whitePath);
268 painter.setPen(pen);
269 painter.drawPath(penPath);
270 painter.setPen(QColor(255, 255, 0));
271 painter.drawPath(cursorAPath);
272 painter.setPen(QColor(255, 0, 255));
273 painter.drawPath(cursorBPath);
a9eeb576 274 painter.setPen(QColor(255, 153, 0)); //orange
275 painter.drawPath(cursorCPath);
276 painter.setPen(QColor(0, 0, 205)); //light blue
277 painter.drawPath(cursorDPath);
6658905f 278
346ad5fb 279 char str[200];
ff2e9c1c 280 sprintf(str, "@%d max=%d min=%d mean=%d n=%d/%d dt=%d [%.3f] zoom=%.3f CursorA=%d [%d] CursorB=%d [%d] GridX=%d GridY=%d (%s)",
6658905f 281 GraphStart, yMax, yMin, yMean, n, GraphTraceLen,
eb7eab85 282 CursorBPos - CursorAPos,
283 (CursorBPos - CursorAPos)/CursorScaleFactor,
284 GraphPixelsPerPoint,
285 CursorAPos,
286 GraphBuffer[CursorAPos],
287 CursorBPos,
288 GraphBuffer[CursorBPos],
289 PlotGridXdefault,
290 PlotGridYdefault,
291 GridLocked ? "Locked" : "Unlocked"
292 );
6658905f 293
294 painter.setPen(QColor(255, 255, 255));
295 painter.drawText(50, r.bottom() - 20, str);
296}
297
298ProxWidget::ProxWidget(QWidget *parent) : QWidget(parent), GraphStart(0), GraphPixelsPerPoint(1)
299{
8d0a3e87 300 resize(600, 300);
6658905f 301
302 QPalette palette(QColor(0,0,0,0));
303 palette.setColor(QPalette::WindowText, QColor(255,255,255));
304 palette.setColor(QPalette::Text, QColor(255,255,255));
305 palette.setColor(QPalette::Button, QColor(100, 100, 100));
306 setPalette(palette);
307 setAutoFillBackground(true);
cee48e2b 308 CursorAPos = 0;
309 CursorBPos = 0;
6658905f 310}
311
312void ProxWidget::closeEvent(QCloseEvent *event)
313{
314 event->ignore();
315 this->hide();
316}
317
318void ProxWidget::mouseMoveEvent(QMouseEvent *event)
319{
320 int x = event->x();
321 x -= 40;
322 x = (int)(x / GraphPixelsPerPoint);
323 x += GraphStart;
324 if((event->buttons() & Qt::LeftButton)) {
325 CursorAPos = x;
326 } else if (event->buttons() & Qt::RightButton) {
327 CursorBPos = x;
328 }
329
6658905f 330 this->update();
331}
332
333void ProxWidget::keyPressEvent(QKeyEvent *event)
334{
18856d88 335 int offset;
336 int gridchanged;
337
338 gridchanged= 0;
339
340 if(event->modifiers() & Qt::ShiftModifier) {
341 if (PlotGridX)
342 offset= PageWidth - (PageWidth % PlotGridX);
343 else
344 offset= PageWidth;
ff2e9c1c 345 } else
346 if(event->modifiers() & Qt::ControlModifier)
347 offset= 1;
348 else
349 offset= (int)(20 / GraphPixelsPerPoint);
18856d88 350
6658905f 351 switch(event->key()) {
352 case Qt::Key_Down:
353 if(GraphPixelsPerPoint <= 50) {
354 GraphPixelsPerPoint *= 2;
355 }
356 break;
357
358 case Qt::Key_Up:
359 if(GraphPixelsPerPoint >= 0.02) {
360 GraphPixelsPerPoint /= 2;
361 }
362 break;
363
364 case Qt::Key_Right:
365 if(GraphPixelsPerPoint < 20) {
18856d88 366 if (PlotGridX && GridLocked && GraphStart < startMax){
367 GridOffset -= offset;
368 GridOffset %= PlotGridX;
369 gridchanged= 1;
370 }
371 GraphStart += offset;
6658905f 372 } else {
18856d88 373 if (PlotGridX && GridLocked && GraphStart < startMax){
7ddb9900 374 GridOffset--;
18856d88 375 GridOffset %= PlotGridX;
376 gridchanged= 1;
377 }
3bc2349d 378 GraphStart++;
6658905f 379 }
18856d88 380 if(GridOffset < 0) {
7ddb9900 381 GridOffset += PlotGridX;
18856d88 382 }
383 if (gridchanged)
384 if (GraphStart > startMax) {
385 GridOffset += (GraphStart - startMax);
386 GridOffset %= PlotGridX;
387 }
6658905f 388 break;
389
390 case Qt::Key_Left:
391 if(GraphPixelsPerPoint < 20) {
18856d88 392 if (PlotGridX && GridLocked && GraphStart > 0){
393 GridOffset += offset;
394 GridOffset %= PlotGridX;
395 gridchanged= 1;
396 }
397 GraphStart -= offset;
6658905f 398 } else {
18856d88 399 if (PlotGridX && GridLocked && GraphStart > 0){
7ddb9900 400 GridOffset++;
18856d88 401 GridOffset %= PlotGridX;
402 gridchanged= 1;
403 }
3bc2349d 404 GraphStart--;
6658905f 405 }
18856d88 406 if (gridchanged){
407 if (GraphStart < 0)
408 GridOffset += GraphStart;
409 if(GridOffset < 0)
410 GridOffset += PlotGridX;
411 GridOffset %= PlotGridX;
412 }
7ddb9900 413 break;
414
415 case Qt::Key_G:
416 if(PlotGridX || PlotGridY) {
417 PlotGridX= 0;
418 PlotGridY= 0;
419 } else {
420 PlotGridX= PlotGridXdefault;
421 PlotGridY= PlotGridYdefault;
422 }
423 break;
424
425 case Qt::Key_H:
426 puts("Plot Window Keystrokes:\n");
ff2e9c1c 427 puts(" Key Action\n");
428 puts(" DOWN Zoom in");
429 puts(" G Toggle grid display");
430 puts(" H Show help");
431 puts(" L Toggle lock grid relative to samples");
432 puts(" LEFT Move left");
433 puts(" <CTL>LEFT Move left 1 sample");
434 puts(" <SHIFT>LEFT Page left");
435 puts(" LEFT-MOUSE-CLICK Set yellow cursor");
436 puts(" Q Hide window");
437 puts(" RIGHT Move right");
438 puts(" <CTL>RIGHT Move right 1 sample");
439 puts(" <SHIFT>RIGHT Page right");
440 puts(" RIGHT-MOUSE-CLICK Set purple cursor");
441 puts(" UP Zoom out");
7ddb9900 442 puts("");
443 puts("Use client window 'data help' for more plot commands\n");
444 break;
445
446 case Qt::Key_L:
447 GridLocked= !GridLocked;
448 break;
449
450 case Qt::Key_Q:
451 this->hide();
6658905f 452 break;
453
454 default:
455 QWidget::keyPressEvent(event);
456 return;
457 break;
458 }
459
460 this->update();
461}
Impressum, Datenschutz