]> git.zerfleddert.de Git - proxmark3-svn/blob - client/proxguiqt.cpp
a845468f59d56dad8931640f692347f5ce10fb1c
[proxmark3-svn] / client / proxguiqt.cpp
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
3 //
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
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>
21 #include <stdio.h>
22 #include "proxguiqt.h"
23 #include "proxgui.h"
24
25 int GridOffset= 0;
26 bool GridLocked= 0;
27 int startMax;
28 int PageWidth;
29
30 void ProxGuiQT::ShowGraphWindow(void)
31 {
32 emit ShowGraphWindowSignal();
33 }
34
35 void ProxGuiQT::RepaintGraphWindow(void)
36 {
37 emit RepaintGraphWindowSignal();
38 }
39
40 void ProxGuiQT::HideGraphWindow(void)
41 {
42 emit HideGraphWindowSignal();
43 }
44
45 void ProxGuiQT::_ShowGraphWindow(void)
46 {
47 if(!plotapp)
48 return;
49
50 if (!plotwidget)
51 plotwidget = new ProxWidget();
52
53 plotwidget->show();
54 }
55
56 void ProxGuiQT::_RepaintGraphWindow(void)
57 {
58 if (!plotapp || !plotwidget)
59 return;
60
61 plotwidget->update();
62 }
63
64 void ProxGuiQT::_HideGraphWindow(void)
65 {
66 if (!plotapp || !plotwidget)
67 return;
68
69 plotwidget->hide();
70 }
71
72 void 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
83 ProxGuiQT::ProxGuiQT(int argc, char **argv) : plotapp(NULL), plotwidget(NULL), argc(argc), argv(argv) {}
84
85 ProxGuiQT::~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
99 void ProxWidget::paintEvent(QPaintEvent *event)
100 {
101 QPainter painter(this);
102 QPainterPath penPath, whitePath, greyPath, lightgreyPath, cursorAPath, cursorBPath, cursorCPath, cursorDPath;
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
109 if(GraphStart < 0)
110 GraphStart = 0;
111
112 if (CursorAPos > GraphTraceLen)
113 CursorAPos= 0;
114
115 if(CursorBPos > GraphTraceLen)
116 CursorBPos= 0;
117 if(CursorCPos > GraphTraceLen)
118 CursorCPos= 0;
119 if(CursorDPos > GraphTraceLen)
120 CursorDPos= 0;
121
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);
135
136 PageWidth= (int)((r.right() - r.left() - 40) / GraphPixelsPerPoint);
137
138 // plot X and Y grid lines
139 int i;
140 if ((PlotGridX > 0) && ((PlotGridX * GraphPixelsPerPoint) > 1)) {
141 for(i = 40 + (GridOffset * GraphPixelsPerPoint); i < r.right(); i += (int)(PlotGridX * GraphPixelsPerPoint)) {
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());
146 lightgreyPath.lineTo(r.left()+i,r.bottom());
147 painter.drawPath(lightgreyPath);
148 }
149 }
150 if ((PlotGridY > 0) && ((PlotGridY * GraphPixelsPerPoint) > 1)){
151 for(i = 0; i < ((r.top() + r.bottom())>>1); i += (int)(PlotGridY * GraphPixelsPerPoint)) {
152 lightgreyPath.moveTo(r.left() + 40,zeroHeight + i);
153 lightgreyPath.lineTo(r.right(),zeroHeight + i);
154 painter.drawPath(lightgreyPath);
155 lightgreyPath.moveTo(r.left() + 40,zeroHeight - i);
156 lightgreyPath.lineTo(r.right(),zeroHeight - i);
157 painter.drawPath(lightgreyPath);
158 }
159 }
160
161 startMax = (GraphTraceLen - (int)((r.right() - r.left() - 40) / GraphPixelsPerPoint));
162
163 if(startMax < 0)
164 startMax = 0;
165
166 if(GraphStart > startMax)
167 GraphStart = startMax;
168
169 int absYMax = 1;
170
171 for(i = GraphStart; ; i++) {
172
173 if(i >= GraphTraceLen) break;
174
175 if(fabs((double)GraphBuffer[i]) > absYMax)
176 absYMax = (int)fabs((double)GraphBuffer[i]);
177
178 int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
179
180 if(x > r.right()) break;
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);
187
188 // one label every 100 pixels, let us say
189 int labels = (r.right() - r.left() - 40) / 100;
190 if(labels <= 0) labels = 1;
191
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++) {
201 if(i >= GraphTraceLen) break;
202
203 int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
204 if(x > r.right() + GraphPixelsPerPoint) break;
205
206 int y = GraphBuffer[i];
207 if(y < yMin)
208 yMin = y;
209
210 if(y > yMax)
211 yMax = y;
212
213 yMean += y;
214 n++;
215
216 y = (y * (r.top() - r.bottom()) / (2*absYMax)) + zeroHeight;
217
218 if(i == GraphStart)
219 penPath.moveTo(x, y);
220 else
221 penPath.lineTo(x, y);
222
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
245 if(i == CursorAPos || i == CursorBPos || i == CursorCPos || i == CursorDPos) {
246 QPainterPath *cursorPath;
247
248 if (i == CursorAPos)
249 cursorPath = &cursorAPath;
250 else if (i == CursorBPos)
251 cursorPath = &cursorBPath;
252 else if (i == CursorCPos)
253 cursorPath = &cursorCPath;
254 else
255 cursorPath = &cursorDPath;
256
257 cursorPath->moveTo(x, r.top());
258 cursorPath->lineTo(x, r.bottom());
259 penPath.moveTo(x, y);
260 }
261 }
262
263 if(n != 0)
264 yMean /= n;
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);
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);
278
279 char str[200];
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)",
281 GraphStart, yMax, yMin, yMean, n, GraphTraceLen,
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 );
293
294 painter.setPen(QColor(255, 255, 255));
295 painter.drawText(50, r.bottom() - 20, str);
296 }
297
298 ProxWidget::ProxWidget(QWidget *parent) : QWidget(parent), GraphStart(0), GraphPixelsPerPoint(1)
299 {
300 resize(600, 300);
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);
308 CursorAPos = 0;
309 CursorBPos = 0;
310 }
311
312 void ProxWidget::closeEvent(QCloseEvent *event)
313 {
314 event->ignore();
315 this->hide();
316 }
317
318 void 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
330 this->update();
331 }
332
333 void ProxWidget::keyPressEvent(QKeyEvent *event)
334 {
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;
345 } else
346 if(event->modifiers() & Qt::ControlModifier)
347 offset= 1;
348 else
349 offset= (int)(20 / GraphPixelsPerPoint);
350
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) {
366 if (PlotGridX && GridLocked && GraphStart < startMax){
367 GridOffset -= offset;
368 GridOffset %= PlotGridX;
369 gridchanged= 1;
370 }
371 GraphStart += offset;
372 } else {
373 if (PlotGridX && GridLocked && GraphStart < startMax){
374 GridOffset--;
375 GridOffset %= PlotGridX;
376 gridchanged= 1;
377 }
378 GraphStart++;
379 }
380 if(GridOffset < 0) {
381 GridOffset += PlotGridX;
382 }
383 if (gridchanged)
384 if (GraphStart > startMax) {
385 GridOffset += (GraphStart - startMax);
386 GridOffset %= PlotGridX;
387 }
388 break;
389
390 case Qt::Key_Left:
391 if(GraphPixelsPerPoint < 20) {
392 if (PlotGridX && GridLocked && GraphStart > 0){
393 GridOffset += offset;
394 GridOffset %= PlotGridX;
395 gridchanged= 1;
396 }
397 GraphStart -= offset;
398 } else {
399 if (PlotGridX && GridLocked && GraphStart > 0){
400 GridOffset++;
401 GridOffset %= PlotGridX;
402 gridchanged= 1;
403 }
404 GraphStart--;
405 }
406 if (gridchanged){
407 if (GraphStart < 0)
408 GridOffset += GraphStart;
409 if(GridOffset < 0)
410 GridOffset += PlotGridX;
411 GridOffset %= PlotGridX;
412 }
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");
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");
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();
452 break;
453
454 default:
455 QWidget::keyPressEvent(event);
456 return;
457 break;
458 }
459
460 this->update();
461 }
Impressum, Datenschutz