moved to shstk

This commit is contained in:
2020-08-25 22:24:02 +03:00
parent d4f1c78a6e
commit b92a1fa558
904 changed files with 2448 additions and 36452 deletions

View File

@@ -0,0 +1 @@
qad_library(graphic "Gui;Widgets;OpenGL" "qad_widgets;qad_utils;${OPENGL_LIBRARIES}")

1745
libs/graphic/graphic.cpp Normal file
View File

@@ -0,0 +1,1745 @@
#include "graphic.h"
#include "qad_types.h"
#include "uglwidget.h"
#include "ui_graphic.h"
#include "ui_graphic_conf.h"
#include <QMetaObject>
#include <QMessageBox>
#include <QTapAndHoldGesture>
#include <QPanGesture>
#include <QPinchGesture>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
# include <QRandomGenerator>
#endif
#ifndef Q_OS_ANDROID
# define HAS_GL
#endif
#ifdef HAS_GL
# ifndef GL_MULTISAMPLE
# define GL_MULTISAMPLE 0x809D
# endif
#endif
__GraphicRegistrator__ __graphic_registrator__;
Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), line_x_max(this), line_y_min(this), line_y_max(this) {
canvas_gl = 0;
gesture_angle = 45.;
leg_update = true;
visible_update = fullscr = need_mouse_pan = false;
gestures =
#ifdef Q_OS_ANDROID
true;
#else
false;
#endif
ui = new Ui::Graphic();
ui->setupUi(this);
line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
line_x_max.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
((QBoxLayout * )ui->widgetLY->layout())->insertWidget(0, &line_y_min);
((QBoxLayout * )ui->widgetLY->layout())->addWidget(&line_y_max);
((QBoxLayout * )ui->widgetLX->layout())->insertWidget(0, &line_x_min);
((QBoxLayout * )ui->widgetLX->layout())->addWidget(&line_x_max);
tm.restart();
grid_numbers_x = grid_numbers_y = 1;
LN10 = qLn(10.);
line_x_min.setClearButtonVisible(true);
line_x_max.setClearButtonVisible(true);
line_y_min.setClearButtonVisible(true);
line_y_max.setClearButtonVisible(true);
connect(&line_x_min, SIGNAL(valueChanged(double)), this, SLOT(lineXMinChanged(double)));
connect(&line_x_max, SIGNAL(valueChanged(double)), this, SLOT(lineXMaxChanged(double)));
connect(&line_y_min, SIGNAL(valueChanged(double)), this, SLOT(lineYMinChanged(double)));
connect(&line_y_max, SIGNAL(valueChanged(double)), this, SLOT(lineYMaxChanged(double)));
connect(ui->canvas_raster, SIGNAL(paintEvent(QPaintEvent * )), this, SLOT(canvasPaintEvent()));
prepareCanvas(ui->canvas_raster);
#ifdef HAS_GL
canvas_gl = new UGLWidget();
ui->layoutCanvas->addWidget(canvas_gl);
connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent()));
prepareCanvas(canvas_gl);
#endif
icon_exp_x = QIcon(":/icons/expand_x.png");
icon_exp_y = QIcon(":/icons/expand_y.png");
icon_exp_sx = QIcon(":/icons/expand_s_x.png");
icon_exp_sy = QIcon(":/icons/expand_s_y.png");
icon_pause_b = QImage(":/icons/pause-back.png");
icon_pause_f = QImage(":/icons/pause-front.png");
aupdate = grid = isFit = navigation = true;
aalias = bufferActive = isOGL = cancel = guides = hasLblX = hasLblY = isHover = false;
pause_ = only_expand_x = only_expand_y = false;
limit_.setCoords(-DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX);
eminx = eminy = DBL_MAX;
emaxx = emaxy = DBL_MIN;
grad_x = grad_y = Auto;
axis_type_x = Numeric;
min_repaint_int = 25;
inc_x = 1.;
buffer = 0;
gridx = gridy = 1.;
history = 5.;
visible_time = -1.;
thick = lineThickness();
pause_phase = 0.;
def_rect.setRect(0., 0., 1., 1.);
selrect = def_rect;
margins_.setRect(4, 4, 4, 4);
curaction = gaMove;
selbrush.setStyle(Qt::SolidPattern);
selbrush.setColor(QColor(60, 175, 255, 100));
text_color = palette().color(QPalette::WindowText);
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine);
graphics.append(GraphicType());
curGraphic = 0;
selpen = palette().color(QPalette::WindowText);
selpen.setStyle(Qt::DashLine);
back_color = palette().color(QPalette::Base);
buttons_ = AllButtons;
setOpenGL(false);
setButtonsPosition(Graphic::Left);
setAntialiasing(false);
setCaption("");
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
ui->layoutButtons->update();
updateLegend();
setRectToLines();
conf = new GraphicConf(graphics, this);
}
Graphic::~Graphic() {
delete conf;
if (buffer != 0) delete buffer;
}
void Graphic::changeEvent(QEvent * e) {
QFrame::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
return;
}
}
void Graphic::resizeEvent(QResizeEvent *) {
if (leg_update) updateLegend(false);
}
void Graphic::timerEvent(QTimerEvent * ) {
pause_phase += 0.02;
if (pause_phase > 1.)
pause_phase -= 1.;
update();
}
bool Graphic::eventFilter(QObject * o, QEvent * e) {
if (o == canvas) {
switch (e->type()) {
case QEvent::Gesture:
if (!navigation || !gestures) break;
foreach (QGesture * g, ((QGestureEvent*)e)->gestures())
procGesture(g);
break;
case QEvent::KeyPress: {
int k = ((QKeyEvent*)e)->key();
if ((k == Qt::Key_Back || k == Qt::Key_Escape) && fullscr) {
leaveFullscreen();
return true;
}
} break;
case QEvent::TouchBegin:
if (!navigation || !gestures) break;
need_mouse_pan = true;
break;
case QEvent::TouchUpdate: {
if (!navigation || !gestures) break;
QList<QTouchEvent::TouchPoint> tpl = ((QTouchEvent*)e)->touchPoints();
if (tpl.size() == 2) {
need_mouse_pan = false;
QPointF dp = tpl[0].scenePos() - tpl[1].scenePos();
gesture_angle = rad2deg_qpie * qAtan2(qAbs(dp.y()), qAbs(dp.x()));
}
} break;
default: break;
}
}
return QFrame::eventFilter(o, e);
}
void Graphic::prepareCanvas(QWidget * w) {
connect(w, SIGNAL(mouseMoveEvent(QMouseEvent * )), this, SLOT(canvasMouseMoveEvent(QMouseEvent * )));
connect(w, SIGNAL(mousePressEvent(QMouseEvent * )), this, SLOT(canvasMousePressEvent(QMouseEvent * )));
connect(w, SIGNAL(mouseReleaseEvent(QMouseEvent * )), this, SLOT(canvasMouseReleaseEvent(QMouseEvent * )));
connect(w, SIGNAL(mouseDoubleClickEvent(QMouseEvent*)), this, SLOT(canvasMouseDoubleClickEvent(QMouseEvent * )));
connect(w, SIGNAL(wheelEvent(QWheelEvent * )), this, SLOT(canvasWheelEvent(QWheelEvent * )));
connect(w, SIGNAL(leaveEvent(QEvent * )), this, SLOT(canvasLeaveEvent(QEvent * )));
connect(w, SIGNAL(keyPressEvent(QKeyEvent * )), this, SLOT(canvasKeyPressEvent(QKeyEvent * )));
w->grabGesture(Qt::TapAndHoldGesture);
w->grabGesture(Qt::PanGesture);
w->grabGesture(Qt::PinchGesture);
w->setMouseTracking(true);
w->installEventFilter(this);
}
void Graphic::procGesture(QGesture * g) {
if (!g) return;
switch (g->gestureType()) {
case Qt::PanGesture: {
if (need_mouse_pan) break;
QPanGesture * pg = (QPanGesture*)g;
QPointF dp = -pg->delta();
dp.rx() /= getScaleX();
dp.ry() /= getScaleY();
selrect.translate(dp);
totalUpdate();
} break;
case Qt::PinchGesture: {
QPinchGesture * pg = (QPinchGesture*)g;
Qt::KeyboardModifiers km = Qt::NoModifier;
if (gesture_angle <= 20.) km = Qt::ControlModifier;
if (gesture_angle >= 70.) km = Qt::ShiftModifier;
QPoint cp = pg->centerPoint().toPoint();
if (!fullscr) cp = mapFromGlobal(cp);
procZoom(cp, (pg->scaleFactor() - 1.) * 500., km);
totalUpdate();
} break;
case Qt::TapAndHoldGesture: {
QTapAndHoldGesture * pg = (QTapAndHoldGesture*)g;
if (pg->state() == Qt::GestureStarted)
QMetaObject::invokeMethod(this, "enterFullscreen", Qt::QueuedConnection);
} break;
default:
break;
}
}
void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km) {
double scl, wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
double px = view_center.x() - gridborder.x() - margins_.left(), py = hei - view_center.y() + margins_.height();
px = px / wid * selrect.width() + selrect.x();
py = py / hei * selrect.height() + selrect.y();
scl = 1. - dzoom / 500.;
if (km == Qt::NoModifier)
selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl);
else {
if (km == Qt::ControlModifier)
selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height());
if (km == Qt::ShiftModifier)
selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
}
}
void Graphic::totalUpdate() {
isFit = false;
emit visualRectChanged();
update(true);
setRectToLines();
}
void Graphic::canvasPaintEvent() {
if (is_lines_update) return;
int wid = canvas->width(), hei = canvas->height();
if (canvas->isHidden() || wid <= 1 || hei <= 1) return;
lastw = wid;
lasth = hei;
font_sz = fontMetrics().size(0, "0");
font_sz.setHeight(font_sz.height() * 1.);
#ifdef Q_OS_ANDROID
font_sz.setWidth(font_sz.width() * 6);
#else
font_sz.setWidth(font_sz.width() * 8);
#endif
thick = lineThickness();
if (buffer != 0) if (buffer->width() != wid || buffer->height() != hei) {delete buffer; buffer = 0;}
if (buffer == 0) buffer = new QImage(wid, hei, QImage::Format_RGB32);
if (bufferActive) {
QPainter p(canvas);
p.drawImage(0, 0, *buffer);
painter = &p;
fp_size.clear();
if (curpos != startpos) drawAction();
drawGuides();
return;
}
QPainter p;
#ifdef HAS_GL
if (isOGL) {
p.fillRect(canvas->rect(), Qt::black);
glClearColor(0.f, 0.f, 0.f, 0.f);
p.begin(canvas);
} else
#endif
p.begin(buffer);
p.fillRect(canvas->rect(), back_color);
painter = &p;
p.setFont(font());
gridborder = QPoint(5, 5);
if (grid) {
gridborder += QPoint(font_sz.width(), font_sz.height());
if (hasLblY) gridborder += QPoint(font_sz.height(), 0);
if (hasLblX) gridborder += QPoint(0, font_sz.height());
}
painter->setClipping(true);
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
emit beforeGraphicPaintEvent(painter);
painter->setClipping(false);
if (grid)
drawGrid();
p.setRenderHint(QPainter::Antialiasing, aalias);
#ifndef ANDROID
if (isOGL) {
if (aalias) glEnable(GL_MULTISAMPLE);
else glDisable(GL_MULTISAMPLE);
}
#endif
fp_size.clear();
if (!aalias) p.translate(-0.5, -0.5);
drawGraphics();
drawGuides();
if (pause_) drawPause();
emit graphicPaintEvent(painter);
p.end();
if (isOGL) return;
p.begin(canvas);
p.drawImage(0, 0, *buffer);
p.end();
}
void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
isHover = true;
curpos = e->pos();
curpos_r = canvas2real(curpos);
QPointF dp;
QString cursorstr = tr("Cursor: ") + pointCoords(curpos_r);
emit graphicMouseMoveEvent(curpos_r, e->buttons());
if (e->buttons() == Qt::NoButton) {
ui->status->setText(cursorstr);
if (guides) update();
return;
}
if (!navigation) return;
if (gestures) {
if (!need_mouse_pan) return;
curaction = gaMove;
} else
if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton) return;
switch (curaction) {
case gaZoomInRect:
ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " +
pointCoords(curpos_r) + ", " + tr("Size") + ": " + pointCoords(absPoint(curpos_r - startpos_r)));
repaintCanvas(true);
break;
case gaZoomRangeX:
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) +
" -> " + QString::number(curpos_r.x(), 'f', 3) + ", " + tr("Length") + ": " +
QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
repaintCanvas(true);
break;
case gaZoomRangeY:
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) +
" -> " + QString::number(curpos_r.y(), 'f', 3) + ", " + tr("Length") + ": " +
QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
repaintCanvas(true);
break;
case gaMove:
dp = e->pos() - prevpos;
dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw);
dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5);
if (e->modifiers() == Qt::ControlModifier)
dp.setY(0.);
if (e->modifiers() == Qt::ShiftModifier)
dp.setX(0.);
selrect.translate(dp);
totalUpdate();
break;
default: break;
}
prevpos = e->pos();
}
void Graphic::canvasMousePressEvent(QMouseEvent * e) {
emit graphicMousePressEvent(canvas2real(QPointF(e->pos())), e->button());
if (!navigation) return;
if (gestures && !need_mouse_pan) return;
#ifdef HAS_GL
canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
#endif
ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
prevpos = e->pos();
startpos = prevpos;
startpos_r = canvas2real(startpos);
if (cancel || gestures) return;
if (e->button() == Qt::MidButton) curaction = gaMove;
if (e->button() == Qt::RightButton) {
if (bufferActive) {
curpos = startpos;
curpos_r = canvas2real(curpos);
repaintCanvas(true);
swapToNormal();
cancel = true;
return;
} else {
prevaction = curaction;
curaction = gaMove;
return;
}
}
if (e->button() == Qt::LeftButton) {
if (e->modifiers() == Qt::ControlModifier) curaction = gaZoomRangeX;
else if (e->modifiers() == Qt::ShiftModifier) curaction = gaZoomRangeY;
else curaction = gaZoomInRect;
switch (curaction) {
case gaZoomInRect:
case gaZoomRangeX:
case gaZoomRangeY:
swapToBuffer();
break;
default: break;
}
}
setCurrentAction(curaction);
}
void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) {
emit graphicMouseReleaseEvent(canvas2real(QPointF(e->pos())), e->button());
if (gestures) return;
need_mouse_pan = false;
if (!navigation) return;
#ifdef HAS_GL
canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
#endif
ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
QPointF tlp, brp;
QRect sr;
sr = QRect(startpos, curpos).normalized();
if (cancel) {
if (e->buttons() == Qt::NoButton) cancel = false;
return;
}
if (e->button() == Qt::RightButton && curaction == gaMove) {
curaction = prevaction;
return;
}
if (e->button() == Qt::LeftButton && (e->buttons() & Qt::RightButton) != Qt::RightButton) {
if (curpos != startpos) {
tlp = canvas2real(sr.topLeft());
brp = canvas2real(sr.bottomRight());
isFit = false;
switch (curaction) {
case gaZoomInRect:
if (sr.width() <= 1 || sr.height() <= 1) break;
selrect.setCoords(tlp.x(), brp.y(), brp.x(), tlp.y());
setRectToLines();
break;
case gaZoomRangeX:
if (sr.width() <= 1) break;
findGraphicsRect(tlp.x(), brp.x());
break;
case gaZoomRangeY:
if (sr.height() <= 1) break;
findGraphicsRect(0., 0., brp.y(), tlp.y());
break;
default: return;
}
}
swapToNormal();
update(true);
}
QPointF rp = canvas2real(QPointF(e->pos()));
ui->status->setText(tr("Cursor") + ": " + pointCoords(rp));
emit visualRectChanged();
}
void Graphic::canvasMouseDoubleClickEvent(QMouseEvent * ) {
autofit();
}
void Graphic::canvasWheelEvent(QWheelEvent * e) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
emit graphicWheelEvent(canvas2real(e->position()), e->delta()/* TODO: test use angleDelta()*/);
#else
emit graphicWheelEvent(canvas2real(QPointF(e->pos())), e->delta());
#endif
if (gestures) return;
if (!navigation) return;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
procZoom(e->position(), e->delta(), e->modifiers());
#else
procZoom(e->pos(), e->delta(), e->modifiers());
#endif
totalUpdate();
}
void Graphic::zoom(float factor) {
double wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
double px = wid / 2, py = hei / 2;
px = px / wid * selrect.width() + selrect.x();
py = py / hei * selrect.height() + selrect.y();
selrect.setRect(px - (px - selrect.x()) * factor, py - (py - selrect.y()) * factor, selrect.width() * factor, selrect.height() * factor);
isFit = false;
update(true);
setRectToLines();
}
void Graphic::fullscreen() {
if (fullscr) leaveFullscreen();
else enterFullscreen();
}
void Graphic::canvasLeaveEvent(QEvent * ) {
isHover = false;
if (guides) update(true);
ui->status->setText(tr("Cursor") + ": ( ; )");
leaveFullscreen();
}
void Graphic::canvasKeyPressEvent(QKeyEvent * e) {
switch (e->key()) {
case Qt::Key_Escape: leaveFullscreen();
default: break;
};
}
void Graphic::clear() {
for (int i = 0; i < graphics.size(); ++i) {
graphics[i].polyline.clear();
graphics[i].polyline_pause.clear();
graphics[i].max_x = 0.;
graphics[i].cvrect = QRectF();
}
if (isFit) on_buttonAutofit_clicked();
}
void Graphic::setAntialiasing(bool enabled) {
if (aalias == enabled) return;
aalias = enabled;
update();
}
void Graphic::setPaused(bool yes) {
pause_ = yes;
ui->checkPause->blockSignals(true);
ui->checkPause->setChecked(yes);
ui->checkPause->blockSignals(false);
for (int i = 0; i < graphics.size(); ++i)
graphics[i].cvrect = QRectF();
if (!pause_) {
killTimer(timer_pause);
timer_pause = 0;
update(true);
return;
}
for (int i = 0; i < graphics.size(); ++i) {
graphics[i].polyline_pause = graphics[i].polyline;
graphics[i].polyline_pause.detach();
graphics[i].max_x_pause = graphics[i].max_x;
}
timer_pause = startTimer(40);
}
void Graphic::setHistorySize(double val) {
history = val;
double x;
for (int i = 0; i < graphics.size(); ++i) {
QPolygonF & pol(graphics[i].polyline);
if (pol.isEmpty() || history <= 0.) continue;
graphics[i].cvrect = QRectF();
x = pol.back().x() - history;
for (int j = pol.size() - 2; j >= 0 ; --j)
if (pol[j].x() < x) {
pol.erase(pol.begin(), pol.begin() + j);
break;
}
}
}
void Graphic::setMaxVisibleTime(double val) {
visible_time = val;
if (isFit) on_buttonAutofit_clicked();
}
void Graphic::setOnlyExpandY(bool yes) {
only_expand_y = yes;
ui->checkExpandY->blockSignals(true);
ui->checkExpandY->setCheckable(yes);
ui->checkExpandY->blockSignals(false);
}
void Graphic::setOnlyExpandX(bool yes) {
only_expand_x = yes;
ui->checkExpandX->blockSignals(true);
ui->checkExpandX->setCheckable(yes);
ui->checkExpandX->blockSignals(false);
}
void Graphic::setGesturesNavigation(bool yes) {
gestures = yes;
}
Graphic::GraphicsData Graphic::graphicsData() const {
GraphicsData ret;
ret.resize(graphics.size());
for (int i = 0; i < graphics.size(); ++i)
ret[i] = graphics[i].polyline;
return ret;
}
QByteArray Graphic::graphicsDataRaw() const {
QByteArray ret;
QDataStream s(&ret, QIODevice::WriteOnly);
s << graphicsData();
return ret;
}
void Graphic::setGraphicsData(const Graphic::GraphicsData & gd) {
setGraphicsCount(gd.size());
for (int i = 0; i < gd.size(); ++i)
setGraphicData(gd[i], i, false);
updateGraphics();
}
void Graphic::setGraphicsDataRaw(const QByteArray & ba) {
if (ba.isEmpty()) {
clear();
return;
}
Graphic::GraphicsData gd;
QDataStream s(ba);
s >> gd;
setGraphicsData(gd);
}
void Graphic::setButtons(Graphic::Buttons b) {
buttons_ = b;
ui->buttonAutofit->setVisible(b.testFlag(Autofit));
ui->checkGrid->setVisible(b.testFlag(Grid));
ui->checkGuides->setVisible(b.testFlag(CursorAxis));
ui->checkExpandY->setVisible(b.testFlag(OnlyExpandY));
ui->checkExpandX->setVisible(b.testFlag(OnlyExpandX));
ui->buttonFullscreen->setVisible(b.testFlag(Fullscreen));
ui->checkBorderInputs->setVisible(b.testFlag(BorderInputs));
ui->checkLegend->setVisible(b.testFlag(Legend));
ui->buttonClear->setVisible(b.testFlag(Clear));
ui->buttonConfigure->setVisible(b.testFlag(Configure));
ui->buttonSave->setVisible(b.testFlag(Save));
ui->buttonClose->setVisible(b.testFlag(Close));
ui->checkPause->setVisible(b.testFlag(Pause));
if (ui->buttonAutofit->isVisible() || ui->checkGrid->isVisible() || ui->checkGuides->isVisible() ||
ui->buttonConfigure->isVisible() || ui->buttonSave->isVisible() || ui->checkPause->isVisible())
ui->verticalSpacer->changeSize(0, 30, QSizePolicy::Preferred, QSizePolicy::Preferred);
else
ui->verticalSpacer->changeSize(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred);
ui->layoutButtons->update();
}
void Graphic::setButtonsPosition(Graphic::Alignment a) {
align = a;
ui->widgetLeft->hide();
ui->widgetRight->hide();
switch (a) {
case Graphic::Left:
ui->widgetLeft->setLayout(ui->layoutButtons);
ui->widgetLeft->show();
break;
case Graphic::Right:
ui->widgetRight->setLayout(ui->layoutButtons);
ui->widgetRight->show();
break;
}
}
void Graphic::addPoint(const QPointF & p, int graphic, bool update_) {
if (graphic >= graphics.size() || graphic < 0) return;
GraphicType & t(graphics[graphic]);
if (!t.cvrect.isNull() && !pause_) {
if (t.cvrect.top() < p.y()) t.cvrect.setTop(p.y());
if (t.cvrect.bottom() > p.y()) t.cvrect.setBottom(p.y());
if (t.cvrect.right() < p.x()) t.cvrect.setRight(p.x());
if (t.cvrect.left() > p.x()) t.cvrect.setLeft(p.x());
}
if (t.polyline.size() == 0) t.max_x = p.x();
t.polyline << p;
if (t.max_x < p.x()) t.max_x = p.x();
tick(graphic, true, update_);
}
void Graphic::setGraphicData(const QVector<QPointF> & g, int graphic, bool update_) {
if (graphic >= graphics.size() || graphic < 0) return;
GraphicType & t(graphics[graphic]);
t.cvrect = QRectF();
t.polyline.clear();
t.polyline = g;
if (t.polyline.size() == 0) {
t.max_x = 0.;
tick(graphic, false, update_);
return;
}
t.max_x = t.polyline[0].x();
for (int i = 1; i < t.polyline.size(); ++i)
if (t.max_x < t.polyline[i].x())
t.max_x = t.polyline[i].x();
tick(graphic, false, update_);
}
void Graphic::setGraphicProperties(int graphic, const QString & name, const QColor& color, Qt::PenStyle style, double width, bool visible) {
if (graphic < 0 || graphic >= graphics.size()) return;
graphics[graphic].name = name;
graphics[graphic].pen.setColor(color);
graphics[graphic].pen.setStyle(style);
graphics[graphic].pen.setWidth(width);
graphics[graphic].visible = visible;
updateLegend();
}
void Graphic::addGraphic(const QString & name, const QColor & color, Qt::PenStyle style, double width, bool visible) {
graphics << GraphicType(name, color, style, width, visible);
updateLegend();
}
void Graphic::setVisualRect(const QRectF & rect) {
selrect = rect;
isFit = false;
update();
}
void Graphic::setDefaultRect(const QRectF & rect) {
def_rect = rect;
if (isFit) autofit();
}
void Graphic::saveImage() {
QString str = QFileDialog::getSaveFileName(this, tr("Save Image"), ppath, "PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)");
if (str == "") return;
ppath = str;
QPixmap im(canvas->size());
canvas->render(&im);
im.save(ppath);
update(true);
}
void Graphic::setOpenGL(bool on) {
#ifdef HAS_GL
isOGL = on;
if (on) {
ui->canvas_raster->hide();
canvas_gl->show();
canvas = canvas_gl;
} else {
canvas_gl->hide();
ui->canvas_raster->show();
canvas = ui->canvas_raster;
}
#else
isOGL = false;
ui->canvas_raster->show();
canvas = ui->canvas_raster;
#endif
update();
}
void Graphic::update(bool force) {
repaintCanvas(force);
}
void Graphic::setGraphicsCount(int arg, bool update) {
if (arg < 0) return;
while (graphics.size() < arg) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115)));
#else
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115)));
#endif
}
while (graphics.size() > arg) {
delete graphics.back().pb;
graphics.pop_back();
}
if (update) updateLegend();
}
void Graphic::removeGraphic(int arg, bool update) {
if (arg < 0 || arg >= graphics.size()) return;
delete graphics[arg].pb;
graphics.remove(arg);
if (update) updateLegend();
}
void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, double end_y) {
double cx, cy, maxX, minX, maxY, minY, vx;
bool isRangeX = (start_x != end_x), isRangeY = (start_y != end_y);
bool can_fast = (start_x == 0 && end_x == 0 && start_y == 0 && end_y == 0);
bool anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY);
vx = -DBL_MAX;
minY = minX = DBL_MAX;
maxY = maxX = -DBL_MAX;
foreach (const GraphicType & t, graphics) {
if (!t.visible) continue;
if (vx < (pause_ ? t.max_x_pause : t.max_x)) vx = (pause_ ? t.max_x_pause : t.max_x);
}
vx -= visible_time;
for (int g = 0; g < graphics.size(); g++) {
GraphicType & t(graphics[g]);
if (!t.visible) continue;
const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline);
if (pol.isEmpty()) continue;
bool f = true;
if (t.cvrect.isNull() || !can_fast) {
for (int i = 0; i < pol.size(); i++) {
cx = pol[i].x();
cy = pol[i].y();
if ((start_x > cx || end_x < cx) && isRangeX) continue;
if ((start_y > cy || end_y < cy) && isRangeY) continue;
if ((cx < vx) && isTimeLimit) continue;
if (f) {
t.cvrect.setRect(cx, cy, 0, 0);
f = false;
} else {
if (t.cvrect.top() < cy) t.cvrect.setTop(cy);
if (t.cvrect.bottom() > cy) t.cvrect.setBottom(cy);
if (t.cvrect.right() < cx) t.cvrect.setRight(cx);
if (t.cvrect.left() > cx) t.cvrect.setLeft(cx);
}
}
if (f) continue;
}
anyVisible = true;
if (maxY < t.cvrect.top()) maxY = t.cvrect.top();
if (minY > t.cvrect.bottom()) minY = t.cvrect.bottom();
if (maxX < t.cvrect.right()) maxX = t.cvrect.right();
if (minX > t.cvrect.left()) minX = t.cvrect.left();
if (!can_fast) t.cvrect = QRectF();
}
if (!anyVisible) {
grect = def_rect;
setRectToLines();
return;
}
if (maxX > limit_.right()) maxX = limit_.right();
if (minX > limit_.right()) minX = limit_.right();
if (minX < limit_.left()) minX = limit_.left();
if (maxX < limit_.left()) maxX = limit_.left();
if (maxY > limit_.bottom()) maxY = limit_.bottom();
if (minY > limit_.bottom()) minY = limit_.bottom();
if (minY < limit_.top()) minY = limit_.top();
if (maxY < limit_.top()) maxY = limit_.top();
if (minX > maxX) qSwap<double>(minX, maxX);
if (minY > maxY) qSwap<double>(minY, maxY);
if (qAbs<double>(minX - maxX) < 1E-60) {minX -= defaultRect().width()/2; maxX += defaultRect().width()/2;}
if (qAbs<double>(minY - maxY) < 1E-60) {minY -= defaultRect().height()/2; maxY += defaultRect().height()/2;}
if (only_expand_x) {
if (minX > eminx) minX = eminx;
if (maxX < emaxx) maxX = emaxx;
}
if (only_expand_y) {
if (minY > eminy) minY = eminy;
if (maxY < emaxy) maxY = emaxy;
}
eminx = minX; emaxx = maxX;
eminy = minY; emaxy = maxY;
if (isRangeX) selrect.setRect(start_x, minY, end_x - start_x, maxY - minY);
else if (isRangeY) selrect.setRect(minX, start_y, maxX - minX, end_y - start_y);
else grect.setRect(minX, minY, maxX - minX, maxY - minY);
grect = grect.normalized();
if (isFit) {
if (visible_time > 0.) {
if (grect.width() > visible_time)
grect.setLeft(grect.right() - visible_time);
}
selrect = grect;
}
setRectToLines();
}
void Graphic::drawAction() {
int wid = canvas->width(), hei = canvas->height() - gridborder.y(), sx = startpos.x(), sy = startpos.y(), cx = curpos.x(), cy = curpos.y();
painter->setPen(selpen);
painter->setBrush(selbrush);
switch (curaction) {
case gaZoomInRect: {
QSizeF rsz = QRectF(startpos_r, curpos_r).normalized().size();
painter->drawRect(QRect(startpos, curpos));
fp_size = " x " + pointCoords(QPointF(rsz.width(), rsz.height()));
} break;
case gaZoomRangeX:
painter->drawLine(sx, hei, sx, 0);
painter->drawLine(cx, hei, cx, 0);
painter->fillRect(sx, 0, cx - sx, hei, selbrush);
fp_size = " x " + pointCoords(QPointF(qAbs(startpos_r.x() - curpos_r.x()), 0.), true, false);
break;
case gaZoomRangeY:
painter->drawLine(gridborder.x(), sy, wid, sy);
painter->drawLine(gridborder.x(), cy, wid, cy);
painter->fillRect(gridborder.x(), sy, wid - gridborder.x(), cy - sy, selbrush);
fp_size = " x " + pointCoords(QPointF(0., qAbs(startpos_r.y() - curpos_r.y())), false, true);
break;
default: break;
}
}
void Graphic::drawGrid() {
int gbx = gridborder.x(), gby = gridborder.y(), cwid = canvas->width(), chei = canvas->height();
double px, py, range, step, start;
int wid = cwid - gbx - 5, hei = chei - gby - 5, cx, cy, cnt;
QRect rect;
QPair<QString, QString> str;
range = selrect.bottom() - selrect.top();
if (grad_y == Graphic::Auto) step = splitRange(range, hei / gridy / font_sz.height() / 1.4);
else step = gridy;
start = roundTo(canvas2realY(-hei), step) - step;
py = start + step;
cy = 0;
cx = gbx - 5;
grid_pen.setWidth(qMax<int>(qMax<int>(qRound(thick / 1.4), 1), grid_pen.width()));
QFont sf = font();
QFont nf = sf;
sf.setPointSizeF(qMax<qreal>(sf.pointSizeF() / 1.6, 7.));
QFontMetrics fm(nf), sfm(sf);
if (step > 0.) {
cnt = 1000;
while (cnt-- > 0) {
py -= step;
if (fabs(py) < step * .5) py = 0.;
cy = real2canvasY(py);
if (cy < 0) continue;
if (cy > hei + 5) break;
painter->setPen(grid_pen);
painter->drawLine(gbx, cy, cwid, cy);
str = gridMark(py * grid_numbers_y);
painter->setPen(text_color);
cy += font_sz.height() / 4.;
int dx = font_sz.height() / 8.;
if (!str.second.isEmpty()) {
rect = sfm.boundingRect(str.second);
painter->setFont(sf);
painter->drawText(cx - rect.width() - dx, cy - font_sz.height() / 2.5, str.second);
dx += rect.width() + font_sz.height() / 6.;
}
rect = fm.boundingRect(str.first);
painter->setFont(nf);
painter->drawText(cx - rect.width() - dx, cy, str.first);
}
}
cy = real2canvasY(0.);
if (cy >= 0 && cy <= (hei + 5)) {
QPen _p(grid_pen);
_p.setStyle(Qt::SolidLine);
painter->setPen(_p);
painter->drawLine(gbx, cy, cwid, cy);
}
if (hasLblY) {
painter->setPen(text_color);
painter->save();
painter->translate(5, hei);
painter->rotate(-90.);
painter->drawText(0, 0, hei, font_sz.height(), Qt::AlignCenter, label_y);
painter->restore();
}
cy = chei - font_sz.height() / 4;
if (hasLblX) cy -= font_sz.height();
range = selrect.right() - selrect.left();
QString df;
if (axis_type_x == Graphic::Numeric) {
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
else step = gridx;
start = roundTo(canvas2realX(wid), step) + step;
px = start + step;
if (step > 0.) {
cnt = 1000;
while (cnt-- > 0) {
px -= step;
if (fabs(px) < step * .5) px = 0.;
cx = real2canvasX(px);
if (cx > cwid) continue;
if (cx < gbx) break;
painter->setPen(grid_pen);
painter->drawLine(cx, hei + 5, cx, 0);
painter->setPen(text_color);
int dx = -font_sz.height() / 4.;
painter->setFont(nf);
str = gridMark(px * grid_numbers_x);
rect = fm.boundingRect(str.first);
painter->drawText(cx + dx, cy, str.first);
dx += rect.width() + font_sz.height() / 6.;
if (!str.second.isEmpty()) {
rect = sfm.boundingRect(str.second);
painter->setFont(sf);
painter->drawText(cx + dx, cy - font_sz.height() / 4., str.second);
}
}
}
cx = real2canvasX(0.);
if (cx <= cwid && cx >= gbx) {
QPen _p(grid_pen);
_p.setStyle(Qt::SolidLine);
painter->setPen(_p);
painter->drawLine(cx, hei + 5, cx, 0);
}
} else {
int cur_scl[7] = {0,0,0,0,0,0,0};
step = splitRangeDate(range, wid / gridx / font_sz.width() * 1.4, &df, cur_scl);
start = roundTo(canvas2realX(wid), step) + step;
px = start + step;
QDateTime cd = QDateTime::fromMSecsSinceEpoch(px * grid_numbers_x);
roundDateTime(cd, cur_scl);
addDateTime(cd, cur_scl);
if (step > 0.) {
cnt = 1000;
while (cnt-- > 0) {
addDateTime(cd, cur_scl, -1);
cx = real2canvasX(cd.toMSecsSinceEpoch() / grid_numbers_x);
if (cx > cwid) continue;
if (cx < gbx) break;
painter->setPen(grid_pen);
painter->drawLine(cx, hei + 5, cx, 0);
painter->setPen(text_color);
int dx = -font_sz.height() / 4.;
painter->setFont(nf);
str.first = cd.toString(df);
painter->drawText(cx + dx, cy, str.first);
}
}
}
painter->setPen(text_color);
painter->setFont(nf);
if (hasLblX) {
painter->setPen(text_color);
painter->drawText(gbx, chei - font_sz.height(), wid, font_sz.height(), Qt::AlignCenter, label_x);
}
painter->setPen(QPen(grid_pen.color(), qMax<int>(thick, grid_pen.width())));
painter->drawRect(gbx, -1, wid + 6, hei + 6);
}
QPair<QString, QString> Graphic::gridMark(double v) const {
QPair<QString, QString> ret;
if ((qAbs(v) >= 1E+4 || qAbs(v) <= 1E-4) && v != 0.) {
int p = qFloor(qLn(qAbs(v)) / LN10);
v /= qPow(10., p);
if (v == 10.) {
v = 1.;
p += 1;
}
ret.first = QString::fromUtf8("%1·10").arg(v);
ret.second = QString::number(p);
} else
ret.first = QString::number(v);
return ret;
}
void Graphic::drawGraphics() {
if (isHover)
ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
QPointF srp = -selrect.topLeft();
double sclx, scly, wid = canvas->width(), hei = canvas->height();
sclx = (wid - gridborder.x() - margins_.left() - margins_.width()) / selrect.width();
scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height();
painter->setClipping(true);
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
painter->translate(gridborder.x() + margins_.left(), hei - gridborder.y() - margins_.top());
painter->scale(sclx, -scly);
painter->translate(srp);
QTransform mat = painter->transform();
painter->resetTransform();
painter->setWorldMatrixEnabled(false);
QPolygonF cpol;
QPen pen;
for (int i = 0; i < graphics.size(); ++i) {
GraphicType & t(graphics[i]);
QPolygonF & rpol(pause_ ? t.polyline_pause : t.polyline);
if (t.visible && !rpol.isEmpty()) {
pen = t.pen;
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick);
else pen.setWidthF(pen.widthF()*thick);
pen.setCosmetic(true);
if (t.lines) {
painter->setPen(pen);
if (t.fill) {
cpol = rpol;
painter->setBrush(t.fill_color);
painter->drawPolygon(mat.map(cpol));
} else
painter->drawPolyline(mat.map(rpol));
}
if (t.points) {
if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick));
else pen.setWidthF(t.pointWidth*thick);
painter->setPen(pen);
painter->drawPoints(mat.map(rpol));
}
}
}
painter->setWorldMatrixEnabled(true);
}
QString Graphic::pointCoords(QPointF point, bool x, bool y) {
QString ret = "(";
if (x) {
if (axis_type_x == Numeric)
ret += QString::number(point.x(), 'f', 3);
else
ret += QDateTime::fromMSecsSinceEpoch(point.x()).toString();
}
if (y) {
if (ret.size() > 1) ret += " ; ";
ret += QString::number(point.y(), 'f', 3);
}
ret += ")";
return ret;
}
void Graphic::drawGuides() {
if (!guides || !isHover) return;
int wid = canvas->width(), hei = canvas->height();
painter->setRenderHint(QPainter::Antialiasing, false);
painter->setPen(QPen(grid_pen.color(), qMax<int>(qRound(thick / 1.4), 1)));
painter->resetTransform();
painter->setClipping(true);
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
painter->drawLine(0, curpos.y(), wid, curpos.y());
painter->drawLine(curpos.x(), 0, curpos.x(), hei);
QString str = pointCoords(canvas2real(curpos)) + fp_size;
QFontMetrics fm(font());
QRect r = fm.boundingRect(str);
QPoint p = curpos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.);
if (r.width() + curpos.x() > wid - font_sz.height() / 2.) p.setX(curpos.x() - r.width() - font_sz.height() / 4.);
if (curpos.y() - r.height() < font_sz.height() / 8.) p.setY(curpos.y() + r.height() - font_sz.height() / 8.);
painter->setPen(text_color);
painter->drawText(p, str);
}
void Graphic::drawPause() {
painter->setClipping(false);
painter->save();
painter->resetTransform();
painter->translate(canvas->width() - icon_pause_b.width() - 6, 6);
double o = (0.5 - pause_phase) * 2;
painter->setOpacity(o*o);
painter->drawImage(0, 0, icon_pause_b);
painter->setOpacity(1.);
painter->drawImage(0, 0, icon_pause_f);
painter->restore();
painter->setClipping(true);
}
double Graphic::splitRange(double range, int count) {
double digits, step, tln;
range = qAbs<double>(range);
tln = qFloor(qLn(range) / LN10);
for (int i = 0; i <= 5; ++i) {
digits = qPow(10., tln - i);
step = qRound(range / count / digits);
if (step > 0.) {
digits = qPow(10., tln - i - 1);
step = qRound(range / count / digits);
break;
}
}
double step5 = qRound(step / 5.) * 5., step10 = qRound(step / 10.) * 10.;
double err5 = qAbs<double>(step - step5), err10 = qAbs<double>(step - step10);
step = (err5 < err10 ? step5 : step10) * digits;
return step;
}
double Graphic::splitRangeDate(double range, int count, QString * format, int step[7]) {
double ret = splitRange(range, count);
if (ret < 1000. * 1) {*format = "ss.zzz"; step[0] = ret;}
else if (ret < 1000. * 60) {*format = "h:m:ss"; step[1] = qRound(ret / 1000);}
else if (ret < 1000. * 60 * 60) {*format = "h:mm"; step[2] = qRound(ret / 1000 / 60);}
else if (ret < 1000. * 60 * 60 * 24) {*format = "dd(ddd) hh"; step[3] = qRound(ret / 1000 / 60 / 60);}
else if (ret < 1000. * 60 * 60 * 24 * 30) {*format = "MMM dd"; step[4] = qRound(ret / 1000 / 60 / 60 / 24);}
else if (ret < 1000. * 60 * 60 * 24 * 30 * 12) {*format = "yyyy MMM"; step[5] = qRound(ret / 1000 / 60 / 60 / 24 / 30);}
else {*format = "yyyy"; step[6] = qRound(ret / 1000 / 60 / 60 / 24 / 30 / 12);}
return ret;
}
double Graphic::roundTo(double value, double round_to) {
if (round_to == 0.) return value;
return qRound(value / round_to) * round_to;
}
void Graphic::roundDateTime(QDateTime & dt, int c[7]) {
QDate d(dt.date()); QTime t(dt.time());
if (c[1] != 0) t.setHMS(t.hour(), t.minute(), t.second());
if (c[2] != 0) t.setHMS(t.hour(), t.minute(), 0);
if (c[3] != 0) t.setHMS(t.hour(), 0, 0);
if (c[4] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), d.day());}
if (c[5] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), 1);}
if (c[6] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), 1, 1);}
dt = QDateTime(d, t);
}
void Graphic::addDateTime(QDateTime & dt, int c[7], int mul) {
if (c[0] != 0) dt = dt.addMSecs(mul * c[0]);
if (c[1] != 0) dt = dt.addSecs(mul * c[1]);
if (c[2] != 0) dt = dt.addSecs(mul * c[2] * 60);
if (c[3] != 0) dt = dt.addSecs(mul * c[3] * 60 * 60);
if (c[4] != 0) dt = dt.addDays(mul * c[4]);
if (c[5] != 0) dt = dt.addMonths(mul * c[5]);
if (c[6] != 0) dt = dt.addYears(mul * c[6]);
}
double Graphic::canvas2realX(double px) const {
int gbx = gridborder.x() + margins_.left(), cwid = lastw, wid = cwid - gbx - margins_.width();
double cx = px - gbx, sclx = selrect.width() / (double)wid;
return cx * sclx + selrect.x();
}
double Graphic::canvas2realY(double py) const {
int gby = gridborder.y() + margins_.top(), chei = lasth, hei = chei - gby - margins_.height();
double cy = chei - py - gby, scly = selrect.height() / (double)hei;
return cy * scly + selrect.y();
}
double Graphic::real2canvasX(double px) const {
int gbx = gridborder.x() + margins_.left(), cwid = lastw, wid = cwid - gbx - margins_.width();
double sclx = selrect.width() / (double)wid;
return (px - selrect.x()) / sclx + gbx;
}
double Graphic::real2canvasY(double py) const {
int gby = gridborder.y() + margins_.top(), chei = lasth, hei = chei - gby - margins_.height();
double scly = selrect.height() / (double)hei;
return chei - gby - (py - selrect.y()) / scly;
}
QPolygonF Graphic::real2canvas(const QPolygonF & real_polygon) const {
QPolygonF ret;
for (int i=0; i<real_polygon.size(); ++i)
ret << real2canvas(real_polygon[i]);
return ret;
}
QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
QPolygonF ret;
for (int i=0; i<canvas_polygon.size(); ++i)
ret << canvas2real(canvas_polygon[i]);
return ret;
}
void Graphic::setCurrentAction(GraphicAction action) {
curaction = action;
switch (action) {
case gaNone:
if (guides) setCanvasCursor(Qt::BlankCursor);
else setCanvasCursor(Qt::ArrowCursor);
break;
case gaZoomInRect:
setCanvasCursor(Qt::CrossCursor);
break;
case gaZoomRangeX:
setCanvasCursor(Qt::SplitHCursor);
break;
case gaZoomRangeY:
setCanvasCursor(Qt::SplitVCursor);
break;
case gaMove:
setCanvasCursor(Qt::SizeAllCursor);
break;
}
}
void Graphic::setCanvasCursor(QCursor cursor) {
ui->canvas_raster->setCursor(cursor);
#ifdef HAS_GL
canvas_gl->setCursor(cursor);
#endif
}
void Graphic::swapToBuffer() {
QImage timg;
#ifdef HAS_GL
if (isOGL) {
timg = canvas_gl->grabFrameBuffer();
QPainter p(buffer);
p.drawImage(0, 0, timg);
p.end();
}
#endif
bufferActive = true;
}
void Graphic::setRectToLines() {
is_lines_update = true;
if (line_x_min.isVisible() && line_x_max.isVisible() && line_y_min.isVisible() && line_y_max.isVisible()) {
line_x_min.blockSignals(true); line_x_max.blockSignals(true); line_y_min.blockSignals(true); line_y_max.blockSignals(true);
if (!line_x_min.hasFocus()) {
if (isFit) line_x_min.setValue(grect.left());
else line_x_min.setValue(selrect.left());
}
if (!line_x_max.hasFocus()) {
if(isFit) line_x_max.setValue(grect.right());
else line_x_max.setValue(selrect.right());
}
if (!line_y_min.hasFocus()) {
if(isFit) line_y_min.setValue(grect.bottom());
else line_y_min.setValue(selrect.bottom());
}
if (!line_y_max.hasFocus()) {
if(isFit) line_y_max.setValue(grect.top());
else line_y_max.setValue(selrect.top());
}
line_x_min.setDefaultText(QString::number(grect.left()).toUpper());
line_x_max.setDefaultText(QString::number(grect.right()).toUpper());
line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper());
line_y_max.setDefaultText(QString::number(grect.top()).toUpper());
line_x_min.blockSignals(false); line_x_max.blockSignals(false); line_y_min.blockSignals(false); line_y_max.blockSignals(false);
}
is_lines_update = false;
}
void Graphic::checkLines() {
isFit = (line_x_min.isCleared() && line_x_max.isCleared() && line_y_min.isCleared() && line_y_max.isCleared());
update(true);
}
void Graphic::tick(int index, bool slide, bool update_) {
if (slide) {
GraphicType & t(graphics[index]);
if (history > 0.)
while (t.polyline.size() > 1) {
if (fabs(t.polyline.back().x() - t.polyline.front().x()) <= history) break;
/// TODO: [Graphic] fast autofit while addPoint(double y, ...)
if (!t.cvrect.isNull()) {
QPointF fp(t.polyline.first());
if (qFuzzyCompare(t.cvrect.left(), fp.x()) ||
qFuzzyCompare(t.cvrect.right(), fp.x()) ||
qFuzzyCompare(t.cvrect.top(), fp.y()) ||
qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
t.cvrect = QRectF();
}
}
t.polyline.pop_front();
}
}
if (!update_) {
if (isFit) findGraphicsRect();
return;
}
if (isFit) findGraphicsRect();
if (!slide) {
if (aupdate) update();
return;
}
if (aupdate) update();
}
void Graphic::on_buttonAutofit_clicked() {
isFit = true;
bool isEmpty = true;
foreach (const GraphicType & t, graphics) {
const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline);
if (!pol.isEmpty()) {
isEmpty = false;
break;
}
}
if (isEmpty) grect = def_rect;
selrect = grect;
findGraphicsRect();
update();
}
void Graphic::on_buttonConfigure_clicked() {
conf->graphicItems.clear();
for (int i = 0; i < graphics.size(); i++) {
GraphicConf::GraphicItem item;
item.icon = graphics[i].icon;
item.name = graphics[i].name;
conf->graphicItems.append(item);
}
conf->ui->colorGrid->setColor(grid_pen.color());
conf->ui->comboStyleGrid->setCurrentIndex((int)grid_pen.style());
conf->ui->spinWidthGrid->setValue(grid_pen.widthF());
conf->ui->checkOGL->setChecked(isOGL);
conf->ui->checkAAlias->setChecked(aalias);
conf->ui->checkInputs->setChecked(borderInputsVisible());
conf->ui->checkStatus->setChecked(statusVisible());
conf->ui->checkLegend->setChecked(legendVisible());
conf->ui->checkGridAutoX->setChecked(grad_x == Auto);
conf->ui->checkGridAutoY->setChecked(grad_y == Auto);
conf->ui->colorBackground->setColor(back_color);
conf->ui->colorText->setColor(text_color);
conf->ui->spinGridStepX->setValue(gridx);
conf->ui->spinGridStepY->setValue(gridy);
conf->ui->spinMarginL->setValue(margins_.left());
conf->ui->spinMarginT->setValue(margins_.height());
conf->ui->spinMarginR->setValue(margins_.width());
conf->ui->spinMarginB->setValue(margins_.top());
conf->readParams();
if (conf->exec() == QDialog::Rejected) return;
grid_pen = QPen(conf->ui->colorGrid->color(), conf->ui->spinWidthGrid->value(), (Qt::PenStyle)conf->ui->comboStyleGrid->currentIndex());
back_color = conf->ui->colorBackground->color();
text_color = conf->ui->colorText->color();
grad_x = conf->ui->checkGridAutoX->isChecked() ? Auto : Fixed;
grad_y = conf->ui->checkGridAutoY->isChecked() ? Auto : Fixed;
gridx = conf->ui->spinGridStepX->value();
gridy = conf->ui->spinGridStepY->value();
setOpenGL(conf->ui->checkOGL->isChecked());
setAntialiasing(conf->ui->checkAAlias->isChecked());
setBorderInputsVisible(conf->ui->checkInputs->isChecked());
setStatusVisible(conf->ui->checkStatus->isChecked());
setLegendVisible(conf->ui->checkLegend->isChecked());
setMargins(conf->ui->spinMarginL->value(), conf->ui->spinMarginR->value(), conf->ui->spinMarginT->value(), conf->ui->spinMarginB->value());
updateLegend();
update();
}
void Graphic::on_checkGuides_toggled(bool checked) {
guides = checked;
if (guides) setCanvasCursor(Qt::BlankCursor);
else setCanvasCursor(Qt::ArrowCursor);
update();
}
void Graphic::updateLegend(bool es) {
QPixmap pix(60, 22);
for (int i = 0; i < graphics.size(); i++) {
pix.fill(back_color);
QPainter p(&pix);
QPen pen = graphics[i].pen;
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick);
else pen.setWidthF(pen.widthF()*thick);
p.setPen(pen);
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
p.end();
graphics[i].icon = QIcon(pix);
}
if (!ui->widgetLegend->isVisibleTo(this)) {
if (es) emit graphicSettingsChanged();
return;
}
leg_update = false;
int ps = 100;
for (int r = 0; r < ui->layoutLegend->rowCount(); ++r)
for (int c = 0; c < ui->layoutLegend->columnCount(); ++c) {
QLayoutItem * li = ui->layoutLegend->itemAtPosition(r, c);
if (!li) continue;
if (!li->widget()) continue;
while (li->widget()->actions().isEmpty())
li->widget()->removeAction(li->widget()->actions()[0]);
delete li->widget();
}
ui->layoutLegend->invalidate();
for (int i = 0; i < graphics.size(); i++) {
graphics[i].pb = new QCheckBox(graphics[i].name);
graphics[i].pb->setIconSize(pix.size());
graphics[i].pb->setIcon(graphics[i].icon);
graphics[i].pb->setChecked(graphics[i].visible);
graphics[i].pb->setProperty("graphic_num", i);
graphics[i].pb->setContextMenuPolicy(Qt::ActionsContextMenu);
QAction * act = new QAction(tr("Check all"), 0);
act->setCheckable(true);
act->setChecked(true);
graphics[i].pb->addAction(act);
connect(act, SIGNAL(triggered(bool)), this, SLOT(graphicAllVisibleChange(bool)));
connect(graphics[i].pb, SIGNAL(toggled(bool)), this, SLOT(graphicVisibleChange(bool)));
int cps = graphics[i].pb->sizeHint().width() + 4;
if (cps > ps) ps = cps;
}
int maxcol = qMax<int>(ui->widgetLegend->width() / ps - 1, 1);
int row = 0, col = 0;
bool lv = ui->widgetLegend->isVisibleTo(this);
ui->widgetLegend->hide();
for (int i = 0; i < graphics.size(); i++) {
ui->layoutLegend->addWidget(graphics[i].pb,row,col);
graphics[i].pb->show();
col++;
if (col > maxcol) {col = 0; row++;}
}
ui->widgetLegend->setVisible(lv);
leg_update = true;
if (es) emit graphicSettingsChanged();
}
void Graphic::updateLegendChecks() {
for (int i = 0; i < graphics.size(); i++) {
if (!graphics[i].pb) continue;
bool pbs = graphics[i].pb->blockSignals(true);
graphics[i].pb->setChecked(graphics[i].visible);
graphics[i].pb->blockSignals(pbs);
}
emit graphicSettingsChanged();
}
void Graphic::graphicVisibleChange(bool checked) {
if (visible_update) return;
QCheckBox * cb = qobject_cast<QCheckBox*>(sender());
int i = cb->property("graphic_num").toInt();
graphics[i].visible = checked;
if (isFit) on_buttonAutofit_clicked();
else update();
emit graphicSettingsChanged();
}
void Graphic::graphicAllVisibleChange(bool checked) {
visible_update = true;
for (int i=0; i<graphics.size(); i++) {
graphics[i].visible = checked;
graphics[i].pb->setChecked(checked);
}
visible_update = false;
if (isFit) on_buttonAutofit_clicked();
else update();
emit graphicSettingsChanged();
}
void Graphic::enterFullscreen() {
if (fullscr) return;
fullscr = true;
canvas->hide();
#ifdef Q_OS_ANDROID
tm_fscr.restart();
QDialog dlg;
dlg.setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
dlg.layout()->setContentsMargins(0, 0, 0, 0);
dlg.layout()->addWidget(canvas);
QPushButton * btn = new QPushButton("Leave fullscreen");
dlg.layout()->addWidget(btn);
connect(btn, SIGNAL(clicked(bool)), this, SLOT(leaveFullscreen()));
canvas->show();
dlg.showFullScreen();
dlg.exec();
dlg.layout()->removeWidget(canvas);
leaveFullscreen();
#else
ui->layoutCanvas->removeWidget(canvas);
canvas->setParent(0);
canvas->showFullScreen();
canvas->setFocus();
canvas->raise();
#endif
}
void Graphic::leaveFullscreen() {
#ifdef Q_OS_ANDROID
if (tm_fscr.elapsed() < 100) return;
#endif
if (!fullscr) return;
fullscr = false;
#ifndef Q_OS_ANDROID
canvas->showNormal();
canvas->hide();
#endif
ui->layoutCanvas->addWidget(canvas);
canvas->show();
}
QString Graphic::caption() const {
return ui->labelCaption->text();
}
bool Graphic::borderInputsVisible() const {
return ui->widgetLX->isVisible();
}
bool Graphic::statusVisible() const {
return ui->status->isVisible();
}
bool Graphic::legendVisible() const {
return ui->widgetLegend->isVisible();
}
QByteArray Graphic::save() {
// QByteArray ba;
// QDataStream s(&ba, QIODevice::ReadWrite);
// s << openGL() << antialiasing() << borderInputsVisible() << statusVisible() << legendVisible();
// s << graphics;
// return ba;
// version '2':
ChunkStream cs;
cs.add(1, antialiasing()).add(2, openGL()).add(3, borderInputsVisible()).add(4, statusVisible()).add(5, legendVisible());
cs.add(6, backgroundColor()).add(7, textColor()).add(8, margins());
cs.add(9, gridPen()).add(10, graduationX()).add(11, graduationY()).add(12, graduationStepX()).add(13, graduationStepY());
cs.add(14, graphics);
cs.add(15, isFit).add(16, visualRect());
if (backgroundColor() == palette().color(QPalette::Base) &&
textColor() == palette().color(QPalette::WindowText) &&
gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText))
cs.add(17, true);
return cs.data().prepend('2');
}
void Graphic::load(QByteArray ba) {
if (ba.isEmpty()) return;
char ver = ba[0];
switch(ver) {
case '2': {// version '2':
ba.remove(0, 1);
QRectF vrect;
ChunkStream cs(ba);
bool def_colors = false;
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: setAntialiasing(cs.getData<bool>()); break;
case 2: setOpenGL(cs.getData<bool>()); break;
case 3: setBorderInputsVisible(cs.getData<bool>()); break;
case 4: setStatusVisible(cs.getData<bool>()); break;
case 5: setLegendVisible(cs.getData<bool>()); break;
case 6: if (!def_colors) setBackgroundColor(cs.getData<QColor>()); break;
case 7: if (!def_colors) setTextColor(cs.getData<QColor>()); break;
case 8: setMargins(cs.getData<QRect>()); break;
case 9: if (!def_colors) setGridPen(cs.getData<QPen>()); break;
case 10: setGraduationX(cs.getData<Graduation>()); break;
case 11: setGraduationY(cs.getData<Graduation>()); break;
case 12: setGraduationStepX(cs.getData<double>()); break;
case 13: setGraduationStepY(cs.getData<double>()); break;
case 14: graphics = cs.getData<QVector<GraphicType> >(); break;
case 15: isFit = cs.getData<bool>(); break;
case 16: vrect = cs.getData<QRectF>(); break;
case 17: if(cs.getData<bool>()) {
setTextColor(palette().color(QPalette::WindowText));
setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine));
setBackgroundColor(palette().color(QPalette::Base));
def_colors = true;
} break;
default: break;
}
}
if (!isFit) setVisualRect(vrect);
} break;
default: {// old version 0:
QDataStream s(ba);
bool a;
s >> a; setOpenGL(a);
s >> a; setAntialiasing(a);
s >> a; setBorderInputsVisible(a);
s >> a; setStatusVisible(a);
s >> a;
s >> graphics;
setLegendVisible(a);
} break;
}
}
void Graphic::setCaption(const QString & str) {
ui->labelCaption->setText(str);
ui->labelCaption->setVisible(str.length() > 0);
if (aupdate) update();
}
void Graphic::setGridEnabled(bool enabled) {
ui->checkGrid->setChecked(enabled);
}
void Graphic::setBorderInputsVisible(bool visible) {
ui->widgetLX->setVisible(visible);
ui->widgetLY->setVisible(visible);
ui->checkBorderInputs->setChecked(visible);
if (visible) setRectToLines();
}
void Graphic::setStatusVisible(bool visible) {
ui->status->setVisible(visible);
}
void Graphic::setLegendVisible(bool visible) {
ui->widgetLegend->setVisible(visible);
ui->checkLegend->setChecked(visible);
updateLegend();
}
void Graphic::on_checkExpandY_toggled(bool checked) {
only_expand_y = checked;
ui->checkExpandY->setIcon(checked ? icon_exp_y : icon_exp_sy);
}
void Graphic::on_checkExpandX_toggled(bool checked) {
only_expand_x = checked;
ui->checkExpandX->setIcon(checked ? icon_exp_x : icon_exp_sx);
}

461
libs/graphic/graphic.h Normal file
View File

@@ -0,0 +1,461 @@
/*
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRAPHIC_H
#define GRAPHIC_H
#include <QWidget>
#include <QPainter>
#include <QPixmap>
#include <QMouseEvent>
#include <QComboBox>
#include <QDebug>
#include <QGridLayout>
#include <QFileDialog>
#include <QElapsedTimer>
#include <QTranslator>
#include <QGestureEvent>
#include <qmath.h>
#include <float.h>
#include "graphic_conf.h"
#include "evalspinbox.h"
#include "qad_graphic_export.h"
namespace Ui {
class Graphic;
}
class UGLWidget;
Q_DECLARE_METATYPE(QVector<QPointF>)
class QAD_GRAPHIC_EXPORT Graphic: public QFrame
{
Q_OBJECT
Q_FLAGS(Buttons)
Q_ENUMS(Alignment Graduation AxisType)
Q_PROPERTY(QString caption READ caption WRITE setCaption)
Q_PROPERTY(QString labelX READ labelX WRITE setLabelX)
Q_PROPERTY(QString labelY READ labelY WRITE setLabelY)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
Q_PROPERTY(int currentGraphic READ currentGraphic WRITE setCurrentGraphic)
Q_PROPERTY(int graphicsCount READ graphicsCount WRITE setGraphicsCount)
Q_PROPERTY(QString graphicName READ graphicName WRITE setGraphicName)
Q_PROPERTY(QPen graphicPen READ graphicPen WRITE setGraphicPen)
Q_PROPERTY(QColor graphicColor READ graphicColor WRITE setGraphicColor)
Q_PROPERTY(Qt::PenStyle graphicStyle READ graphicStyle WRITE setGraphicStyle)
Q_PROPERTY(double graphicLineWidth READ graphicLineWidth WRITE setGraphicLineWidth)
Q_PROPERTY(double graphicPointWidth READ graphicPointWidth WRITE setGraphicPointWidth)
Q_PROPERTY(QColor graphicFillColor READ graphicFillColor WRITE setGraphicFillColor)
Q_PROPERTY(bool graphicLinesEnabled READ graphicLinesEnabled WRITE setGraphicLinesEnabled)
Q_PROPERTY(bool graphicPointsEnabled READ graphicPointsEnabled WRITE setGraphicPointsEnabled)
Q_PROPERTY(bool graphicFillEnabled READ graphicFillEnabled WRITE setGraphicFillEnabled)
Q_PROPERTY(bool gridEnabled READ gridEnabled WRITE setGridEnabled)
Q_PROPERTY(QPen gridPen READ gridPen WRITE setGridPen)
Q_PROPERTY(QColor gridColor READ gridColor WRITE setGridColor)
Q_PROPERTY(Qt::PenStyle gridStyle READ gridStyle WRITE setGridStyle)
Q_PROPERTY(QPen selectionPen READ selectionPen WRITE setSelectionPen)
Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)
Q_PROPERTY(Qt::PenStyle selectionStyle READ selectionStyle WRITE setSelectionStyle)
Q_PROPERTY(QBrush selectionBrush READ selectionBrush WRITE setSelectionBrush)
Q_PROPERTY(Alignment buttonsPosition READ buttonsPosition WRITE setButtonsPosition)
Q_PROPERTY(Buttons buttons READ buttons WRITE setButtons)
Q_PROPERTY(bool navigationEnabled READ navigationEnabled WRITE setNavigationEnabled)
Q_PROPERTY(bool openGL READ openGL WRITE setOpenGL)
Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing)
Q_PROPERTY(bool autoUpdate READ autoUpdate WRITE setAutoUpdate)
Q_PROPERTY(bool borderInputsVisible READ borderInputsVisible WRITE setBorderInputsVisible)
Q_PROPERTY(bool statusVisible READ statusVisible WRITE setStatusVisible)
Q_PROPERTY(bool legendVisible READ legendVisible WRITE setLegendVisible)
Q_PROPERTY(bool paused READ paused WRITE setPaused)
Q_PROPERTY(bool onlyExpandY READ onlyExpandY WRITE setOnlyExpandY)
Q_PROPERTY(bool onlyExpandX READ onlyExpandX WRITE setOnlyExpandX)
Q_PROPERTY(bool gesturesNavigation READ gesturesNavigation WRITE setGesturesNavigation)
Q_PROPERTY(double historySize READ historySize WRITE setHistorySize)
Q_PROPERTY(double maxVisibleTime READ maxVisibleTime WRITE setMaxVisibleTime)
Q_PROPERTY(double autoXIncrement READ autoXIncrement WRITE setAutoXIncrement)
Q_PROPERTY(QRectF limit READ limit WRITE setLimit)
Q_PROPERTY(QRect margins READ margins WRITE setMargins)
Q_PROPERTY(QRectF visualRect READ visualRect WRITE setVisualRect)
Q_PROPERTY(QRectF defaultRect READ defaultRect WRITE setDefaultRect)
Q_PROPERTY(int minimumRepaintInterval READ minimumRepaintInterval WRITE setMinimumRepaintInterval)
Q_PROPERTY(double gridNumbersMultiplierX READ gridNumbersMultiplierX WRITE setGridNumbersMultiplierX)
Q_PROPERTY(double gridNumbersMultiplierY READ gridNumbersMultiplierY WRITE setGridNumbersMultiplierY)
Q_PROPERTY(Graduation graduationX READ graduationX WRITE setGraduationX)
Q_PROPERTY(Graduation graduationY READ graduationY WRITE setGraduationY)
Q_PROPERTY(double graduationStepX READ graduationStepX WRITE setGraduationStepX)
Q_PROPERTY(double graduationStepY READ graduationStepY WRITE setGraduationStepY)
Q_PROPERTY(AxisType axisType READ axisType WRITE setAxisType)
Q_PROPERTY(Graphic::GraphicsData graphicsData READ graphicsData WRITE setGraphicsData)
Q_PROPERTY(QByteArray graphicsDataRaw READ graphicsDataRaw WRITE setGraphicsDataRaw)
public:
Graphic(QWidget * parent = 0);
virtual ~Graphic();
typedef QVector<QVector<QPointF> > GraphicsData;
enum GraphicAction {gaNone, gaZoomInRect, gaZoomRangeX, gaZoomRangeY, gaMove};
enum Button {NoButtons = 0x0,
AllButtons = 0xFFFFFFFF,
Autofit = 0x01,
Grid = 0x02,
CursorAxis = 0x04,
OnlyExpandY = 0x08,
OnlyExpandX = 0x10,
Fullscreen = 0x20,
BorderInputs = 0x40,
Legend = 0x80,
Configure = 0x100,
Save = 0x200,
Clear = 0x800,
Close = 0x1000,
Pause = 0x2000,
StandartButtons = 0x2FFF
};
enum Alignment {Left, Right};
enum Graduation {Auto, Fixed};
enum AxisType {Numeric, DateTime};
Q_DECLARE_FLAGS(Buttons, Button)
QString caption() const;
QString labelX() const {return label_x;}
QString labelY() const {return label_y;}
QString graphicName() const {return graphics[curGraphic].name;}
QColor backgroundColor() const {return back_color;}
QColor textColor() const {return text_color;}
QColor graphicColor() const {return graphics[curGraphic].pen.color();}
QColor gridColor() const {return grid_pen.color();}
QColor selectionColor() const {return selpen.color();}
Qt::PenStyle graphicStyle() const {return graphics[curGraphic].pen.style();}
Qt::PenStyle gridStyle() const {return grid_pen.style();}
Qt::PenStyle selectionStyle() const {return selpen.style();}
double graphicLineWidth() const {return graphics[curGraphic].pen.widthF();}
double graphicPointWidth() const {return graphics[curGraphic].pointWidth;}
QColor graphicFillColor() const {return graphics[curGraphic].fill_color;}
bool graphicVisible() const {return graphics[curGraphic].visible;}
bool graphicLinesEnabled() const {return graphics[curGraphic].lines;}
bool graphicPointsEnabled() const {return graphics[curGraphic].points;}
bool graphicFillEnabled() const {return graphics[curGraphic].fill;}
QPen graphicPen() const {return graphics[curGraphic].pen;}
QPen gridPen() const {return grid_pen;}
QPen selectionPen() const {return selpen;}
QBrush selectionBrush() const {return selbrush;}
bool navigationEnabled() const {return navigation;}
bool openGL() const {return isOGL;}
bool antialiasing() const {return aalias;}
bool autoUpdate() const {return aupdate;}
bool gridEnabled() const {return grid;}
bool borderInputsVisible() const;
bool statusVisible() const;
bool legendVisible() const;
bool paused() const {return pause_;}
bool onlyExpandY() const {return only_expand_y;}
bool onlyExpandX() const {return only_expand_x;}
bool gesturesNavigation() const {return gestures;}
bool isAutofitted() const {return isFit;}
int currentGraphic() const {return curGraphic;}
int graphicsCount() const {return graphics.size();}
Graphic::Buttons buttons() const {return buttons_;}
Graphic::Alignment buttonsPosition() const {return align;}
double historySize() const {return history;}
double maxVisibleTime() const {return visible_time;}
double autoXIncrement() const {return inc_x;}
QRectF visualRect() const {return selrect;}
QRectF defaultRect() const {return def_rect;}
QRectF limit() const {return limit_;}
QRect margins() const {return margins_;}
int minimumRepaintInterval() const {return min_repaint_int;}
double gridNumbersMultiplierX() const {return grid_numbers_x;}
double gridNumbersMultiplierY() const {return grid_numbers_y;}
Graduation graduationX() const {return grad_x;}
Graduation graduationY() const {return grad_y;}
double graduationStepX() const {return gridx;}
double graduationStepY() const {return gridy;}
AxisType axisType() const {return axis_type_x;}
QVector<QPointF> graphicData(const int index = 0) const {return graphics[index].polyline;}
GraphicsData graphicsData() const;
QByteArray graphicsDataRaw() const;
QWidget * viewport() const {return canvas;}
QByteArray save();
void load(QByteArray ba);
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];}
const QVector<GraphicType> & allGraphics() const {return graphics;}
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();}
double canvas2realX(double px) const;
double canvas2realY(double py) const;
double real2canvasX(double px) const;
double real2canvasY(double py) const;
QPointF canvas2real(QPointF canvas_point) const {return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y()));}
QPointF real2canvas(QPointF real_point) const {return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y()));}
QPolygonF real2canvas(const QPolygonF & real_polygon) const;
QPolygonF canvas2real(const QPolygonF & canvas_polygon) const;
double getScaleX() const {return real2canvasX(1.) - real2canvasX(0.);}
double getScaleY() const {return real2canvasY(1.) - real2canvasY(0.);}
QPointF getScale() const {return QPointF(getScaleX(), getScaleY());}
public slots:
void setCaption(const QString & str);
void setLabelX(const QString & str) {label_x = str; hasLblX = (str.length() > 0); if (aupdate) update();}
void setLabelY(const QString & str) {label_y = str; hasLblY = (str.length() > 0); if (aupdate) update();}
void setGraphicName(const QString & str, int index) {graphics[index].name = str; updateLegend(); if (aupdate) update();}
void setGraphicName(const QString & str) {graphics[curGraphic].name = str; updateLegend(); if (aupdate) update();}
void setBackgroundColor(const QColor & color) {back_color = color; if (aupdate) update(); updateLegend();}
void setTextColor(const QColor & color) {text_color = color; if (aupdate) update();}
void setGraphicColor(const QColor & color, int index) {graphics[index].pen.setColor(color); updateLegend(); if (aupdate) update();}
void setGraphicColor(const QColor & color) {setGraphicColor(color, curGraphic);}
void setGridColor(const QColor & color) {grid_pen.setColor(color); if (aupdate) update();}
void setSelectionColor(const QColor & color) {selpen.setColor(color);}
void setGraphicStyle(const Qt::PenStyle & style, int index) {graphics[index].pen.setStyle(style); updateLegend(); if (aupdate) update();}
void setGraphicStyle(const Qt::PenStyle & style) {setGraphicStyle(style, curGraphic);}
void setGridStyle(const Qt::PenStyle & style) {grid_pen.setStyle(style); if (aupdate) update();}
void setSelectionStyle(const Qt::PenStyle & style) {selpen.setStyle(style);}
void setGraphicVisible(bool visible, int index) {graphics[index].visible = visible; updateLegendChecks(); if (aupdate) update();}
void setGraphicVisible(bool visible) {setGraphicVisible(visible, curGraphic);}
void setGraphicLineWidth(double w, int index) {if (qRound(w) == w) graphics[index].pen.setWidth(qRound(w)); else graphics[index].pen.setWidthF(w); updateLegend(); if (aupdate) update();}
void setGraphicLineWidth(double w) {setGraphicLineWidth(w, curGraphic);}
void setGraphicPointWidth(double w, int index) {graphics[index].pointWidth = w; updateLegend(); if (aupdate) update();}
void setGraphicPointWidth(double w) {setGraphicPointWidth(w, curGraphic);}
void setGraphicFillColor(const QColor & w, int index) {graphics[index].fill_color = w; updateLegend(); if (aupdate) update();}
void setGraphicFillColor(const QColor & w) {setGraphicFillColor(w, curGraphic);}
void setGraphicLinesEnabled(bool w, int index) {graphics[index].lines = w; updateLegend(); if (aupdate) update();}
void setGraphicLinesEnabled(bool w) {setGraphicLinesEnabled(w, curGraphic);}
void setGraphicPointsEnabled(bool w, int index) {graphics[index].points = w; updateLegend(); if (aupdate) update();}
void setGraphicPointsEnabled(bool w) {setGraphicPointsEnabled(w, curGraphic);}
void setGraphicFillEnabled(bool w, int index) {graphics[index].fill = w; updateLegend(); if (aupdate) update();}
void setGraphicFillEnabled(bool w) {setGraphicFillEnabled(w, curGraphic);}
void setGraphicPen(const QPen & pen, int index) {graphics[index].pen = pen; updateLegend(); if (aupdate) update();}
void setGraphicPen(const QPen & pen) {setGraphicPen(pen, curGraphic);}
void setGridPen(const QPen & pen) {grid_pen = pen; if (aupdate) update();}
void setSelectionPen(const QPen & pen) {selpen = pen;}
void setSelectionBrush(const QBrush & brush) {selbrush = brush;}
void setNavigationEnabled(bool on) {navigation = on;}
void setOpenGL(bool on);
void setAntialiasing(bool enabled);
void setAutoUpdate(bool enabled) {aupdate = enabled;}
void setGridEnabled(bool enabled);
void setBorderInputsVisible(bool visible);
void setStatusVisible(bool visible);
void setLegendVisible(bool visible);
void setPaused(bool yes);
void setButtons(Graphic::Buttons b);
void setButtonsPosition(Graphic::Alignment a);
void setHistorySize(double val);
void setMaxVisibleTime(double val);
void setAutoXIncrement(double val) {inc_x = val;}
void setLimit(const QRectF & val) {limit_ = val;}
void setMargins(const QRect & val) {margins_ = val; update();}
void setMargins(int left_, int right_, int top_, int bottom_) {setMargins(QRect(left_, bottom_, right_, top_));}
void setLeftMargin(int value) {margins_.moveLeft(value); setMargins(margins_);}
void setRightMargin(int value) {margins_.setWidth(value); setMargins(margins_);}
void setTopMargin(int value) {margins_.setHeight(value); setMargins(margins_);}
void setBottomMargin(int value) {margins_.moveTop(value); setMargins(margins_);}
void setMinimumRepaintInterval(const int & val) {min_repaint_int = val;}
void setOnlyExpandY(bool yes);
void setOnlyExpandX(bool yes);
void setGesturesNavigation(bool yes);
void setGraphicsData(const GraphicsData & gd);
void setGraphicsDataRaw(const QByteArray & ba);
void setGridNumbersMultiplierX(double value) {grid_numbers_x = value; updateGraphics();}
void setGridNumbersMultiplierY(double value) {grid_numbers_y = value; updateGraphics();}
void setGraduationX(Graduation value) {grad_x = value; if (aupdate) update();;}
void setGraduationY(Graduation value) {grad_y = value; if (aupdate) update();;}
void setGraduationStepX(double sx) {gridx = sx; if (aupdate) update();}
void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();}
void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();}
void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();}
void addPoint(const QPointF & p, int graphic, bool update_ = true);
void addPoint(const QPointF & p, bool update = true) {addPoint(p, curGraphic, update);}
void addPoint(double x, double y, int graphic, bool update = true) {addPoint(QPointF(x, y), graphic, update);}
void addPoint(double x, double y, bool update = true) {addPoint(QPointF(x, y), update);}
void addPoint(double y, int graphic, bool update = true) {if (graphics[graphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), graphic, update); else addPoint(QPointF(graphics[graphic].max_x + inc_x, y), graphic, update);}
void addPoint(double y, bool update = true) {if (graphics[curGraphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), update); else addPoint(QPointF(graphics[curGraphic].max_x + inc_x, y), update);}
void setGraphicData(const QVector<QPointF> & g, int graphic, bool update_ = true);
void setGraphicData(const QVector<QPointF> & g) {setGraphicData(g, curGraphic);}
void setGraphicProperties(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true) {setGraphicProperties(curGraphic, name, color, style, width, visible);}
void setGraphicProperties(int graphic, const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
void addGraphic(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
void addGraphic(const GraphicType & gd, bool update = true) {graphics << gd; if (update) updateLegend();}
void setVisualRect(const QRectF & rect);
void setDefaultRect(const QRectF & rect);
void autofit() {on_buttonAutofit_clicked();}
void saveImage();
void clear();
void update(bool force = false);
void updateGraphics() {findGraphicsRect(); update();}
void setCurrentGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curGraphic = arg;}
void setGraphicsCount(int arg, bool update = true);
void removeGraphic(int arg, bool update = true);
void zoom(float factor);
void zoomIn() {zoom(1. / 1.2);}
void zoomOut() {zoom(1.2);}
void fullscreen();
protected:
virtual void changeEvent(QEvent * e);
virtual void resizeEvent(QResizeEvent * );
virtual QSize sizeHint() const {return QSize(400, 300);}
virtual void timerEvent(QTimerEvent * );
virtual bool eventFilter(QObject * o, QEvent * e);
void prepareCanvas(QWidget * w);
void procGesture(QGesture * g);
void procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km = Qt::NoModifier);
void totalUpdate();
void setCurrentAction(GraphicAction action);
void findGraphicsRect(double start_x = 0., double end_x = 0., double start_y = 0., double end_y = 0.);
void tick(int index, bool slide = true, bool update = true);
void repaintCanvas(bool force = false) {if (tm.elapsed() < min_repaint_int && !force) return; tm.restart(); canvas->update();}
void drawGraphics();
void drawGrid();
void drawGuides();
void drawPause();
void drawAction();
void updateLegend(bool es = true);
void updateLegendChecks();
void setCanvasCursor(QCursor cursor);
void swapToBuffer();
void swapToNormal() {bufferActive = false;}
void setRectToLines();
void checkLines();
double splitRange(double range, int count = 1);
double splitRangeDate(double range, int count = 1, QString * format = 0, int step[7] = 0);
double roundTo(double value, double round_to);
void roundDateTime(QDateTime & dt, int c[7]);
void addDateTime(QDateTime & dt, int c[7], int mul = 1);
QPointF absPoint(QPointF point) {return QPointF(qAbs(point.x()), qAbs(point.y()));}
QString pointCoords(QPointF point, bool x = true, bool y = true);
QPair<QString, QString> gridMark(double v) const;
Ui::Graphic * ui;
UGLWidget * canvas_gl;
QWidget * canvas;
QImage * buffer;
QPainter * painter;
QBrush selbrush;
QPen grid_pen, selpen;
QColor back_color, text_color;
QVector<GraphicType> graphics;
int curGraphic;
GraphicAction curaction, prevaction;
QRectF grect, selrect, limit_, def_rect;
QRect margins_;
QSize font_sz;
QPoint startpos, curpos, prevpos, gridborder;
QPointF startpos_r, curpos_r;
QString label_x, label_y, ppath, fp_size;
Graphic::Buttons buttons_;
Graphic::Alignment align;
GraphicConf * conf;
EvalSpinBox line_x_min, line_x_max, line_y_min, line_y_max;
QElapsedTimer tm;
#ifdef Q_OS_ANDROID
QElapsedTimer tm_fscr;
#endif
QIcon icon_exp_x, icon_exp_y, icon_exp_sx, icon_exp_sy;
QImage icon_pause_b, icon_pause_f;
Graduation grad_x, grad_y;
AxisType axis_type_x;
double gridx, gridy, history, visible_time, inc_x, grid_numbers_x, grid_numbers_y, LN10;
double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle;
int lastw, lasth, min_repaint_int, timer_pause, thick;
bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures;
bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan;
protected slots:
void canvasPaintEvent();
void canvasMouseMoveEvent(QMouseEvent * );
void canvasMousePressEvent(QMouseEvent * );
void canvasMouseReleaseEvent(QMouseEvent * );
void canvasMouseDoubleClickEvent(QMouseEvent * );
void canvasWheelEvent(QWheelEvent * );
void canvasLeaveEvent(QEvent * );
void canvasKeyPressEvent(QKeyEvent * );
void graphicVisibleChange(bool checked);
void graphicAllVisibleChange(bool checked);
void lineXMinChanged(double value) {selrect.setLeft(value); checkLines();}
void lineXMaxChanged(double value) {selrect.setRight(value); checkLines();}
void lineYMinChanged(double value) {selrect.setBottom(value); checkLines();}
void lineYMaxChanged(double value) {selrect.setTop(value); checkLines();}
void on_buttonClose_clicked() {emit closeRequest(this);}
void on_buttonClear_clicked() {clear(); emit cleared();}
void on_buttonAutofit_clicked();
void on_buttonConfigure_clicked();
void on_buttonFullscreen_clicked() {fullscreen();}
void on_buttonSave_clicked() {saveImage();}
void on_checkGrid_toggled(bool checked) {grid = checked; update();}
void on_checkGuides_toggled(bool checked);
void on_checkExpandY_toggled(bool checked);
void on_checkExpandX_toggled(bool checked);
void on_checkBorderInputs_toggled(bool checked) {setBorderInputsVisible(checked);}
void on_checkLegend_toggled(bool checked) {setLegendVisible(checked);}
void on_checkPause_toggled(bool checked) {setPaused(checked);}
void enterFullscreen();
void leaveFullscreen();
signals:
void beforeGraphicPaintEvent(QPainter * );
void graphicPaintEvent(QPainter * );
void graphicMouseMoveEvent(QPointF point, int buttons);
void graphicMousePressEvent(QPointF point, int buttons);
void graphicMouseReleaseEvent(QPointF point, int buttons);
void graphicWheelEvent(QPointF point, int delta);
void closeRequest(QWidget * );
void cleared();
void visualRectChanged();
void graphicSettingsChanged();
};
Q_DECLARE_METATYPE(Graphic::GraphicsData)
Q_DECLARE_OPERATORS_FOR_FLAGS(Graphic::Buttons)
inline QDataStream & operator <<(QDataStream & s, const Graphic::Graduation & v) {s << (int)v; return s;}
inline QDataStream & operator >>(QDataStream & s, Graphic::Graduation & v) {s >> *((int*)(&v)); return s;}
class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ {
public:
__GraphicRegistrator__() {
qRegisterMetaType<QVector<QPointF> >("QVector<QPointF>");
qRegisterMetaType<Graphic::GraphicsData>("Graphic::GraphicsData");
qRegisterMetaTypeStreamOperators<Graphic::GraphicsData>("Graphic::GraphicsData");
}
};
#endif // GRAPHIC_H

443
libs/graphic/graphic.ui Normal file
View File

@@ -0,0 +1,443 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Graphic</class>
<widget class="QFrame" name="Graphic">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>564</width>
<height>433</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>150</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0" rowspan="2">
<widget class="QWidget" name="widgetLeft" native="true">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>-10</x>
<y>0</y>
<width>33</width>
<height>420</height>
</rect>
</property>
<layout class="QVBoxLayout" name="layoutButtons">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QToolButton" name="buttonAutofit">
<property name="toolTip">
<string>Autofit</string>
</property>
<property name="icon">
<iconset resource="qad_graphic.qrc">
<normaloff>:/icons/view-autofit.png</normaloff>:/icons/view-autofit.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkGrid">
<property name="toolTip">
<string>Grid</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/view-grid.png</normaloff>:/icons/view-grid.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkGuides">
<property name="toolTip">
<string>Cursor axis</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/edit-guides.png</normaloff>:/icons/edit-guides.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkExpandY">
<property name="toolTip">
<string>Only expand Y</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/expand_s_y.png</normaloff>:/icons/expand_s_y.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkExpandX">
<property name="toolTip">
<string>Only expand X</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/expand_s_x.png</normaloff>:/icons/expand_s_x.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonFullscreen">
<property name="toolTip">
<string>Fullscreen</string>
</property>
<property name="icon">
<iconset resource="../blockview/qad_blockview.qrc">
<normaloff>:/icons/view-fullscreen.png</normaloff>:/icons/view-fullscreen.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkBorderInputs">
<property name="toolTip">
<string>Border inputs</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/border-line.png</normaloff>:/icons/border-line.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkLegend">
<property name="toolTip">
<string>Legend</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="checkPause">
<property name="toolTip">
<string>Pause</string>
</property>
<property name="icon">
<iconset resource="qad_graphic.qrc">
<normaloff>:/icons/media-playback-pause.png</normaloff>:/icons/media-playback-pause.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonConfigure">
<property name="toolTip">
<string>Configure ...</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/configure.png</normaloff>:/icons/configure.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonSave">
<property name="toolTip">
<string>Save image ...</string>
</property>
<property name="icon">
<iconset resource="../utils/qad_utils.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="buttonClear">
<property name="toolTip">
<string>Clear</string>
</property>
<property name="icon">
<iconset resource="../utils/qad_utils.qrc">
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonClose">
<property name="toolTip">
<string>Close</string>
</property>
<property name="icon">
<iconset resource="../widgets/qad_widgets.qrc">
<normaloff>:/icons/dialog-close.png</normaloff>:/icons/dialog-close.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>79</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelCaption">
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QWidget" name="widgetRight" native="true"/>
</item>
<item row="1" column="1">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="1" colspan="2">
<widget class="QWidget" name="widgetLX" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2" colspan="2">
<layout class="QVBoxLayout" name="layoutCanvas">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="UWidget" name="canvas_raster" native="true">
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QWidget" name="widgetLY" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="status">
<property name="text">
<string>Cursor: ( ; )</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QWidget" name="widgetLegend" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<layout class="QGridLayout" name="layoutLegend">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<property name="horizontalSpacing">
<number>4</number>
</property>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>UWidget</class>
<extends>QWidget</extends>
<header>uwidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../utils/qad_utils.qrc"/>
<include location="../widgets/qad_widgets.qrc"/>
<include location="../blockview/qad_blockview.qrc"/>
<include location="qad_graphic.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,107 @@
#include "graphic_conf.h"
#include "qad_types.h"
#include "ui_graphic_conf.h"
GraphicConf::GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent): QDialog(parent), graphics(graphics_) {
ui = new Ui::GraphicConf();
ui->setupUi(this);
QStringList styles;
int fh = qMax<int>(fontMetrics().size(0, "0").height(), 22);
int thick = lineThickness();
QSize sz(fh * 2.5, fh);
styles << tr("NoPen") << tr("Solid") << tr("Dash")
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
ui->comboStyleGrid->setIconSize(sz);
ui->comboStyleGraphic->setIconSize(sz);
ui->cbGraphicNames->setIconSize(sz);
for (int i = 0; i < 6; i++) {
QPixmap pix(sz);
pix.fill();
QPainter p(&pix);
p.setPen(QPen(Qt::black, thick, (Qt::PenStyle)i));
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
p.end();
ui->comboStyleGraphic->addItem(QIcon(pix), styles[i]);
ui->comboStyleGrid->addItem(QIcon(pix), styles[i]);
}
}
void GraphicConf::changeEvent(QEvent * e) {
QDialog::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
return;
}
}
void GraphicConf::readParams() {
ui->cbGraphicNames->clear();
for (int i = 0; i < graphicItems.size(); i++)
ui->cbGraphicNames->addItem(graphicItems[i].icon, graphicItems[i].name);
}
void GraphicConf::on_cbGraphicNames_currentIndexChanged(int i) {
if (i < 0) return;
if (graphicItems.isEmpty()) return;
ui->comboStyleGraphic->setCurrentIndex((int)graphics[i].pen.style());
ui->colorGraphic->setColor(graphics[i].pen.color());
ui->colorFill->setColor(graphics[i].fill_color);
ui->spinLineWidthGraphic->setValue(graphics[i].pen.widthF());
ui->spinPointWidthGraphic->setValue(graphics[i].pointWidth);
ui->checkLines->setChecked(graphics[i].lines);
ui->checkPoints->setChecked(graphics[i].points);
ui->checkFill->setChecked(graphics[i].fill);
}
void GraphicConf::on_colorGraphic_colorChanged(const QColor & c) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].pen.setColor(c);
}
void GraphicConf::on_comboStyleGraphic_currentIndexChanged(int index) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].pen.setStyle((Qt::PenStyle)index);
}
void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) {
if (graphicItems.isEmpty()) return;
if (qRound(value) == value) graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value));
else graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value);
}
void GraphicConf::on_spinPointWidthGraphic_valueChanged(double value) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].pointWidth = value;
}
void GraphicConf::on_checkLines_toggled(bool on) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].lines = on;
}
void GraphicConf::on_checkPoints_toggled(bool on) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].points = on;
}
void GraphicConf::on_checkFill_toggled(bool on) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].fill = on;
}
void GraphicConf::on_colorFill_colorChanged(const QColor & color) {
if (graphicItems.isEmpty()) return;
graphics[ui->cbGraphicNames->currentIndex()].fill_color = color;
}

111
libs/graphic/graphic_conf.h Normal file
View File

@@ -0,0 +1,111 @@
/*
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRAPHIC_CONF_H
#define GRAPHIC_CONF_H
#include <QDialog>
#include <QCheckBox>
#include <QPen>
#include <QPainter>
#include "qad_graphic_export.h"
namespace Ui {
class GraphicConf;
}
struct QAD_GRAPHIC_EXPORT GraphicType {
GraphicType(QString name_ = "y(x)", QColor color = Qt::red, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible_ = true) {
pen.setColor(color);
pen.setStyle(style);
lines = true;
points = false;
fill = false;
fill_color = Qt::yellow;
if (qRound(width) == width) pen.setWidth(qRound(width));
else pen.setWidthF(width);
pen.setWidth(1);
pen.setCosmetic(true);
max_x = 0.;
name = name_;
visible = visible_;
pointWidth = 2.;
pb = new QCheckBox(name);
}
//~GraphicType() {delete pb;}
QString name;
QPolygonF polyline;
QPolygonF polyline_pause;
QPen pen;
QColor fill_color;
bool lines;
bool points;
bool fill;
double pointWidth;
double max_x;
double max_x_pause;
QCheckBox * pb;
QIcon icon;
bool visible;
QRectF cvrect;
};
inline QDataStream & operator <<(QDataStream & s, const GraphicType & v) {s << v.name << v.pen << v.fill_color << v.lines << v.points << v.fill << v.pointWidth << v.visible; return s;}
inline QDataStream & operator >>(QDataStream & s, GraphicType & v) {s >> v.name >> v.pen >> v.fill_color >> v.lines >> v.points >> v.fill >> v.pointWidth >> v.visible; return s;}
class QAD_GRAPHIC_EXPORT GraphicConf: public QDialog
{
Q_OBJECT
friend class Graphic;
public:
explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0);
struct QAD_GRAPHIC_EXPORT GraphicItem {
QString name;
QIcon icon;
};
void readParams();
QVector<GraphicType> & graphics;
QVector<GraphicItem> graphicItems;
protected:
void changeEvent(QEvent * e);
Ui::GraphicConf * ui;
private slots:
void on_cbGraphicNames_currentIndexChanged(int index);
void on_colorGraphic_colorChanged(const QColor &);
void on_colorFill_colorChanged(const QColor &);
void on_comboStyleGraphic_currentIndexChanged(int index);
void on_spinLineWidthGraphic_valueChanged(double value);
void on_spinPointWidthGraphic_valueChanged(double value);
void on_checkLines_toggled(bool on);
void on_checkPoints_toggled(bool on);
void on_checkFill_toggled(bool on);
};
#endif // GRAPHIC_CONF_H

View File

@@ -0,0 +1,644 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GraphicConf</class>
<widget class="QDialog" name="GraphicConf">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>583</height>
</rect>
</property>
<property name="windowTitle">
<string>Graphic parameters</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Appearance</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QCheckBox" name="checkInputs">
<property name="text">
<string>Border inputs</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkAAlias">
<property name="text">
<string>Antialiasing</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkStatus">
<property name="text">
<string>Status bar</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkOGL">
<property name="text">
<string>OpenGL</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="checkLegend">
<property name="text">
<string>Legend</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QFormLayout" name="formLayout_3">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Background color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorBackground">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Text color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="ColorButton" name="colorText">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<widget class="QGroupBox" name="groupBox_1">
<property name="title">
<string>Graphics</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0" colspan="2">
<widget class="QComboBox" name="cbGraphicNames">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="ColorButton" name="colorGraphic">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Style:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboStyleGraphic"/>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkLines">
<property name="text">
<string>Lines width:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="spinLineWidthGraphic">
<property name="decimals">
<number>2</number>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkPoints">
<property name="text">
<string>Points width:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="spinPointWidthGraphic">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>999.990000000000009</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="checkFill">
<property name="text">
<string>Fill:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="ColorButton" name="colorFill">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Grid</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorGrid">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Style:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboStyleGrid"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Width:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinWidthGrid">
<property name="decimals">
<number>2</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Step X:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Step Y:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkGridAutoX">
<property name="text">
<string>Auto X</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="checkGridAutoY">
<property name="text">
<string>Auto Y</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="EvalSpinBox" name="spinGridStepY">
<property name="expression">
<string>30</string>
</property>
<property name="defaultText">
<string>30</string>
</property>
<property name="clearButtonVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="EvalSpinBox" name="spinGridStepX">
<property name="expression">
<string>50</string>
</property>
<property name="defaultText">
<string>50</string>
</property>
<property name="clearButtonVisible">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Margins</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="5">
<widget class="QSpinBox" name="spinMarginR">
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="spinMarginB">
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelAll">
<property name="text">
<string>All:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinMarginL">
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Right:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Left:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Bottom:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="spinMarginT">
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Top:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="spinMarginT_2">
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ColorButton</class>
<extends>QPushButton</extends>
<header>colorbutton.h</header>
<slots>
<signal>colorChanged(QColor)</signal>
</slots>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>checkAAlias</tabstop>
<tabstop>checkOGL</tabstop>
<tabstop>colorBackground</tabstop>
<tabstop>colorText</tabstop>
<tabstop>colorGrid</tabstop>
<tabstop>comboStyleGrid</tabstop>
<tabstop>spinWidthGrid</tabstop>
<tabstop>cbGraphicNames</tabstop>
<tabstop>colorGraphic</tabstop>
<tabstop>comboStyleGraphic</tabstop>
<tabstop>checkLines</tabstop>
<tabstop>spinLineWidthGraphic</tabstop>
<tabstop>checkPoints</tabstop>
<tabstop>spinPointWidthGraphic</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GraphicConf</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>255</x>
<y>641</y>
</hint>
<hint type="destinationlabel">
<x>245</x>
<y>207</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkLines</sender>
<signal>toggled(bool)</signal>
<receiver>spinLineWidthGraphic</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>322</x>
<y>410</y>
</hint>
<hint type="destinationlabel">
<x>415</x>
<y>411</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkPoints</sender>
<signal>toggled(bool)</signal>
<receiver>spinPointWidthGraphic</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>322</x>
<y>434</y>
</hint>
<hint type="destinationlabel">
<x>415</x>
<y>435</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GraphicConf</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>294</x>
<y>641</y>
</hint>
<hint type="destinationlabel">
<x>288</x>
<y>268</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkFill</sender>
<signal>toggled(bool)</signal>
<receiver>colorFill</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>322</x>
<y>458</y>
</hint>
<hint type="destinationlabel">
<x>415</x>
<y>460</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinMarginT_2</sender>
<signal>valueChanged(int)</signal>
<receiver>spinMarginT</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>259</x>
<y>221</y>
</hint>
<hint type="destinationlabel">
<x>249</x>
<y>191</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinMarginT_2</sender>
<signal>valueChanged(int)</signal>
<receiver>spinMarginR</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>268</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>371</x>
<y>220</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinMarginT_2</sender>
<signal>valueChanged(int)</signal>
<receiver>spinMarginB</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>233</x>
<y>230</y>
</hint>
<hint type="destinationlabel">
<x>234</x>
<y>252</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinMarginT_2</sender>
<signal>valueChanged(int)</signal>
<receiver>spinMarginL</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>213</x>
<y>230</y>
</hint>
<hint type="destinationlabel">
<x>133</x>
<y>229</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,387 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>Graphic</name>
<message>
<location filename="../graphic.ui" line="53"/>
<source>Autofit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="64"/>
<source>Grid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="81"/>
<source>Cursor axis</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="95"/>
<source>Only expand Y</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="109"/>
<source>Only expand X</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="123"/>
<source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="134"/>
<source>Border inputs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="151"/>
<source>Legend</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="168"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="182"/>
<source>Configure ...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="193"/>
<source>Save image ...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="220"/>
<source>Clear</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="231"/>
<source>Close</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.ui" line="396"/>
<source>Cursor: ( ; )</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="387"/>
<location filename="../graphic.cpp" line="1231"/>
<source>Cursor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="402"/>
<source>Selection</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="403"/>
<source>Size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="407"/>
<location filename="../graphic.cpp" line="413"/>
<source>Range</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="408"/>
<location filename="../graphic.cpp" line="414"/>
<source>Length</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="525"/>
<location filename="../graphic.cpp" line="566"/>
<source>Cursor</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="814"/>
<source>Save Image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="865"/>
<source>y(x)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic.cpp" line="1678"/>
<source>Check all</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>GraphicConf</name>
<message>
<location filename="../graphic_conf.ui" line="17"/>
<source>Graphic parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="26"/>
<source>Appearance</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="34"/>
<source>Border inputs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="41"/>
<source>Antialiasing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="48"/>
<source>Status bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="55"/>
<source>OpenGL</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="62"/>
<source>Legend</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="82"/>
<source>Background color:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="102"/>
<source>Text color:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="121"/>
<source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="140"/>
<location filename="../graphic_conf.ui" line="236"/>
<source>Color:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="154"/>
<location filename="../graphic_conf.ui" line="250"/>
<source>Style:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="164"/>
<source>Lines width:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="184"/>
<source>Points width:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="207"/>
<source>Fill:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="227"/>
<source>Grid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="260"/>
<source>Width:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="274"/>
<source>Step X:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="281"/>
<source>Step Y:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="288"/>
<source>Auto X</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="298"/>
<source>Auto Y</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="308"/>
<location filename="../graphic_conf.ui" line="311"/>
<source>30</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="321"/>
<location filename="../graphic_conf.ui" line="324"/>
<source>50</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="357"/>
<source>Margins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="363"/>
<location filename="../graphic_conf.ui" line="373"/>
<location filename="../graphic_conf.ui" line="393"/>
<location filename="../graphic_conf.ui" line="433"/>
<location filename="../graphic_conf.ui" line="453"/>
<source> px</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="383"/>
<source>All:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="403"/>
<source>Right:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="413"/>
<source>Left:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="423"/>
<source>Bottom:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="443"/>
<source>Top:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="13"/>
<source>NoPen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="13"/>
<source>Solid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="13"/>
<source>Dash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="14"/>
<source>Dot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="14"/>
<source>Dash-Dot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="14"/>
<source>Dash-Dot-Dot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="14"/>
<source>QPICalculator</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="29"/>
<source>Calculator</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="60"/>
<source>Expression</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="65"/>
<source>Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="76"/>
<source>Correct</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="83"/>
<location filename="../qpicalculator/mainwindow.ui" line="100"/>
<source>0</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="111"/>
<source>Variables</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="139"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="144"/>
<source>Value</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="169"/>
<location filename="../qpicalculator/mainwindow.ui" line="290"/>
<source>Del</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="219"/>
<source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="260"/>
<source>On</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="265"/>
<source>Function</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@@ -0,0 +1,391 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ru_RU">
<context>
<name>Graphic</name>
<message>
<location filename="../graphic.ui" line="53"/>
<source>Autofit</source>
<translation>Автомасштаб</translation>
</message>
<message>
<location filename="../graphic.ui" line="64"/>
<source>Grid</source>
<translation>Сетка</translation>
</message>
<message>
<location filename="../graphic.ui" line="81"/>
<source>Cursor axis</source>
<translation>Плавающие оси</translation>
</message>
<message>
<location filename="../graphic.ui" line="95"/>
<source>Only expand Y</source>
<translation>Только расширять Y</translation>
</message>
<message>
<location filename="../graphic.ui" line="109"/>
<source>Only expand X</source>
<translation>Только расширять X</translation>
</message>
<message>
<location filename="../graphic.ui" line="123"/>
<source>Fullscreen</source>
<translation>Во весь экран</translation>
</message>
<message>
<location filename="../graphic.ui" line="134"/>
<source>Border inputs</source>
<translation>Граничные поля ввода</translation>
</message>
<message>
<location filename="../graphic.ui" line="151"/>
<source>Legend</source>
<translation>Легенда</translation>
</message>
<message>
<location filename="../graphic.ui" line="168"/>
<source>Pause</source>
<translation>Пауза</translation>
</message>
<message>
<location filename="../graphic.ui" line="182"/>
<source>Configure ...</source>
<translation>Настроить ...</translation>
</message>
<message>
<location filename="../graphic.ui" line="193"/>
<source>Save image ...</source>
<translation>Сохранить изображение ...</translation>
</message>
<message>
<location filename="../graphic.ui" line="220"/>
<source>Clear</source>
<translation>Очистить</translation>
</message>
<message>
<location filename="../graphic.ui" line="231"/>
<source>Close</source>
<translation>Закрыть</translation>
</message>
<message>
<location filename="../graphic.ui" line="396"/>
<source>Cursor: ( ; )</source>
<translation>Курсор: ( ; )</translation>
</message>
<message>
<location filename="../graphic.cpp" line="387"/>
<location filename="../graphic.cpp" line="1231"/>
<source>Cursor: </source>
<translation>Курсор: </translation>
</message>
<message>
<location filename="../graphic.cpp" line="402"/>
<source>Selection</source>
<translation>Выделение</translation>
</message>
<message>
<location filename="../graphic.cpp" line="403"/>
<source>Size</source>
<translation>Размер</translation>
</message>
<message>
<location filename="../graphic.cpp" line="407"/>
<location filename="../graphic.cpp" line="413"/>
<source>Range</source>
<translation>Диапазон</translation>
</message>
<message>
<location filename="../graphic.cpp" line="408"/>
<location filename="../graphic.cpp" line="414"/>
<source>Length</source>
<translation>Длина</translation>
</message>
<message>
<location filename="../graphic.cpp" line="525"/>
<location filename="../graphic.cpp" line="566"/>
<source>Cursor</source>
<translation>Курсор</translation>
</message>
<message>
<location filename="../graphic.cpp" line="814"/>
<source>Save Image</source>
<translation>Сохранить изображение</translation>
</message>
<message>
<location filename="../graphic.cpp" line="865"/>
<source>y(x)</source>
<translation></translation>
</message>
<message>
<location filename="../graphic.cpp" line="1678"/>
<source>Check all</source>
<translation>Выбрать все</translation>
</message>
</context>
<context>
<name>GraphicConf</name>
<message>
<location filename="../graphic_conf.ui" line="17"/>
<source>Graphic parameters</source>
<translation>Параметры графика</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="26"/>
<source>Appearance</source>
<translation>Внешний вид</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="34"/>
<source>Border inputs</source>
<translation>Граничные поля ввода</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="41"/>
<source>Antialiasing</source>
<translation>Сглаживание</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="48"/>
<source>Status bar</source>
<translation>Панель статуса</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="55"/>
<source>OpenGL</source>
<translation></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="62"/>
<source>Legend</source>
<translation>Легенда</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="82"/>
<source>Background color:</source>
<translation>Цвет фона:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="102"/>
<source>Text color:</source>
<translation>Цвет текста:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="121"/>
<source>Graphics</source>
<translation>Графики</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="140"/>
<location filename="../graphic_conf.ui" line="236"/>
<source>Color:</source>
<translation>Цвет:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="154"/>
<location filename="../graphic_conf.ui" line="250"/>
<source>Style:</source>
<translation>Стиль:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="164"/>
<source>Lines width:</source>
<translation>Толщина линий:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="184"/>
<source>Points width:</source>
<translation>Толщина точек:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="207"/>
<source>Fill:</source>
<translation>Заливка:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="227"/>
<source>Grid</source>
<translation>Сетка</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="260"/>
<source>Width:</source>
<translation>Толщина:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="274"/>
<source>Step X:</source>
<translation>Шаг X:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="281"/>
<source>Step Y:</source>
<translation>Шаг Y:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="288"/>
<source>Auto X</source>
<translation>Авто X</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="298"/>
<source>Auto Y</source>
<translation>Авто Y</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="308"/>
<location filename="../graphic_conf.ui" line="311"/>
<source>30</source>
<translation></translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="321"/>
<location filename="../graphic_conf.ui" line="324"/>
<source>50</source>
<translation></translation>
</message>
<message>
<source>Auto step</source>
<translation type="obsolete">Автоматический шаг</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="357"/>
<source>Margins</source>
<translation>Поля</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="363"/>
<location filename="../graphic_conf.ui" line="373"/>
<location filename="../graphic_conf.ui" line="393"/>
<location filename="../graphic_conf.ui" line="433"/>
<location filename="../graphic_conf.ui" line="453"/>
<source> px</source>
<translation> пикс</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="383"/>
<source>All:</source>
<translation>Все:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="403"/>
<source>Right:</source>
<translation>Правое:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="413"/>
<source>Left:</source>
<translation>Левое:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="423"/>
<source>Bottom:</source>
<translation>Нижнее:</translation>
</message>
<message>
<location filename="../graphic_conf.ui" line="443"/>
<source>Top:</source>
<translation>Верхнее:</translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="13"/>
<source>NoPen</source>
<translation>НетЛинии</translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="13"/>
<source>Solid</source>
<translation>Сплошная</translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="13"/>
<source>Dash</source>
<translation>Штриховая</translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="14"/>
<source>Dot</source>
<translation>Пунктирная</translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="14"/>
<source>Dash-Dot</source>
<translation>ШтрихПунктирная</translation>
</message>
<message>
<location filename="../graphic_conf.cpp" line="14"/>
<source>Dash-Dot-Dot</source>
<translation>ШтрихПунктирПунктирная</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="14"/>
<source>QPICalculator</source>
<translation>Калькулятор</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="29"/>
<source>Calculator</source>
<translation>Калькулятор</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="60"/>
<source>Expression</source>
<translation>Выражение</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="65"/>
<source>Result</source>
<translation>Результат</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="76"/>
<source>Correct</source>
<translation>Корректно</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="83"/>
<location filename="../qpicalculator/mainwindow.ui" line="100"/>
<source>0</source>
<translation></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="111"/>
<source>Variables</source>
<translation>Переменные</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="139"/>
<source>Name</source>
<translation>Имя</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="144"/>
<source>Value</source>
<translation>Значение</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="169"/>
<location filename="../qpicalculator/mainwindow.ui" line="290"/>
<source>Del</source>
<translation></translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="219"/>
<source>Graphics</source>
<translation>Графики</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="260"/>
<source>On</source>
<translation>Вкл</translation>
</message>
<message>
<location filename="../qpicalculator/mainwindow.ui" line="265"/>
<source>Function</source>
<translation>Функция</translation>
</message>
</context>
</TS>

View File

@@ -0,0 +1,2 @@
lupdate ../ -ts qad_graphic_ru.ts
lupdate ../ -ts qad_graphic_en.ts

View File

@@ -0,0 +1 @@
qad_plugin(graphic "Gui;Widgets;OpenGL" "")

View File

@@ -0,0 +1,69 @@
#include "graphic.h"
#include "graphicplugin.h"
#include <QtCore/QtPlugin>
GraphicPlugin::GraphicPlugin(QObject * parent): QObject(parent) {
m_initialized = false;
}
void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized)
return;
// Add extension registrations, etc. here
m_initialized = true;
}
bool GraphicPlugin::isInitialized() const {
return m_initialized;
}
QWidget * GraphicPlugin::createWidget(QWidget * parent) {
return new Graphic(parent);
}
QString GraphicPlugin::name() const {
return QLatin1String("Graphic");
}
QString GraphicPlugin::group() const {
return QLatin1String("Display Widgets");
}
QIcon GraphicPlugin::icon() const {
return QIcon(":/icons/graphic.png");
}
QString GraphicPlugin::toolTip() const {
return QLatin1String("");//QLatin1String("Widget for display any math graphics with grid and navigation");
}
QString GraphicPlugin::whatsThis() const {
return QLatin1String("");
}
bool GraphicPlugin::isContainer() const {
return false;
}
QString GraphicPlugin::domXml() const {
return QLatin1String("<widget class=\"Graphic\" name=\"graphic\">\n</widget>\n");
}
QString GraphicPlugin::includeFile() const {
return QLatin1String("graphic.h");
}

View File

@@ -0,0 +1,36 @@
#ifndef GRAPHICPLUGIN_H
#define GRAPHICPLUGIN_H
#include <QObject>
#if QT_VERSION >= 0x050000
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
#else
# include <QDesignerCustomWidgetInterface>
#endif
class GraphicPlugin: public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
GraphicPlugin(QObject * parent = 0);
bool isContainer() const;
bool isInitialized() const;
QIcon icon() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget * createWidget(QWidget * parent);
void initialize(QDesignerFormEditorInterface * core);
private:
bool m_initialized;
};
#endif

View File

@@ -0,0 +1,17 @@
#include "qad_graphic.h"
#include "graphicplugin.h"
QADGraphic::QADGraphic(QObject * parent): QObject(parent)
{
m_widgets.append(new GraphicPlugin(this));
}
QList<QDesignerCustomWidgetInterface * > QADGraphic::customWidgets() const {
return m_widgets;
}
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(qad_graphic_plugin, QADGraphic)
#endif

View File

@@ -0,0 +1,23 @@
#ifndef QAD_GRAPHIC_H
#define QAD_GRAPHIC_H
#include <QtDesigner/QtDesigner>
#include <QtCore/qplugin.h>
class QADGraphic: public QObject, public QDesignerCustomWidgetCollectionInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "qad.graphic")
#endif
public:
explicit QADGraphic(QObject * parent = 0);
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
private:
QList<QDesignerCustomWidgetInterface * > m_widgets;
};
#endif // QAD_GRAPHIC_H

View File

@@ -0,0 +1,28 @@
<RCC>
<qresource prefix="/">
<file>../../icons/media-playback-pause.png</file>
<file>../../icons/dialog-close.png</file>
<file>../../icons/edit-clear.png</file>
<file>../../icons/edit-guides.png</file>
<file>../../icons/view-grid.png</file>
<file>../../icons/view-autofit.png</file>
<file>../../icons/configure.png</file>
<file>../../icons/document-save.png</file>
<file>../../icons/edit-clear-locationbar-rtl.png</file>
<file>../../icons/edit-find.png</file>
<file>../../icons/list-add.png</file>
<file>../../icons/edit-delete.png</file>
<file>../../icons/edit-copy.png</file>
<file>../../icons/edit-paste.png</file>
<file>../../icons/expand_s_x.png</file>
<file>../../icons/expand_s_y.png</file>
<file>../../icons/expand_x.png</file>
<file>../../icons/expand_y.png</file>
<file>../../icons/border-line.png</file>
<file>../../icons/legend.png</file>
<file>../../icons/graphic.png</file>
<file>../../icons/view-fullscreen.png</file>
<file>../../icons/pause-back.png</file>
<file>../../icons/pause-front.png</file>
</qresource>
</RCC>

69
libs/graphic/uglwidget.h Normal file
View File

@@ -0,0 +1,69 @@
#ifndef UGLWIDGET_H
#define UGLWIDGET_H
#include <QWidget>
#include <QDebug>
#if QT_VERSION >= 0x050400
# include <QOpenGLWidget>
typedef QOpenGLWidget __GLWidget__;
#else
# include <QGLWidget>
typedef QGLWidget __GLWidget__;
# ifndef GL_MULTISAMPLE
# define GL_MULTISAMPLE 0x809D
# endif
#endif
#include "qad_graphic_export.h"
class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__
{
Q_OBJECT
public:
#if QT_VERSION >= 0x050400
UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {QSurfaceFormat sf = format(); sf.setSamples(8); setFormat(sf);}
#else
UGLWidget(QWidget * parent = 0): __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {}
#endif
//UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {}
#if QT_VERSION >= 0x050400
QImage grabFrameBuffer() {return grabFramebuffer();}
#endif
protected:
#if QT_VERSION >= 0x050400
virtual void paintGL() {emit paintSignal();}
#else
virtual void paintEvent(QPaintEvent * ) {emit paintSignal();}
#endif
virtual void resizeEvent(QResizeEvent * e) {
__GLWidget__::resizeEvent(e);
emit resizeSignal();
}
signals:
void closeEvent(QCloseEvent * e);
void dragEnterEvent(QDragEnterEvent * e);
void dragLeaveEvent(QDragLeaveEvent * e);
void dragMoveEvent(QDragMoveEvent * e);
void dropEvent(QDropEvent * e);
void enterEvent(QEvent * e);
void hideEvent(QHideEvent * e);
void keyPressEvent(QKeyEvent * e);
void keyReleaseEvent(QKeyEvent * e);
void leaveEvent(QEvent * e);
void mouseDoubleClickEvent(QMouseEvent * e);
void mouseMoveEvent(QMouseEvent * e);
void mousePressEvent(QMouseEvent * e);
void mouseReleaseEvent(QMouseEvent * e);
void moveEvent(QMoveEvent * e);
void showEvent(QShowEvent * e);
void wheelEvent(QWheelEvent * e);
void resizeSignal();
void paintSignal();
};
#endif

53
libs/graphic/uwidget.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef UWIDGET_H
#define UWIDGET_H
#include <QWidget>
#include <QPainter>
#include <QStyle>
#include <QStyleOption>
#include <QEvent>
#include "qad_graphic_export.h"
class QAD_GRAPHIC_EXPORT UWidget: public QWidget
{
Q_OBJECT
public:
UWidget(QWidget * parent = 0): QWidget(parent) {}
private:
virtual bool event(QEvent * e) {
if (e->type() != QEvent::Paint) return QWidget::event(e);
e->accept();
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
emit paintEvent((QPaintEvent * )e);
return true;
}
signals:
void closeEvent(QCloseEvent * e);
void dragEnterEvent(QDragEnterEvent * e);
void dragLeaveEvent(QDragLeaveEvent * e);
void dragMoveEvent(QDragMoveEvent * e);
void dropEvent(QDropEvent * e);
void enterEvent(QEvent * e);
void hideEvent(QHideEvent * e);
void keyPressEvent(QKeyEvent * e);
void keyReleaseEvent(QKeyEvent * e);
void leaveEvent(QEvent * e);
void mouseDoubleClickEvent(QMouseEvent * e);
void mouseMoveEvent(QMouseEvent * e);
void mousePressEvent(QMouseEvent * e);
void mouseReleaseEvent(QMouseEvent * e);
void moveEvent(QMoveEvent * e);
void resizeEvent(QResizeEvent * e);
void showEvent(QShowEvent * e);
void wheelEvent(QWheelEvent * e);
void paintEvent(QPaintEvent * e);
};
#endif