code format

This commit is contained in:
2022-12-14 14:14:33 +03:00
parent 09e5342956
commit cdb02fc9be
278 changed files with 15371 additions and 12176 deletions
+25 -29
View File
@@ -1,7 +1,9 @@
#include "aboutwindow.h" #include "aboutwindow.h"
#include "ui_aboutwindow.h"
#include "qad_types.h" #include "qad_types.h"
#include "qpiconfig.h" #include "qpiconfig.h"
#include "ui_aboutwindow.h"
#include <QApplication> #include <QApplication>
#include <QFile> #include <QFile>
#if QT_VERSION < 0x050000 #if QT_VERSION < 0x050000
@@ -23,44 +25,41 @@ AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWin
#ifdef ANDROID #ifdef ANDROID
QDialog::setStyleSheet("font: 12pt \"DejaVu Sans\";"); QDialog::setStyleSheet("font: 12pt \"DejaVu Sans\";");
#endif #endif
if (!stylesheet.isEmpty()) if (!stylesheet.isEmpty()) QDialog::setStyleSheet(stylesheet);
QDialog::setStyleSheet(stylesheet);
ui->setupUi(this); ui->setupUi(this);
ui->labelAuthors->setOpenExternalLinks(true); ui->labelAuthors->setOpenExternalLinks(true);
QImage logo_im = logo; QImage logo_im = logo;
if (logo_im.isNull()) if (logo_im.isNull()) logo_im.load(":/icons/splash.png");
logo_im.load(":/icons/splash.png");
setWindowTitle(QApplication::applicationName() + " - " + tr("About")); setWindowTitle(QApplication::applicationName() + " - " + tr("About"));
QIcon ic = QApplication::windowIcon(); QIcon ic = QApplication::windowIcon();
if (ic.isNull()) { if (ic.isNull()) {
QWidgetList tlw = QApplication::topLevelWidgets(); QWidgetList tlw = QApplication::topLevelWidgets();
foreach (QWidget * w, tlw) foreach(QWidget * w, tlw)
if (!w->windowIcon().isNull()) { if (!w->windowIcon().isNull()) {
ic = w->windowIcon(); ic = w->windowIcon();
break; break;
} }
} }
if (ic.isNull()) if (ic.isNull()) ic = QIcon(QPixmap::fromImage(logo_im));
ic = QIcon(QPixmap::fromImage(logo_im));
setWindowIcon(ic); setWindowIcon(ic);
QFormLayout * lay = (QFormLayout*)(ui->groupVersions->layout()); QFormLayout * lay = (QFormLayout *)(ui->groupVersions->layout());
foreach (SSPair p, versions) { foreach(SSPair p, versions) {
lay->addRow(p.first, new QLabel(p.second)); lay->addRow(p.first, new QLabel(p.second));
} }
lay = (QFormLayout*)(ui->groupBuild->layout()); lay = (QFormLayout *)(ui->groupBuild->layout());
foreach (SSPair p, builds) { foreach(SSPair p, builds) {
lay->addRow(p.first, new QLabel(p.second)); lay->addRow(p.first, new QLabel(p.second));
} }
ui->imageView->setPixmap(QPixmap::fromImage(logo_im)); ui->imageView->setPixmap(QPixmap::fromImage(logo_im));
ui->labelComment->setText(comment); ui->labelComment->setText(comment);
ui->labelComment->setOpenExternalLinks(true); ui->labelComment->setOpenExternalLinks(true);
ui->labelComment->setHidden(comment.isEmpty()); ui->labelComment->setHidden(comment.isEmpty());
//ui->labelArch->setText(QSysInfo::currentCpuArchitecture()); // ui->labelArch->setText(QSysInfo::currentCpuArchitecture());
ui->labelAuthors->setText(authors()); ui->labelAuthors->setText(authors());
connect(ui->buttonQt, SIGNAL(clicked()), qApp, SLOT(aboutQt())); connect(ui->buttonQt, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
#ifdef MOBILE_VIEW #ifdef MOBILE_VIEW
ui->layoutMain->insertWidget(0, ui->imageView); ui->layoutMain->insertWidget(0, ui->imageView);
//ui->verticalSpacer->changeSize(1, 1, QSizePolicy::Preferred, QSizePolicy::Preferred); // ui->verticalSpacer->changeSize(1, 1, QSizePolicy::Preferred, QSizePolicy::Preferred);
#endif #endif
#ifdef MOBILE_VIEW #ifdef MOBILE_VIEW
ui->layoutMain->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::Expanding)); ui->layoutMain->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::Expanding));
@@ -70,18 +69,17 @@ AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWin
r = QApplication::desktop()->geometry(); r = QApplication::desktop()->geometry();
# else # else
QScreen * scr = QScreen * scr =
# if QT_VERSION >= 0x050A00 # if QT_VERSION >= 0x050A00
QApplication::screenAt(QCursor::pos()); QApplication::screenAt(QCursor::pos());
# else # else
QApplication::screens()[0]; QApplication::screens()[0];
# endif # endif
if (scr) { if (scr) {
r.setSize(scr->availableSize() / 2); r.setSize(scr->availableSize() / 2);
r.moveCenter(scr->availableGeometry().center()); r.moveCenter(scr->availableGeometry().center());
} }
# endif # endif
if (r.isValid()) if (r.isValid()) setGeometry(r);
setGeometry(r);
#endif #endif
} }
@@ -103,7 +101,7 @@ void AboutWindow::setLogo(QString path) {
void AboutWindow::addVersion(QString name, QString version) { void AboutWindow::addVersion(QString name, QString version) {
if (!name.endsWith(":")) name.append(":"); if (!name.endsWith(":")) name.append(":");
foreach (const SSPair & p, versions) { foreach(const SSPair & p, versions) {
if (p.first == name) return; if (p.first == name) return;
} }
version.prepend("<b>"); version.prepend("<b>");
@@ -117,7 +115,7 @@ void AboutWindow::addVersion(QString name, QString version) {
void AboutWindow::addBuildInfo(QString name, QString value) { void AboutWindow::addBuildInfo(QString name, QString value) {
if (!name.endsWith(":")) name.append(":"); if (!name.endsWith(":")) name.append(":");
foreach (const SSPair & p, builds) { foreach(const SSPair & p, builds) {
if (p.first == name) return; if (p.first == name) return;
} }
builds << SSPair(name, value); builds << SSPair(name, value);
@@ -143,13 +141,13 @@ void AboutWindow::show() {
int AboutWindow::exec() { int AboutWindow::exec() {
#ifdef MOBILE_VIEW #ifdef MOBILE_VIEW
showFullScreen(); showFullScreen();
//setWindowState(Qt::WindowFullScreen); // setWindowState(Qt::WindowFullScreen);
#endif #endif
return QDialog::exec(); return QDialog::exec();
} }
void AboutWindow::changeEvent(QEvent *e) { void AboutWindow::changeEvent(QEvent * e) {
QDialog::changeEvent(e); QDialog::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange:
@@ -202,14 +200,13 @@ QString AboutWindow::authors() {
} else { } else {
QPIConfig conf(&fc); QPIConfig conf(&fc);
QPIConfig::Branch br = conf.allLeaves(); QPIConfig::Branch br = conf.allLeaves();
foreach (QPIConfig::Entry * e, br) { foreach(QPIConfig::Entry * e, br) {
l = e->toString().trimmed(); l = e->toString().trimmed();
if (!l.contains("<")) continue; if (!l.contains("<")) continue;
QString name, mail; QString name, mail;
name = l.left(l.indexOf("<")); name = l.left(l.indexOf("<"));
mail = l.mid(name.size() + 1); mail = l.mid(name.size() + 1);
if (mail.endsWith(">")) if (mail.endsWith(">")) mail.chop(1);
mail.chop(1);
name = name.trimmed(); name = name.trimmed();
mail = mail.trimmed(); mail = mail.trimmed();
addAuthor(ret, name, mail); addAuthor(ret, name, mail);
@@ -217,4 +214,3 @@ QString AboutWindow::authors() {
} }
return ret; return ret;
} }
+30 -31
View File
@@ -1,61 +1,61 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef ABOUTWINDOW_H #ifndef ABOUTWINDOW_H
#define ABOUTWINDOW_H #define ABOUTWINDOW_H
#include <QDialog>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QDialog>
#define ADD_ABOUT_VERSION(lib) \
{ \ #define ADD_ABOUT_VERSION(lib) \
if (lib##_VERSION_BUILD > 0) \ { \
if (lib##_VERSION_BUILD > 0) \
AboutWindow::addVersion(#lib, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \ AboutWindow::addVersion(#lib, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \
else \ else \
AboutWindow::addVersion(#lib, lib##_VERSION_NAME); \ AboutWindow::addVersion(#lib, lib##_VERSION_NAME); \
} }
#define ADD_ABOUT_VERSION_NAMED(lib, label) \ #define ADD_ABOUT_VERSION_NAMED(lib, label) \
{ \ { \
if (lib##_VERSION_BUILD > 0) \ if (lib##_VERSION_BUILD > 0) \
AboutWindow::addVersion(label, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \ AboutWindow::addVersion(label, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \
else \ else \
AboutWindow::addVersion(label, lib##_VERSION_NAME); \ AboutWindow::addVersion(label, lib##_VERSION_NAME); \
} }
#define ADD_ABOUT_BUILD_INFO(lib) \ #define ADD_ABOUT_BUILD_INFO(lib) \
AboutWindow::addBuildInfo("Arch", lib##_ARCH); \ AboutWindow::addBuildInfo("Arch", lib##_ARCH); \
AboutWindow::addBuildInfo("Compiler", lib##_CXX_COMPILER); \ AboutWindow::addBuildInfo("Compiler", lib##_CXX_COMPILER); \
AboutWindow::addBuildInfo("CMake", lib##_CMAKE_VERSION); \ AboutWindow::addBuildInfo("CMake", lib##_CMAKE_VERSION); \
AboutWindow::addBuildInfo("Date", lib##_BUILD_DATE); AboutWindow::addBuildInfo("Date", lib##_BUILD_DATE);
namespace Ui { namespace Ui {
class AboutWindow; class AboutWindow;
} }
class QAD_APPLICATION_EXPORT AboutWindow: public QDialog class QAD_APPLICATION_EXPORT AboutWindow: public QDialog {
{
Q_OBJECT Q_OBJECT
typedef QPair<QString, QString> SSPair; typedef QPair<QString, QString> SSPair;
explicit AboutWindow(QWidget * parent = 0); explicit AboutWindow(QWidget * parent = 0);
~AboutWindow(); ~AboutWindow();
public:
public:
static void setLogo(QImage im); static void setLogo(QImage im);
static void setLogo(QString path); static void setLogo(QString path);
static void addVersion(QString name, QString version); static void addVersion(QString name, QString version);
@@ -77,7 +77,6 @@ private:
static QImage logo; static QImage logo;
static QVector<SSPair> versions, builds; static QVector<SSPair> versions, builds;
static QString stylesheet, comment; static QString stylesheet, comment;
}; };
#endif // ABOUTWINDOW_H #endif // ABOUTWINDOW_H
+18 -15
View File
@@ -1,5 +1,7 @@
#include "edockwidget.h" #include "edockwidget.h"
#include "qad_types.h" #include "qad_types.h"
#include <QEvent> #include <QEvent>
#include <QStyle> #include <QStyle>
@@ -18,14 +20,14 @@ void EDockWidget::setWindowTitle(const QString & title) {
void EDockWidget::setWindowIcon(const QIcon & icon) { void EDockWidget::setWindowIcon(const QIcon & icon) {
//#ifndef Q_OS_MACOS // #ifndef Q_OS_MACOS
lbl_icon->setPixmap(icon.pixmap(QSize(256, 256))); lbl_icon->setPixmap(icon.pixmap(QSize(256, 256)));
QDockWidget::setWindowIcon(icon); QDockWidget::setWindowIcon(icon);
if (!icon.isNull()) { if (!icon.isNull()) {
lbl_icon->setScaledContents(true); lbl_icon->setScaledContents(true);
lbl_icon->setFixedSize(preferredIconSize(1.5, this)); lbl_icon->setFixedSize(preferredIconSize(1.5, this));
} }
//#endif // #endif
} }
@@ -40,32 +42,33 @@ bool EDockWidget::event(QEvent * e) {
void EDockWidget::init() { void EDockWidget::init() {
header = new QFrame(); header = new QFrame();
header->setFrameShape(QFrame::StyledPanel); header->setFrameShape(QFrame::StyledPanel);
QBoxLayout * lay = new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); QBoxLayout * lay =
new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
lay->setContentsMargins(2, 2, 2, 2); lay->setContentsMargins(2, 2, 2, 2);
lay->setSpacing(2); lay->setSpacing(2);
lbl_icon = new QLabel(); lbl_icon = new QLabel();
//#ifndef Q_OS_MACOS // #ifndef Q_OS_MACOS
QIcon wi = windowIcon(); QIcon wi = windowIcon();
if (!wi.isNull()) { if (!wi.isNull()) {
lbl_icon->setPixmap(wi.pixmap(QSize(256,256))); lbl_icon->setPixmap(wi.pixmap(QSize(256, 256)));
/*#if QT_VERSION >= 0x500000 /*#if QT_VERSION >= 0x500000
if (lbl_icon->pixmap()) if (lbl_icon->pixmap())
const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.); const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.);
#endif*/ #endif*/
//qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size(); // qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size();
lbl_icon->setScaledContents(true); lbl_icon->setScaledContents(true);
} }
lbl_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); lbl_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
//#endif // #endif
lbl_title = new QLabel(windowTitle()); lbl_title = new QLabel(windowTitle());
lbl_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); lbl_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
btn_dock = new QToolButton(); btn_dock = new QToolButton();
//btn_dock->setIconSize(QSize(16, 16)); // btn_dock->setIconSize(QSize(16, 16));
btn_dock->setAutoRaise(true); btn_dock->setAutoRaise(true);
btn_dock->setFocusPolicy(Qt::NoFocus); btn_dock->setFocusPolicy(Qt::NoFocus);
btn_dock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); btn_dock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
btn_hide = new QToolButton(); btn_hide = new QToolButton();
//btn_hide->setIconSize(QSize(16, 16)); // btn_hide->setIconSize(QSize(16, 16));
btn_hide->setAutoRaise(true); btn_hide->setAutoRaise(true);
btn_hide->setFocusPolicy(Qt::NoFocus); btn_hide->setFocusPolicy(Qt::NoFocus);
btn_hide->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); btn_hide->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
@@ -83,8 +86,8 @@ void EDockWidget::init() {
void EDockWidget::updateStyle() { void EDockWidget::updateStyle() {
QSize icon_size = preferredIconSize(0.75, this); QSize icon_size = preferredIconSize(0.75, this);
int bm = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this); int bm = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
QSize btn_size = icon_size; QSize btn_size = icon_size;
btn_size += QSize(bm, bm); btn_size += QSize(bm, bm);
btn_dock->setIcon(style()->standardIcon(QStyle::SP_TitleBarNormalButton)); btn_dock->setIcon(style()->standardIcon(QStyle::SP_TitleBarNormalButton));
btn_dock->setIconSize(icon_size); btn_dock->setIconSize(icon_size);
+37 -28
View File
@@ -1,42 +1,52 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EDOCKWIDGET_H #ifndef EDOCKWIDGET_H
#define EDOCKWIDGET_H #define EDOCKWIDGET_H
#include <QDockWidget>
#include <QLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QIcon>
#include <QToolButton>
#include <QDebug>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QDebug>
#include <QDockWidget>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QLayout>
#include <QToolButton>
class QAD_APPLICATION_EXPORT EDockWidget: public QDockWidget
{ class QAD_APPLICATION_EXPORT EDockWidget: public QDockWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(title, parent, flags) {init();} explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags())
explicit EDockWidget(QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(parent, flags) {init();} : QDockWidget(title, parent, flags) {
~EDockWidget() {delete btn_hide; delete btn_dock; delete lbl_title; delete lbl_icon; delete header;} init();
}
explicit EDockWidget(QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(parent, flags) { init(); }
~EDockWidget() {
delete btn_hide;
delete btn_dock;
delete lbl_title;
delete lbl_icon;
delete header;
}
void setFeatures(QDockWidget::DockWidgetFeatures features); void setFeatures(QDockWidget::DockWidgetFeatures features);
void setWindowTitle(const QString & title); void setWindowTitle(const QString & title);
@@ -48,12 +58,11 @@ private:
void updateStyle(); void updateStyle();
QFrame * header; QFrame * header;
QLabel * lbl_title, * lbl_icon; QLabel *lbl_title, *lbl_icon;
QToolButton * btn_hide, * btn_dock; QToolButton *btn_hide, *btn_dock;
private slots: private slots:
void dockClicked() {setFloating(!isFloating());} void dockClicked() { setFloating(!isFloating()); }
}; };
#endif // EDOCKWIDGET_H #endif // EDOCKWIDGET_H
+74 -70
View File
@@ -1,13 +1,19 @@
#include "emainwindow.h" #include "emainwindow.h"
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox>
#include <QMenu>
#include <QLabel> #include <QLabel>
#include <QMenu>
#include <QMessageBox>
EMainWindow::EMainWindow(QWidget * parent): QMainWindow(parent), action_show_all_tools(this), action_hide_all_tools(this), EMainWindow::EMainWindow(QWidget * parent)
action_show_all_docks(this), action_hide_all_docks(this), first_show(true) { : QMainWindow(parent)
menu_recent = 0; , action_show_all_tools(this)
, action_hide_all_tools(this)
, action_show_all_docks(this)
, action_hide_all_docks(this)
, first_show(true) {
menu_recent = 0;
action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this); action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this);
connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent())); connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent()));
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea"); qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
@@ -26,8 +32,7 @@ action_show_all_docks(this), action_hide_all_docks(this), first_show(true) {
} }
EMainWindow::~EMainWindow() { EMainWindow::~EMainWindow() {}
}
void EMainWindow::setRecentFiles(const QStringList & rl) { void EMainWindow::setRecentFiles(const QStringList & rl) {
@@ -39,7 +44,7 @@ void EMainWindow::setRecentFiles(const QStringList & rl) {
QStringList EMainWindow::recentFiles() const { QStringList EMainWindow::recentFiles() const {
QStringList ret; QStringList ret;
foreach (QAction * a, actions_recent) foreach(QAction * a, actions_recent)
ret << a->data().toString(); ret << a->data().toString();
return ret; return ret;
} }
@@ -56,7 +61,7 @@ void EMainWindow::showEvent(QShowEvent * e) {
initMenus(); initMenus();
if (!first_show) return; if (!first_show) return;
first_show = false; first_show = false;
QList<QDockWidget * > docks(findChildren<QDockWidget * >()); QList<QDockWidget *> docks(findChildren<QDockWidget *>());
for (QDockWidget * d: docks) { for (QDockWidget * d: docks) {
connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(changedDock())); connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(changedDock()));
connect(d, SIGNAL(topLevelChanged(bool)), this, SLOT(changedDock())); connect(d, SIGNAL(topLevelChanged(bool)), this, SLOT(changedDock()));
@@ -67,16 +72,18 @@ void EMainWindow::showEvent(QShowEvent * e) {
void EMainWindow::closeEvent(QCloseEvent * e) { void EMainWindow::closeEvent(QCloseEvent * e) {
if (!checkSave()) e->ignore(); if (!checkSave())
else saveSession(); e->ignore();
else
saveSession();
} }
bool EMainWindow::eventFilter(QObject * o, QEvent * e) { bool EMainWindow::eventFilter(QObject * o, QEvent * e) {
if (tbars.contains((QTabBar*)o) && e->type() == QEvent::MouseButtonDblClick) { if (tbars.contains((QTabBar *)o) && e->type() == QEvent::MouseButtonDblClick) {
int tab = ((QTabBar*)o)->tabAt(((QMouseEvent * )e)->pos()); int tab = ((QTabBar *)o)->tabAt(((QMouseEvent *)e)->pos());
if (tab >= 0) { if (tab >= 0) {
QDockWidget * dock = (QDockWidget * )(((QTabBar*)o)->tabData(tab).toULongLong()); QDockWidget * dock = (QDockWidget *)(((QTabBar *)o)->tabData(tab).toULongLong());
if (dock) { if (dock) {
dock->setFloating(true); dock->setFloating(true);
return true; return true;
@@ -84,25 +91,25 @@ bool EMainWindow::eventFilter(QObject * o, QEvent * e) {
} }
} }
/*if (e->type() == QEvent::Show || e->type() == QEvent::Hide) { /*if (e->type() == QEvent::Show || e->type() == QEvent::Hide) {
if (tdocks.contains((QDockWidget*)o)) { if (tdocks.contains((QDockWidget*)o)) {
changedDock(); changedDock();
} }
}*/ }*/
if (e->type() == QEvent::MouseButtonPress) { if (e->type() == QEvent::MouseButtonPress) {
if (tbars.contains((QTabBar*)o) || tdocks.contains((QDockWidget*)o)) { if (tbars.contains((QTabBar *)o) || tdocks.contains((QDockWidget *)o)) {
if (e->type() == QEvent::MouseButtonPress) { if (e->type() == QEvent::MouseButtonPress) {
if (((QMouseEvent*)e)->button() == Qt::RightButton) { if (((QMouseEvent *)e)->button() == Qt::RightButton) {
bool popup = tbars.contains((QTabBar*)o); bool popup = tbars.contains((QTabBar *)o);
if (tdocks.contains((QDockWidget*)o)) if (tdocks.contains((QDockWidget *)o))
popup = popup || ((QDockWidget*)o)->titleBarWidget()->geometry().contains(((QMouseEvent*)e)->pos()); popup = popup || ((QDockWidget *)o)->titleBarWidget()->geometry().contains(((QMouseEvent *)e)->pos());
if (popup) { if (popup) {
createPopupMenu()->popup( createPopupMenu()->popup(
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
((QMouseEvent*)e)->globalPos() ((QMouseEvent *)e)->globalPos()
#else #else
((QMouseEvent*)e)->globalPosition().toPoint() ((QMouseEvent *)e)->globalPosition().toPoint()
#endif #endif
); );
return true; return true;
} }
} }
@@ -123,8 +130,7 @@ void EMainWindow::changeEvent(QEvent * e) {
action_hide_all_docks.setText(tr("Hide all")); action_hide_all_docks.setText(tr("Hide all"));
action_clear_recent->setText(tr("Clear recent list")); action_clear_recent->setText(tr("Clear recent list"));
break; break;
default: default: break;
break;
} }
} }
@@ -137,9 +143,9 @@ QMenu * EMainWindow::createPopupMenu() {
QFont f; QFont f;
f.setBold(true); f.setBold(true);
// Toolbars // Toolbars
QList<QToolBar * > tools = findChildren<QToolBar * >(); QList<QToolBar *> tools = findChildren<QToolBar *>();
if (!tools.isEmpty()) { if (!tools.isEmpty()) {
wa = new QWidgetAction(menuPopup); wa = new QWidgetAction(menuPopup);
lbl = new QLabel(); lbl = new QLabel();
lbl->setFrameShape(QFrame::StyledPanel); lbl->setFrameShape(QFrame::StyledPanel);
lbl->setFrameShadow(QFrame::Sunken); lbl->setFrameShadow(QFrame::Sunken);
@@ -162,9 +168,9 @@ QMenu * EMainWindow::createPopupMenu() {
menuPopup->addAction(&action_hide_all_tools); menuPopup->addAction(&action_hide_all_tools);
} }
// Docks // Docks
QList<QDockWidget * > docks = findChildren<QDockWidget * >(); QList<QDockWidget *> docks = findChildren<QDockWidget *>();
if (!docks.isEmpty()) { if (!docks.isEmpty()) {
wa = new QWidgetAction(menuPopup); wa = new QWidgetAction(menuPopup);
lbl = new QLabel(); lbl = new QLabel();
lbl->setFrameShape(QFrame::StyledPanel); lbl->setFrameShape(QFrame::StyledPanel);
lbl->setFrameShadow(QFrame::Sunken); lbl->setFrameShadow(QFrame::Sunken);
@@ -193,7 +199,7 @@ QMenu * EMainWindow::createPopupMenu() {
void EMainWindow::addToRecent(const QString & path) { void EMainWindow::addToRecent(const QString & path) {
if (path.isEmpty()) return; if (path.isEmpty()) return;
QFileInfo fi(path); QFileInfo fi(path);
QString fp = fi.absoluteFilePath(); QString fp = fi.absoluteFilePath();
bool insert = true; bool insert = true;
for (int i = 0; i < actions_recent.size(); ++i) for (int i = 0; i < actions_recent.size(); ++i)
if (actions_recent[i]->data().toString() == fp) { if (actions_recent[i]->data().toString() == fp) {
@@ -232,7 +238,7 @@ void EMainWindow::initMenus() {
action_show_all_docks.disconnect(); action_show_all_docks.disconnect();
action_hide_all_docks.disconnect(); action_hide_all_docks.disconnect();
QList<QToolBar * > tools = findChildren<QToolBar * >(); QList<QToolBar *> tools = findChildren<QToolBar *>();
for (QToolBar * i: tools) { for (QToolBar * i: tools) {
if (i->property("ribbon").toBool()) continue; if (i->property("ribbon").toBool()) continue;
i->toggleViewAction()->setIcon(i->windowIcon()); i->toggleViewAction()->setIcon(i->windowIcon());
@@ -240,7 +246,7 @@ void EMainWindow::initMenus() {
connect(&action_hide_all_tools, SIGNAL(triggered(bool)), i, SLOT(hide())); connect(&action_hide_all_tools, SIGNAL(triggered(bool)), i, SLOT(hide()));
} }
QList<QDockWidget * > docks = findChildren<QDockWidget * >(); QList<QDockWidget *> docks = findChildren<QDockWidget *>();
for (QDockWidget * i: docks) { for (QDockWidget * i: docks) {
if (i->property("ribbon").toBool()) continue; if (i->property("ribbon").toBool()) continue;
i->toggleViewAction()->setIcon(i->windowIcon()); i->toggleViewAction()->setIcon(i->windowIcon());
@@ -248,7 +254,7 @@ void EMainWindow::initMenus() {
connect(&action_hide_all_docks, SIGNAL(triggered(bool)), i, SLOT(hide())); connect(&action_hide_all_docks, SIGNAL(triggered(bool)), i, SLOT(hide()));
} }
QList<QAction * > actions = findChildren<QAction * >(); QList<QAction *> actions = findChildren<QAction *>();
for (QAction * i: actions) for (QAction * i: actions)
i->setIconVisibleInMenu(true); i->setIconVisibleInMenu(true);
addActions(actions); addActions(actions);
@@ -256,8 +262,8 @@ void EMainWindow::initMenus() {
void EMainWindow::initSession() { void EMainWindow::initSession() {
connect(&session, SIGNAL(loading(QPIConfig & )), this, SLOT(sessionLoading(QPIConfig & ))); connect(&session, SIGNAL(loading(QPIConfig &)), this, SLOT(sessionLoading(QPIConfig &)));
connect(&session, SIGNAL(saving(QPIConfig & )), this, SLOT(sessionSaving(QPIConfig & ))); connect(&session, SIGNAL(saving(QPIConfig &)), this, SLOT(sessionSaving(QPIConfig &)));
} }
@@ -279,18 +285,18 @@ bool EMainWindow::checkSave() {
void EMainWindow::changedDock() { void EMainWindow::changedDock() {
if (isHidden()) return; if (isHidden()) return;
QSet<QDockWidget * > invalid_tab_docks; QSet<QDockWidget *> invalid_tab_docks;
QList<QTabBar * > tabs(findChildren<QTabBar * >()); QList<QTabBar *> tabs(findChildren<QTabBar *>());
QList<QDockWidget * > docks = findChildren<QDockWidget * >(); QList<QDockWidget *> docks = findChildren<QDockWidget *>();
QRect geom = geometry(); QRect geom = geometry();
//qDebug() << "### change" << docks.size() << tabs.size(); // qDebug() << "### change" << docks.size() << tabs.size();
for (QTabBar * t: tabs) { for (QTabBar * t: tabs) {
if (!t->objectName().isEmpty() || t->isHidden()) continue; if (!t->objectName().isEmpty() || t->isHidden()) continue;
if (!tbars.contains(t)) { if (!tbars.contains(t)) {
//qDebug() << "add tab" << t; // qDebug() << "add tab" << t;
tbars << t; tbars << t;
connect(t, SIGNAL(tabCloseRequested(int)), this, SLOT(closeDock(int))); connect(t, SIGNAL(tabCloseRequested(int)), this, SLOT(closeDock(int)));
connect(t, &QObject::destroyed, this, [this,t](){tbars.removeOne(t);}); connect(t, &QObject::destroyed, this, [this, t]() { tbars.removeOne(t); });
t->installEventFilter(this); t->installEventFilter(this);
#ifndef Q_OS_MACOS #ifndef Q_OS_MACOS
t->setIconSize(dockTabsIconSize()); t->setIconSize(dockTabsIconSize());
@@ -298,12 +304,11 @@ void EMainWindow::changedDock() {
t->setTabsClosable(true); t->setTabsClosable(true);
} }
for (int i = 0; i < t->count(); ++i) { for (int i = 0; i < t->count(); ++i) {
QDockWidget * dock = (QDockWidget * )t->tabData(i).toULongLong(); QDockWidget * dock = (QDockWidget *)t->tabData(i).toULongLong();
//qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock; // qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock;
if (!dock) continue; if (!dock) continue;
if (!docks.contains(dock)) continue; if (!docks.contains(dock)) continue;
if (!geom.intersects(t->geometry())) if (!geom.intersects(t->geometry())) invalid_tab_docks << dock;
invalid_tab_docks << dock;
#ifndef Q_OS_MACOS #ifndef Q_OS_MACOS
QSize is = dockTabsIconSize(); QSize is = dockTabsIconSize();
if (t->iconSize() != is) t->setIconSize(is); if (t->iconSize() != is) t->setIconSize(is);
@@ -318,24 +323,24 @@ void EMainWindow::changedDock() {
if (!d->property("__titleWidget").isValid()) { if (!d->property("__titleWidget").isValid()) {
d->setProperty("__titleWidget", qulonglong(ctb)); d->setProperty("__titleWidget", qulonglong(ctb));
QWidget * ntb = new QWidget(); QWidget * ntb = new QWidget();
int m = style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin); int m = style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin);
ntb->setLayout(new QBoxLayout(QBoxLayout::BottomToTop)); ntb->setLayout(new QBoxLayout(QBoxLayout::BottomToTop));
ntb->layout()->setContentsMargins(m, m, 0, 0); ntb->layout()->setContentsMargins(m, m, 0, 0);
d->setProperty("__titleEmptyWidget", qulonglong(ntb)); d->setProperty("__titleEmptyWidget", qulonglong(ntb));
} }
if (!tdocks.contains(d)) { if (!tdocks.contains(d)) {
//qDebug() << "add dock" << d; // qDebug() << "add dock" << d;
tdocks << d; tdocks << d;
connect(d, &QObject::destroyed, this, [this,d](){tdocks.removeOne(d);}); connect(d, &QObject::destroyed, this, [this, d]() { tdocks.removeOne(d); });
d->installEventFilter(this); d->installEventFilter(this);
} }
//qDebug() << d->windowTitle() << tabifiedDockWidgets(d); // qDebug() << d->windowTitle() << tabifiedDockWidgets(d);
if (tabifiedDockWidgets(d).isEmpty() || invalid_tab_docks.contains(d)) { if (tabifiedDockWidgets(d).isEmpty() || invalid_tab_docks.contains(d)) {
if (d->titleBarWidget() != (QWidget * )(d->property("__titleWidget").toULongLong())) if (d->titleBarWidget() != (QWidget *)(d->property("__titleWidget").toULongLong()))
d->setTitleBarWidget((QWidget * )(d->property("__titleWidget").toULongLong())); d->setTitleBarWidget((QWidget *)(d->property("__titleWidget").toULongLong()));
} else { } else {
if (d->titleBarWidget() != (QWidget * )(d->property("__titleEmptyWidget").toULongLong())) { if (d->titleBarWidget() != (QWidget *)(d->property("__titleEmptyWidget").toULongLong())) {
d->setTitleBarWidget((QWidget * )(d->property("__titleEmptyWidget").toULongLong())); d->setTitleBarWidget((QWidget *)(d->property("__titleEmptyWidget").toULongLong()));
d->layout()->setContentsMargins(0, 20, 0, 0); d->layout()->setContentsMargins(0, 20, 0, 0);
} }
} }
@@ -344,20 +349,19 @@ void EMainWindow::changedDock() {
void EMainWindow::closeDock(int index) { void EMainWindow::closeDock(int index) {
QDockWidget * dock = (QDockWidget * )((QTabBar*)sender())->tabData(index).toULongLong(); QDockWidget * dock = (QDockWidget *)((QTabBar *)sender())->tabData(index).toULongLong();
if (dock == 0) return; if (dock == 0) return;
dock->close(); dock->close();
} }
void EMainWindow::recentTriggered() { void EMainWindow::recentTriggered() {
QAction * a = qobject_cast<QAction * >(sender()); QAction * a = qobject_cast<QAction *>(sender());
if (!a) return; if (!a) return;
QString path = a->data().toString(); QString path = a->data().toString();
if (path.isEmpty()) return; if (path.isEmpty()) return;
if (!checkSave()) return; if (!checkSave()) return;
if (load(path)) if (load(path)) addToRecent(path);
addToRecent(path);
} }
@@ -379,31 +383,32 @@ void EMainWindow::openFile() {
if (!checkSave()) return; if (!checkSave()) return;
QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter()); QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter());
if (ret.isEmpty()) return; if (ret.isEmpty()) return;
if (load(ret)) if (load(ret)) addToRecent(ret);
addToRecent(ret);
} }
void EMainWindow::openFiles() { void EMainWindow::openFiles() {
if (!checkSave()) return; if (!checkSave()) return;
QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter()); QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter());
foreach (QString s, ret) { foreach(QString s, ret) {
if (load(s)) if (load(s)) addToRecent(s);
addToRecent(s);
} }
} }
bool EMainWindow::saveFile(bool ask) { bool EMainWindow::saveFile(bool ask) {
if (ask) { if (ask) {
int ret = QMessageBox::question(this, windowTitle(), tr("Save changes%1?").arg(!file_name.isEmpty() ? (tr(" in") + " \"" + file_name + "\"") : ""), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); int ret = QMessageBox::question(this,
windowTitle(),
tr("Save changes%1?").arg(!file_name.isEmpty() ? (tr(" in") + " \"" + file_name + "\"") : ""),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save);
if (ret == QMessageBox::Cancel) return false; if (ret == QMessageBox::Cancel) return false;
if (ret == QMessageBox::Save) return saveFile(); if (ret == QMessageBox::Save) return saveFile();
return true; return true;
} }
if (file_name.isEmpty()) return saveAsFile(); if (file_name.isEmpty()) return saveAsFile();
if (save(file_name)) if (save(file_name)) addToRecent(file_name);
addToRecent(file_name);
return true; return true;
} }
@@ -411,8 +416,7 @@ bool EMainWindow::saveFile(bool ask) {
bool EMainWindow::saveAsFile() { bool EMainWindow::saveAsFile() {
QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter()); QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter());
if (ret.isEmpty()) return false; if (ret.isEmpty()) return false;
if (save(ret)) if (save(ret)) addToRecent(ret);
addToRecent(ret);
return true; return true;
} }
+60 -50
View File
@@ -1,43 +1,45 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EMAINWINDOW_H #ifndef EMAINWINDOW_H
#define EMAINWINDOW_H #define EMAINWINDOW_H
#include "qad_application_export.h"
#include "ribbon.h"
#include "session_manager.h"
#include <QClipboard>
#include <QColorDialog>
#include <QInputDialog>
#include <QRadioButton>
#include <QSplitter>
#include <QThread>
#include <QTime>
#include <QTranslator> #include <QTranslator>
#include <QUrl> #include <QUrl>
#include <QInputDialog>
#include <QClipboard>
#include <QRadioButton>
#include <QThread>
#include <QColorDialog>
#include <QTime>
#include <QSplitter>
#include "session_manager.h"
#include "ribbon.h"
#include "qad_application_export.h"
class QAD_APPLICATION_EXPORT UAction: public QAction { class QAD_APPLICATION_EXPORT UAction: public QAction {
Q_OBJECT Q_OBJECT
public: public:
UAction(int ind,const QString & text, QObject * parent): QAction(text, parent) { UAction(int ind, const QString & text, QObject * parent): QAction(text, parent) {
index = ind; index = ind;
connect(this, SIGNAL(triggered()), this, SLOT(triggered())); connect(this, SIGNAL(triggered()), this, SLOT(triggered()));
connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool))); connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
@@ -50,16 +52,17 @@ public:
connect(this, SIGNAL(hovered()), this, SLOT(hovered())); connect(this, SIGNAL(hovered()), this, SLOT(hovered()));
} }
public slots: public slots:
void show() {setVisible(true);} void show() { setVisible(true); }
void hide() {setVisible(false);} void hide() { setVisible(false); }
void setCheckedTrue() {setChecked(true);} void setCheckedTrue() { setChecked(true); }
void setCheckedFalse() {setChecked(false);} void setCheckedFalse() { setChecked(false); }
private: private:
int index; int index;
private slots: private slots:
void triggered() {emit itriggered(this, index);} void triggered() { emit itriggered(this, index); }
void toggled(bool t) {emit itoggled(t, this, index);} void toggled(bool t) { emit itoggled(t, this, index); }
void hovered() {emit ihovered(this);} void hovered() { emit ihovered(this); }
signals: signals:
void itriggered(QAction *, int); void itriggered(QAction *, int);
void itoggled(bool, QAction *, int); void itoggled(bool, QAction *, int);
@@ -67,55 +70,63 @@ signals:
}; };
class QAD_APPLICATION_EXPORT EMainWindow: public QMainWindow class QAD_APPLICATION_EXPORT EMainWindow: public QMainWindow {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems) Q_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems)
public: public:
EMainWindow(QWidget * parent = 0); EMainWindow(QWidget * parent = 0);
~EMainWindow(); ~EMainWindow();
virtual void reset(bool full = false) {} virtual void reset(bool full = false) {}
virtual bool load(const QString & path) {return true;} virtual bool load(const QString & path) { return true; }
virtual bool save(const QString & path) {return true;} virtual bool save(const QString & path) { return true; }
void addSeparator() {} void addSeparator() {}
void setRecentFiles(const QStringList & rl); void setRecentFiles(const QStringList & rl);
QStringList recentFiles() const; QStringList recentFiles() const;
void setRecentMenu(QMenu * m); void setRecentMenu(QMenu * m);
int maxRecentItems() const {return max_recent;} int maxRecentItems() const { return max_recent; }
protected: protected:
// Qt`s overloaded // Qt`s overloaded
void showEvent(QShowEvent * ); void showEvent(QShowEvent *);
void closeEvent(QCloseEvent * ); void closeEvent(QCloseEvent *);
bool eventFilter(QObject * o, QEvent * e); bool eventFilter(QObject * o, QEvent * e);
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
QMenu * createPopupMenu(); QMenu * createPopupMenu();
void addToRecent(const QString & path); void addToRecent(const QString & path);
void prepareRecent(); void prepareRecent();
void init(const QString & config) {session.setFile(config); initMenus(); initSession(); loadSession();} // unusable void init(const QString & config) {
session.setFile(config);
initMenus();
initSession();
loadSession();
} // unusable
void saveSession(); void saveSession();
void loadSession(); void loadSession();
virtual void savingSession(QPIConfig & conf) {} virtual void savingSession(QPIConfig & conf) {}
virtual void loadingSession(QPIConfig & conf) {} virtual void loadingSession(QPIConfig & conf) {}
virtual QSize dockTabsIconSize() const {return iconSize();} virtual QSize dockTabsIconSize() const { return iconSize(); }
virtual QString loadFilter() {return "All files(*)";} virtual QString loadFilter() { return "All files(*)"; }
virtual QString saveFilter() {return "All files(*)";} virtual QString saveFilter() { return "All files(*)"; }
bool checkSave(); bool checkSave();
void setChanged(bool yes = true) {isChanged = yes; setWindowModified(yes);} void setChanged(bool yes = true) {
isChanged = yes;
setWindowModified(yes);
}
void initMenus(); void initMenus();
void initSession(); void initSession();
QAction action_show_all_tools, action_hide_all_tools, action_show_all_docks, action_hide_all_docks; QAction action_show_all_tools, action_hide_all_tools, action_show_all_docks, action_hide_all_docks;
QString file_name; QString file_name;
QList<QTabBar * > tbars; QList<QTabBar *> tbars;
QList<QDockWidget * > tdocks; QList<QDockWidget *> tdocks;
QList<QAction * > actions_recent; QList<QAction *> actions_recent;
QAction * action_clear_recent; QAction * action_clear_recent;
QMenu * menu_recent; QMenu * menu_recent;
SessionManager session; SessionManager session;
@@ -124,24 +135,23 @@ protected:
private slots: private slots:
void changedDock(); void changedDock();
void sessionLoading(QPIConfig & conf) {loadingSession(conf);} void sessionLoading(QPIConfig & conf) { loadingSession(conf); }
void sessionSaving(QPIConfig & conf) {savingSession(conf);} void sessionSaving(QPIConfig & conf) { savingSession(conf); }
void closeDock(int index); void closeDock(int index);
void recentTriggered(); void recentTriggered();
public slots: public slots:
void setMaxRecentItems(int mr); void setMaxRecentItems(int mr);
void changed() {setChanged(true);} void changed() { setChanged(true); }
void newFile(); void newFile();
void openFile(); void openFile();
void openFiles(); void openFiles();
bool saveFile(bool ask); bool saveFile(bool ask);
bool saveFile() {return saveFile(false);} bool saveFile() { return saveFile(false); }
bool saveAsFile(); bool saveAsFile();
void clearRecent(); void clearRecent();
signals: signals:
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H
+21 -25
View File
@@ -1,7 +1,7 @@
#include "etabwidget.h" #include "etabwidget.h"
ETabWidget::ETabWidget(QWidget* parent): QTabWidget(parent) { ETabWidget::ETabWidget(QWidget * parent): QTabWidget(parent) {
tabBar()->setMouseTracking(true); tabBar()->setMouseTracking(true);
tabBar()->installEventFilter(this); tabBar()->installEventFilter(this);
} }
@@ -9,26 +9,27 @@ ETabWidget::ETabWidget(QWidget* parent): QTabWidget(parent) {
void ETabWidget::retranslate() { void ETabWidget::retranslate() {
for (int i = 0; i < buttons.size(); ++i) for (int i = 0; i < buttons.size(); ++i)
buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/); buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/);
QList<QToolButton * > bl = findChildren<QToolButton * >(); QList<QToolButton *> bl = findChildren<QToolButton *>();
foreach (QToolButton * i, bl) foreach(QToolButton * i, bl)
i->setToolTip(QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/)); i->setToolTip(
QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/));
} }
int ETabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label) { int ETabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label) {
int ret = QTabWidget::addTab(page, icon, label); int ret = QTabWidget::addTab(page, icon, label);
QWidget * w = new QWidget(); QWidget * w = new QWidget();
w->setLayout(new QBoxLayout(QBoxLayout::RightToLeft)); w->setLayout(new QBoxLayout(QBoxLayout::RightToLeft));
w->layout()->setContentsMargins(0, 0, 0, 0); w->layout()->setContentsMargins(0, 0, 0, 0);
w->layout()->setSpacing(2); w->layout()->setSpacing(2);
QToolButton * b; QToolButton * b;
foreach (const TabButton & i, buttons) { foreach(const TabButton & i, buttons) {
b = new QToolButton(); b = new QToolButton();
b->setToolTip(i.toolTip); b->setToolTip(i.toolTip);
b->setIconSize(QSize(16, 16)); b->setIconSize(QSize(16, 16));
b->setIcon(i.icon); b->setIcon(i.icon);
//b->setFlat(true); // b->setFlat(true);
b->setProperty("sourceToolTip", i.toolTip); b->setProperty("sourceToolTip", i.toolTip);
b->setProperty("buttonRole", i.role); b->setProperty("buttonRole", i.role);
connect(b, SIGNAL(clicked(bool)), this, SLOT(buttonClicked())); connect(b, SIGNAL(clicked(bool)), this, SLOT(buttonClicked()));
@@ -41,14 +42,12 @@ int ETabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label
void ETabWidget::setButtonVisible(int role, bool yes) { void ETabWidget::setButtonVisible(int role, bool yes) {
QList<QToolButton * > bl = findChildren<QToolButton * >(); QList<QToolButton *> bl = findChildren<QToolButton *>();
foreach (QToolButton * i, bl) foreach(QToolButton * i, bl)
if (i->property("buttonRole").toInt() == role) if (i->property("buttonRole").toInt() == role) i->setVisible(yes);
i->setVisible(yes);
QWidget * w; QWidget * w;
for (int i = 0; i < buttons.size(); ++i) { for (int i = 0; i < buttons.size(); ++i) {
if (buttons[i].role == role) if (buttons[i].role == role) buttons[i].visible = yes;
buttons[i].visible = yes;
w = tabBar()->tabButton(i, QTabBar::RightSide); w = tabBar()->tabButton(i, QTabBar::RightSide);
if (w != 0) w->adjustSize(); if (w != 0) w->adjustSize();
} }
@@ -57,19 +56,19 @@ void ETabWidget::setButtonVisible(int role, bool yes) {
/* /*
void ETabWidget::removeTab(int index) { void ETabWidget::removeTab(int index) {
tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(1)->widget())); tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(1)->widget()));
tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(0)->widget())); tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(0)->widget()));
QTabWidget::removeTab(index); QTabWidget::removeTab(index);
} }
*/ */
bool ETabWidget::eventFilter(QObject * o, QEvent * e) { bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
static int prev = -1; static int prev = -1;
if (e->type() == QEvent::MouseMove) { if (e->type() == QEvent::MouseMove) {
QTabBar * t = qobject_cast<QTabBar * >(o); QTabBar * t = qobject_cast<QTabBar *>(o);
if (t == 0) return QTabWidget::eventFilter(o, e); if (t == 0) return QTabWidget::eventFilter(o, e);
for (int i = 0; i < count(); ++i) for (int i = 0; i < count(); ++i)
if (t->tabRect(i).contains(((QMouseEvent * )e)->pos())) { if (t->tabRect(i).contains(((QMouseEvent *)e)->pos())) {
if (i != prev) { if (i != prev) {
prev = i; prev = i;
emit tabHovered(i); emit tabHovered(i);
@@ -94,17 +93,14 @@ bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
void ETabWidget::changeEvent(QEvent * e) { void ETabWidget::changeEvent(QEvent * e) {
QTabWidget::changeEvent(e); QTabWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: retranslate(); break;
retranslate(); default: break;
break;
default:
break;
} }
} }
void ETabWidget::buttonClicked() { void ETabWidget::buttonClicked() {
QToolButton * s = qobject_cast<QToolButton * >(sender()); QToolButton * s = qobject_cast<QToolButton *>(sender());
if (s == 0) return; if (s == 0) return;
QWidget * pw = s->parentWidget(); QWidget * pw = s->parentWidget();
if (pw == 0) return; if (pw == 0) return;
+36 -30
View File
@@ -1,58 +1,65 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef ETABWIDGET_H #ifndef ETABWIDGET_H
#define ETABWIDGET_H #define ETABWIDGET_H
#include <QTabWidget>
#include <QDebug>
#include <QTabBar>
#include <QMouseEvent>
#include <QEvent>
#include <QToolButton>
#include <QPushButton>
#include <QLayout>
#include <QHBoxLayout>
#include <QApplication>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QApplication>
#include <QDebug>
#include <QEvent>
#include <QHBoxLayout>
#include <QLayout>
#include <QMouseEvent>
#include <QPushButton>
#include <QTabBar>
#include <QTabWidget>
#include <QToolButton>
class QAD_APPLICATION_EXPORT ETabWidget: public QTabWidget
{ class QAD_APPLICATION_EXPORT ETabWidget: public QTabWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit ETabWidget(QWidget * parent = 0); explicit ETabWidget(QWidget * parent = 0);
void retranslate(); void retranslate();
void addTabButton(int role, const QIcon & icon, const QString & toolTip = QString()) {buttons << TabButton(role, icon, toolTip);} void addTabButton(int role, const QIcon & icon, const QString & toolTip = QString()) { buttons << TabButton(role, icon, toolTip); }
int addTab(QWidget * page, const QIcon & icon, const QString & label); int addTab(QWidget * page, const QIcon & icon, const QString & label);
int addTab(QWidget * page, const QString & label) {return addTab(page, QIcon(), label);} int addTab(QWidget * page, const QString & label) { return addTab(page, QIcon(), label); }
void setButtonVisible(int role, bool yes); void setButtonVisible(int role, bool yes);
private: private:
bool eventFilter(QObject * o, QEvent * e); bool eventFilter(QObject * o, QEvent * e);
void tabInserted(int) {emit countChanged();} void tabInserted(int) { emit countChanged(); }
void tabRemoved(int) {emit countChanged();} void tabRemoved(int) { emit countChanged(); }
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
struct QAD_APPLICATION_EXPORT TabButton { struct QAD_APPLICATION_EXPORT TabButton {
TabButton(int r, const QIcon & i, const QString & t) {role = r; icon = i; visible = true; srcToolTip = t; toolTip = QApplication::translate("MainWindow", t.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);} TabButton(int r, const QIcon & i, const QString & t) {
role = r;
icon = i;
visible = true;
srcToolTip = t;
toolTip = QApplication::translate("MainWindow", t.toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/);
}
int role; int role;
bool visible; bool visible;
QIcon icon; QIcon icon;
@@ -69,7 +76,6 @@ signals:
void countChanged(); void countChanged();
void tabHovered(int tab); void tabHovered(int tab);
void tabButtonClicked(int tab, int role); void tabButtonClicked(int tab, int role);
}; };
#endif // ETABWIDGET_H #endif // ETABWIDGET_H
+12 -16
View File
@@ -1,26 +1,26 @@
#include "historyview.h" #include "historyview.h"
#include <QScrollBar>
#include <QEvent> #include <QEvent>
#include <QScrollBar>
HistoryView::HistoryView(QWidget* parent): QListWidget(parent) { HistoryView::HistoryView(QWidget * parent): QListWidget(parent) {
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
setSelectionMode(QAbstractItemView::MultiSelection); setSelectionMode(QAbstractItemView::MultiSelection);
setEditTriggers(NoEditTriggers); setEditTriggers(NoEditTriggers);
active_ = true; active_ = true;
duplicates_ = false; duplicates_ = false;
index = 0; index = 0;
setLimit(32); setLimit(32);
setHistoryColor(palette().color(QPalette::Highlight)); setHistoryColor(palette().color(QPalette::Highlight));
connect(this, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(itemClicked(QListWidgetItem*))); connect(this, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(itemClicked(QListWidgetItem *)));
connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
registerAction(-1, tr("History cleared"), QImage(":/icons/clear-history.png")); registerAction(-1, tr("History cleared"), QImage(":/icons/clear-history.png"));
} }
HistoryView::~HistoryView() { HistoryView::~HistoryView() {}
}
QByteArray HistoryView::current() const { QByteArray HistoryView::current() const {
@@ -37,8 +37,7 @@ void HistoryView::addEntry(int action, int count_, const QString & suffix) {
QByteArray ba; QByteArray ba;
emit commandRequest(ba); emit commandRequest(ba);
if (!duplicates_) if (!duplicates_)
if (current() == ba) if (current() == ba) return;
return;
int cnt = count(); int cnt = count();
for (int i = index; i < cnt; ++i) for (int i = index; i < cnt; ++i)
if (i >= 0) delete takeItem(index); if (i >= 0) delete takeItem(index);
@@ -94,11 +93,8 @@ void HistoryView::checkLimit() {
void HistoryView::changeEvent(QEvent * e) { void HistoryView::changeEvent(QEvent * e) {
QListWidget::changeEvent(e); QListWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: actions_[-1].text = tr("History cleared"); break;
actions_[-1].text = tr("History cleared"); default: break;
break;
default:
break;
} }
} }
@@ -107,7 +103,7 @@ void HistoryView::itemClicked(QListWidgetItem * item) {
if (!active_) return; if (!active_) return;
if (index == row(item) + 1) return; if (index == row(item) + 1) return;
index = row(item) + 1; index = row(item) + 1;
//qDebug() << actions[index - 1].command; // qDebug() << actions[index - 1].command;
emit commandExecute(history_[index - 1].command); emit commandExecute(history_[index - 1].command);
emit changed(); emit changed();
itemSelectionChanged(); itemSelectionChanged();
@@ -117,7 +113,7 @@ void HistoryView::itemClicked(QListWidgetItem * item) {
void HistoryView::itemSelectionChanged() { void HistoryView::itemSelectionChanged() {
if (!active_) return; if (!active_) return;
if (index < 1) index = 1; if (index < 1) index = 1;
//qDebug() << "changed" << count(); // qDebug() << "changed" << count();
int vpos = verticalScrollBar()->value(); int vpos = verticalScrollBar()->value();
blockSignals(true); blockSignals(true);
setCurrentItem(item(index - 1)); setCurrentItem(item(index - 1));
+24 -24
View File
@@ -1,45 +1,46 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef HISTORYVIEW_H #ifndef HISTORYVIEW_H
#define HISTORYVIEW_H #define HISTORYVIEW_H
#include <QListWidget>
#include <QDebug>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QDebug>
#include <QListWidget>
class QAD_APPLICATION_EXPORT HistoryView: public QListWidget
{ class QAD_APPLICATION_EXPORT HistoryView: public QListWidget {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive) Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled) Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled)
Q_PROPERTY(int limit READ limit WRITE setLimit) Q_PROPERTY(int limit READ limit WRITE setLimit)
Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor) Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor)
public: public:
explicit HistoryView(QWidget * parent = 0); explicit HistoryView(QWidget * parent = 0);
~HistoryView(); ~HistoryView();
bool isActive() const {return active_;} bool isActive() const { return active_; }
bool isDuplicatesEnabled() const {return duplicates_;} bool isDuplicatesEnabled() const { return duplicates_; }
int limit() const {return limit_;} int limit() const { return limit_; }
QColor historyColor() const {return color_;} QColor historyColor() const { return color_; }
QByteArray current() const; QByteArray current() const;
void addEntry(int action, int count = 0, const QString & suffix = QString()); void addEntry(int action, int count = 0, const QString & suffix = QString());
@@ -75,12 +76,12 @@ private:
int index, limit_; int index, limit_;
public slots: public slots:
void setActive(bool yes) {active_ = yes;} void setActive(bool yes) { active_ = yes; }
void setDuplicatesEnabled(bool yes) {duplicates_ = yes;} void setDuplicatesEnabled(bool yes) { duplicates_ = yes; }
void setLimit(int l); void setLimit(int l);
void setHistoryColor(const QColor & c); void setHistoryColor(const QColor & c);
void clear(bool silent); void clear(bool silent);
void clear() {clear(false);} void clear() { clear(false); }
void undo(); void undo();
void redo(); void redo();
@@ -95,7 +96,6 @@ signals:
void commandRequest(QByteArray & s); void commandRequest(QByteArray & s);
void commandExecute(const QByteArray & s); void commandExecute(const QByteArray & s);
void changed(); void changed();
}; };
#endif // HISTORYVIEW_H #endif // HISTORYVIEW_H
+74 -65
View File
@@ -1,15 +1,17 @@
#include "logview.h" #include "logview.h"
#include "ui_logview.h"
#include "qad_types.h"
#include "ecombobox.h" #include "ecombobox.h"
#include <QTextDocument> #include "qad_types.h"
#include "ui_logview.h"
#include <QAbstractTextDocumentLayout> #include <QAbstractTextDocumentLayout>
#include <QTextEdit>
#include <QTextBlock>
#include <QScrollBar>
#include <QPixmap>
#include <QEvent> #include <QEvent>
#include <QPixmap>
#include <QScrollBar>
#include <QTextBlock>
#include <QTextBlockUserData> #include <QTextBlockUserData>
#include <QTextDocument>
#include <QTextEdit>
class TextBlockData: public QTextBlockUserData { class TextBlockData: public QTextBlockUserData {
@@ -19,8 +21,6 @@ public:
}; };
LogView::Category::Category() { LogView::Category::Category() {
bold = false; bold = false;
} }
@@ -104,33 +104,45 @@ int LogView::linesLimit() const {
} }
void LogView::registerCategory(const QString & label, QString keyword, const QImage & icon, QBrush text_brush, QBrush background, bool bold) { void LogView::registerCategory(const QString & label,
QString keyword,
const QImage & icon,
QBrush text_brush,
QBrush background,
bool bold) {
QRegularExpression regexp(keyword, QRegularExpression regexp(keyword,
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption) QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
#else #else
Qt::CaseInsensitive Qt::CaseInsensitive
#endif #endif
); );
registerCategory(label, regexp, icon, text_brush, background, bold); registerCategory(label, regexp, icon, text_brush, background, bold);
} }
void LogView::registerCategory(const QString & label, QRegularExpression regexp, const QImage & icon, QBrush text_brush, QBrush background, bool bold) { void LogView::registerCategory(const QString & label,
QRegularExpression regexp,
const QImage & icon,
QBrush text_brush,
QBrush background,
bool bold) {
if (!regexp.isValid() || regexp.pattern().isEmpty()) return; if (!regexp.isValid() || regexp.pattern().isEmpty()) return;
removeCategory(regexp); removeCategory(regexp);
Category c; Category c;
c.regexp = regexp; c.regexp = regexp;
c.label = label; c.label = label;
c.image = icon; c.image = icon;
c.text_brush = text_brush; c.text_brush = text_brush;
c.background = background; c.background = background;
c.bold = bold; c.bold = bold;
c.makeIcon(iconImageSize(), preferredIconSize(1., this) c.makeIcon(iconImageSize(),
preferredIconSize(1., this)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
, devicePixelRatioF() ,
devicePixelRatioF()
#endif #endif
); );
categories.append(c); categories.append(c);
ui->comboCategory->addItem(c.icon, label, QVariant(regexp)); ui->comboCategory->addItem(c.icon, label, QVariant(regexp));
} }
@@ -139,11 +151,11 @@ void LogView::registerCategory(const QString & label, QRegularExpression regexp,
void LogView::removeCategory(QString keyword) { void LogView::removeCategory(QString keyword) {
QRegularExpression regexp(keyword, QRegularExpression regexp(keyword,
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption) QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
#else #else
Qt::CaseInsensitive Qt::CaseInsensitive
#endif #endif
); );
removeCategory(regexp); removeCategory(regexp);
} }
@@ -153,13 +165,14 @@ void LogView::removeCategory(QRegularExpression regexp) {
c.regexp = regexp; c.regexp = regexp;
categories.removeAll(c); categories.removeAll(c);
for (int i = 1; i < ui->comboCategory->count(); ++i) { for (int i = 1; i < ui->comboCategory->count(); ++i) {
if (ui->comboCategory->itemData(i). if (ui->comboCategory->itemData(i)
.
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
toRegularExpression() toRegularExpression()
#else #else
toRegExp() toRegExp()
#endif #endif
.pattern() == regexp.pattern()) { .pattern() == regexp.pattern()) {
ui->comboCategory->removeItem(i); ui->comboCategory->removeItem(i);
--i; --i;
} }
@@ -188,16 +201,13 @@ void LogView::addText(const QString & text, const QString & keyword, bool insert
QStringList sl = text.split("\n"); QStringList sl = text.split("\n");
tc.movePosition(QTextCursor::End); tc.movePosition(QTextCursor::End);
QScrollBar * bar = ui->textEdit->verticalScrollBar(); QScrollBar * bar = ui->textEdit->verticalScrollBar();
bool at_end = (bar->value() == bar->maximum()) || bar->isHidden(); bool at_end = (bar->value() == bar->maximum()) || bar->isHidden();
for (int i = 0; i < sl.size(); ++i) { for (int i = 0; i < sl.size(); ++i) {
tc.insertText(sl[i]); tc.insertText(sl[i]);
if (!keyword.isEmpty()) if (!keyword.isEmpty()) tc.block().setUserData(new TextBlockData(keyword));
tc.block().setUserData(new TextBlockData(keyword)); if ((i < sl.size() - 1) || insert_newline) newLine(keyword);
if ((i < sl.size() - 1) || insert_newline)
newLine(keyword);
} }
if (at_end) if (at_end) scrollToBottom();
scrollToBottom();
} }
@@ -215,12 +225,14 @@ void LogView::changeEvent(QEvent * e) {
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this)); ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
QSize is = iconImageSize(), is_i = preferredIconSize(1., this); QSize is = iconImageSize(), is_i = preferredIconSize(1., this);
for (int i = 0; i < categories.size(); ++i) for (int i = 0; i < categories.size(); ++i)
categories[i].makeIcon(is, is_i categories[i].makeIcon(is,
is_i
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
, devicePixelRatioF() ,
devicePixelRatioF()
#endif #endif
); );
} break; } break;
default: break; default: break;
} }
} }
@@ -232,19 +244,18 @@ void LogView::newLine(const QString & keyword) {
tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
QString line = tc.selectedText(); QString line = tc.selectedText();
QImage icon; QImage icon;
foreach (const Category & c, categories) { foreach(const Category & c, categories) {
bool matched = false; bool matched = false;
if (keyword.isEmpty()) matched = line.contains(c.regexp); if (keyword.isEmpty())
else matched = (keyword == c.regexp.pattern()); matched = line.contains(c.regexp);
else
matched = (keyword == c.regexp.pattern());
if (matched) { if (matched) {
QTextCharFormat cf = def_cf; QTextCharFormat cf = def_cf;
QTextBlockFormat bf = def_bf; QTextBlockFormat bf = def_bf;
if (c.text_brush != Qt::NoBrush) if (c.text_brush != Qt::NoBrush) cf.setForeground(c.text_brush);
cf.setForeground(c.text_brush); if (c.background != Qt::NoBrush) bf.setBackground(c.background);
if (c.background != Qt::NoBrush) if (c.bold) cf.setFontWeight(QFont::Bold);
bf.setBackground(c.background);
if (c.bold)
cf.setFontWeight(QFont::Bold);
tc.setCharFormat(cf); tc.setCharFormat(cf);
tc.setBlockFormat(bf); tc.setBlockFormat(bf);
icon = c.icon_image; icon = c.icon_image;
@@ -257,13 +268,12 @@ void LogView::newLine(const QString & keyword) {
} }
QRegularExpression regexp = QRegularExpression regexp =
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
ui->comboCategory->currentData().toRegularExpression(); ui->comboCategory->currentData().toRegularExpression();
#else #else
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp(); ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
#endif #endif
QString fs = ui->lineEdit->text(); QString fs = ui->lineEdit->text();
if (isFilterVisible()) if (isFilterVisible()) filterBlock(tc.block(), fs, regexp);
filterBlock(tc.block(), fs, regexp);
tc.movePosition(QTextCursor::End); tc.movePosition(QTextCursor::End);
tc.setCharFormat(def_cf); tc.setCharFormat(def_cf);
tc.insertBlock(); tc.insertBlock();
@@ -278,15 +288,14 @@ QSize LogView::iconImageSize() {
void LogView::filterBlock(QTextBlock block, const QString & fs, const QRegularExpression & regexp) { void LogView::filterBlock(QTextBlock block, const QString & fs, const QRegularExpression & regexp) {
bool vis = true;//, pvis = block.isVisible(); bool vis = true; //, pvis = block.isVisible();
QString line = block.text(); QString line = block.text();
if (!line.isEmpty()) { if (!line.isEmpty()) {
if (line[0] == QChar::ObjectReplacementCharacter) if (line[0] == QChar::ObjectReplacementCharacter) line.remove(0, 1);
line.remove(0, 1);
} }
if (regexp.isValid() && !regexp.pattern().isEmpty()) { if (regexp.isValid() && !regexp.pattern().isEmpty()) {
QString kw; QString kw;
TextBlockData * bd = (TextBlockData*)block.userData(); TextBlockData * bd = (TextBlockData *)block.userData();
if (bd) kw = bd->keyword; if (bd) kw = bd->keyword;
if (!kw.isEmpty()) if (!kw.isEmpty())
vis = vis && (bd->keyword == regexp.pattern()); vis = vis && (bd->keyword == regexp.pattern());
@@ -295,8 +304,8 @@ void LogView::filterBlock(QTextBlock block, const QString & fs, const QRegularEx
} }
if (!fs.isEmpty()) vis = vis && line.contains(fs, Qt::CaseInsensitive); if (!fs.isEmpty()) vis = vis && line.contains(fs, Qt::CaseInsensitive);
block.setVisible(vis); block.setVisible(vis);
//qDebug() << "filterBlock" << line << vis; // qDebug() << "filterBlock" << line << vis;
//if (vis != pvis) // if (vis != pvis)
// ;//ui->textEdit->document()->mar // ;//ui->textEdit->document()->mar
} }
@@ -325,16 +334,16 @@ void LogView::scrollToBottom() {
void LogView::filter() { void LogView::filter() {
QTextDocument * doc = ui->textEdit->document(); QTextDocument * doc = ui->textEdit->document();
int bc = doc->blockCount(); int bc = doc->blockCount();
QRegularExpression regexp; QRegularExpression regexp;
QString fs; QString fs;
if (isFilterVisible()) { if (isFilterVisible()) {
regexp = regexp =
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
ui->comboCategory->currentData().toRegularExpression(); ui->comboCategory->currentData().toRegularExpression();
#else #else
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp(); ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
#endif #endif
fs = ui->lineEdit->text(); fs = ui->lineEdit->text();
} }
QTextBlock bl; QTextBlock bl;
+29 -30
View File
@@ -1,34 +1,34 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef LOGVIEW_H #ifndef LOGVIEW_H
#define LOGVIEW_H #define LOGVIEW_H
#include <QWidget>
#include <QIcon> #include <QIcon>
#include <QImage> #include <QImage>
#include <QTextBlockFormat> #include <QTextBlockFormat>
#include <QWidget>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QRegularExpression> # include <QRegularExpression>
#else #else
# include <QRegExp> # include <QRegExp>
typedef QRegExp QRegularExpression; typedef QRegExp QRegularExpression;
#endif #endif
#include "qad_application_export.h" #include "qad_application_export.h"
@@ -37,15 +37,15 @@ class QTextBlock;
class QAction; class QAction;
namespace Ui { namespace Ui {
class LogView; class LogView;
} }
class QAD_APPLICATION_EXPORT LogView: public QWidget class QAD_APPLICATION_EXPORT LogView: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool filterVisible READ isFilterVisible WRITE setFilterVisible) Q_PROPERTY(bool filterVisible READ isFilterVisible WRITE setFilterVisible)
Q_PROPERTY(int linesLimit READ linesLimit WRITE setLinesLimit) Q_PROPERTY(int linesLimit READ linesLimit WRITE setLinesLimit)
Q_PROPERTY(QFont logFont READ logFont WRITE setLogFont) Q_PROPERTY(QFont logFont READ logFont WRITE setLogFont)
public: public:
explicit LogView(QWidget * parent = 0); explicit LogView(QWidget * parent = 0);
~LogView(); ~LogView();
@@ -58,18 +58,18 @@ public:
int linesLimit() const; int linesLimit() const;
void registerCategory(const QString & label, void registerCategory(const QString & label,
QString keyword = QString(), QString keyword = QString(),
const QImage & icon = QImage(), const QImage & icon = QImage(),
QBrush text_brush = Qt::NoBrush, QBrush text_brush = Qt::NoBrush,
QBrush background = Qt::NoBrush, QBrush background = Qt::NoBrush,
bool bold = false); bool bold = false);
void registerCategory(const QString & label, void registerCategory(const QString & label,
QRegularExpression regexp, QRegularExpression regexp,
const QImage & icon = QImage(), const QImage & icon = QImage(),
QBrush text_brush = Qt::NoBrush, QBrush text_brush = Qt::NoBrush,
QBrush background = Qt::NoBrush, QBrush background = Qt::NoBrush,
bool bold = false); bool bold = false);
void removeCategory(QString keyword); void removeCategory(QString keyword);
void removeCategory(QRegularExpression regexp); void removeCategory(QRegularExpression regexp);
void clearCategories(); void clearCategories();
@@ -88,7 +88,7 @@ private:
QBrush text_brush; QBrush text_brush;
QBrush background; QBrush background;
bool bold; bool bold;
inline bool operator ==(const Category & it) const {return (regexp.pattern() == it.regexp.pattern());} inline bool operator==(const Category & it) const { return (regexp.pattern() == it.regexp.pattern()); }
}; };
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
@@ -100,7 +100,7 @@ private:
QList<Category> categories; QList<Category> categories;
QTextCharFormat def_cf; QTextCharFormat def_cf;
QTextBlockFormat def_bf; QTextBlockFormat def_bf;
QAction * actionLogSelectAll, * actionLogCopy, * actionLogClear; QAction *actionLogSelectAll, *actionLogCopy, *actionLogClear;
public slots: public slots:
void setFilterVisible(bool yes); void setFilterVisible(bool yes);
@@ -112,7 +112,6 @@ private slots:
void filter(); void filter();
signals: signals:
}; };
@@ -1,5 +1,7 @@
#include "edockwidget.h"
#include "edockwidgetplugin.h" #include "edockwidgetplugin.h"
#include "edockwidget.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ EDockWidgetPlugin::EDockWidgetPlugin(QObject * parent): QObject(parent) {
void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString EDockWidgetPlugin::domXml() const {
QString EDockWidgetPlugin::includeFile() const { QString EDockWidgetPlugin::includeFile() const {
return QLatin1String("edockwidget.h"); return QLatin1String("edockwidget.h");
} }
+3 -3
View File
@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class EDockWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface class EDockWidgetPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif #endif
@@ -1,5 +1,7 @@
#include "emainwindow.h"
#include "emainwindowplugin.h" #include "emainwindowplugin.h"
#include "emainwindow.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ EMainWindowPlugin::EMainWindowPlugin(QObject * parent): QObject(parent) {
void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString EMainWindowPlugin::domXml() const {
QString EMainWindowPlugin::includeFile() const { QString EMainWindowPlugin::includeFile() const {
return QLatin1String("emainwindow.h"); return QLatin1String("emainwindow.h");
} }
+3 -3
View File
@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class EMainWindowPlugin: public QObject, public QDesignerCustomWidgetInterface class EMainWindowPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif #endif
@@ -1,5 +1,7 @@
#include "historyview.h"
#include "historyviewplugin.h" #include "historyviewplugin.h"
#include "historyview.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ HistoryViewPlugin::HistoryViewPlugin(QObject * parent): QObject(parent) {
void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString HistoryViewPlugin::domXml() const {
QString HistoryViewPlugin::includeFile() const { QString HistoryViewPlugin::includeFile() const {
return QLatin1String("historyview.h"); return QLatin1String("historyview.h");
} }
+3 -3
View File
@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class HistoryViewPlugin: public QObject, public QDesignerCustomWidgetInterface class HistoryViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif // HISTORYVIEWPLUGIN_H #endif // HISTORYVIEWPLUGIN_H
+4 -4
View File
@@ -1,5 +1,7 @@
#include "logview.h"
#include "logviewplugin.h" #include "logviewplugin.h"
#include "logview.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ LogViewPlugin::LogViewPlugin(QObject * parent): QObject(parent) {
void LogViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void LogViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString LogViewPlugin::domXml() const {
QString LogViewPlugin::includeFile() const { QString LogViewPlugin::includeFile() const {
return QLatin1String("logview.h"); return QLatin1String("logview.h");
} }
+3 -3
View File
@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class LogViewPlugin: public QObject, public QDesignerCustomWidgetInterface class LogViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif // LOGVIEWPLUGIN_H #endif // LOGVIEWPLUGIN_H
+3 -2
View File
@@ -1,4 +1,5 @@
#include "qad_application.h" #include "qad_application.h"
#include "edockwidgetplugin.h" #include "edockwidgetplugin.h"
#include "emainwindowplugin.h" #include "emainwindowplugin.h"
#include "historyviewplugin.h" #include "historyviewplugin.h"
@@ -6,14 +7,14 @@
QADApplication::QADApplication(QObject * parent): QObject(parent) { QADApplication::QADApplication(QObject * parent): QObject(parent) {
//m_widgets.append(new EDockWidgetPlugin(this)); // m_widgets.append(new EDockWidgetPlugin(this));
m_widgets.append(new EMainWindowPlugin(this)); m_widgets.append(new EMainWindowPlugin(this));
m_widgets.append(new HistoryViewPlugin(this)); m_widgets.append(new HistoryViewPlugin(this));
m_widgets.append(new LogViewPlugin(this)); m_widgets.append(new LogViewPlugin(this));
} }
QList<QDesignerCustomWidgetInterface * > QADApplication::customWidgets() const { QList<QDesignerCustomWidgetInterface *> QADApplication::customWidgets() const {
return m_widgets; return m_widgets;
} }
+7 -6
View File
@@ -1,23 +1,24 @@
#ifndef QAD_APPLICATION_H #ifndef QAD_APPLICATION_H
#define QAD_APPLICATION_H #define QAD_APPLICATION_H
#include <QtDesigner/QtDesigner>
#include <QtCore/qplugin.h> #include <QtCore/qplugin.h>
#include <QtDesigner/QtDesigner>
class QADApplication: public QObject, public QDesignerCustomWidgetCollectionInterface class QADApplication
{ : public QObject
, public QDesignerCustomWidgetCollectionInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "qad.application") Q_PLUGIN_METADATA(IID "qad.application")
#endif #endif
public: public:
explicit QADApplication(QObject * parent = 0); explicit QADApplication(QObject * parent = 0);
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const; virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
private: private:
QList<QDesignerCustomWidgetInterface * > m_widgets; QList<QDesignerCustomWidgetInterface *> m_widgets;
}; };
#endif // QAD_APPLICATION_H #endif // QAD_APPLICATION_H
+12 -13
View File
@@ -1,6 +1,7 @@
#include <QDebug>
#include "qsingleapplication.h" #include "qsingleapplication.h"
#include <QDebug>
#define QSA_SHMSIZE 4096 #define QSA_SHMSIZE 4096
#define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32)) #define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32))
@@ -9,12 +10,11 @@
QSingleApplication::QSingleApplication(const QString & app_name): QThread() { QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
shm.setKey(app_name); shm.setKey(app_name);
exiting = false; exiting = false;
first = !shm.attach(); first = !shm.attach();
if (!first) { if (!first) {
shm.detach(); shm.detach();
first = !shm.attach(); first = !shm.attach();
if (!first) if (!first) return;
return;
} }
shm.create(QSA_SHMSIZE); shm.create(QSA_SHMSIZE);
shm.attach(); shm.attach();
@@ -23,7 +23,7 @@ QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
if (d) memset(d, 0, sizeof(quint32)); if (d) memset(d, 0, sizeof(quint32));
shm.unlock(); shm.unlock();
start(); start();
//qDebug() << "start listen"; // qDebug() << "start listen";
} }
@@ -31,15 +31,14 @@ QSingleApplication::~QSingleApplication() {
if (first) { if (first) {
exiting = true; exiting = true;
quit(); quit();
if (!wait(100)) if (!wait(100)) terminate();
terminate();
} }
if (shm.isAttached()) shm.detach(); if (shm.isAttached()) shm.detach();
} }
void QSingleApplication::sendMessage(const QByteArray & m) { void QSingleApplication::sendMessage(const QByteArray & m) {
//qDebug() << "send message" << first << shm.isAttached(); // qDebug() << "send message" << first << shm.isAttached();
if (first || !shm.isAttached()) return; if (first || !shm.isAttached()) return;
if (m.size() > int(QSA_MSGSIZE)) { if (m.size() > int(QSA_MSGSIZE)) {
qDebug() << "[QSingleApplication] Too large message:" << m.size() << ">" << QSA_MSGSIZE; qDebug() << "[QSingleApplication] Too large message:" << m.size() << ">" << QSA_MSGSIZE;
@@ -52,8 +51,8 @@ void QSingleApplication::sendMessage(const QByteArray & m) {
memcpy(&num, d, sizeof(quint32)); memcpy(&num, d, sizeof(quint32));
num++; num++;
memcpy(d, &num, sizeof(quint32)); memcpy(d, &num, sizeof(quint32));
memcpy((((char*)d) + sizeof(quint32)), &size, sizeof(quint32)); memcpy((((char *)d) + sizeof(quint32)), &size, sizeof(quint32));
memcpy((((char*)d) + sizeof(quint32) + sizeof(quint32)), m.constData(), size); memcpy((((char *)d) + sizeof(quint32) + sizeof(quint32)), m.constData(), size);
} }
shm.unlock(); shm.unlock();
} }
@@ -68,12 +67,12 @@ void QSingleApplication::run() {
memcpy(&num, d, sizeof(quint32)); memcpy(&num, d, sizeof(quint32));
if (pnum != num) { if (pnum != num) {
pnum = num; pnum = num;
//qDebug() << "new message" << num; // qDebug() << "new message" << num;
memcpy(&size, (((const char*)d) + sizeof(quint32)), sizeof(quint32)); memcpy(&size, (((const char *)d) + sizeof(quint32)), sizeof(quint32));
if (size <= int(QSA_MSGSIZE)) { if (size <= int(QSA_MSGSIZE)) {
QByteArray msg; QByteArray msg;
msg.resize(size); msg.resize(size);
memcpy(msg.data(), (((const char*)d) + sizeof(quint32) + sizeof(quint32)), size); memcpy(msg.data(), (((const char *)d) + sizeof(quint32) + sizeof(quint32)), size);
emit messageReceived(msg); emit messageReceived(msg);
} else { } else {
qDebug() << "[QSingleApplication] Invalid message size:" << size; qDebug() << "[QSingleApplication] Invalid message size:" << size;
+18 -18
View File
@@ -1,38 +1,39 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef QSINGLEAPPLICATION_H #ifndef QSINGLEAPPLICATION_H
#define QSINGLEAPPLICATION_H #define QSINGLEAPPLICATION_H
#include <QThread>
#include <QSharedMemory>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QSharedMemory>
#include <QThread>
class QAD_APPLICATION_EXPORT QSingleApplication: public QThread
{ class QAD_APPLICATION_EXPORT QSingleApplication: public QThread {
Q_OBJECT Q_OBJECT
public: public:
QSingleApplication(const QString & app_name = QString("qapp")); QSingleApplication(const QString & app_name = QString("qapp"));
~QSingleApplication(); ~QSingleApplication();
bool isFirst() const {return first;} bool isFirst() const { return first; }
private: private:
void run(); void run();
@@ -45,7 +46,6 @@ public slots:
signals: signals:
void messageReceived(QByteArray); void messageReceived(QByteArray);
}; };
#endif // QSINGLEAPPLICATION_H #endif // QSINGLEAPPLICATION_H
+51 -59
View File
@@ -1,49 +1,45 @@
#include "ribbon.h" #include "ribbon.h"
#include "qad_types.h" #include "qad_types.h"
#include <QScrollBar> #include <QScrollBar>
Ribbon::Ribbon(QMainWindow * parent_): QToolBar() { Ribbon::Ribbon(QMainWindow * parent_): QToolBar() {
tab = 0; tab = 0;
scroll_area = 0; scroll_area = 0;
delay_e = true; delay_e = true;
delay = 1000; delay = 1000;
hovered = -1; hovered = -1;
setObjectName("ribbon"); setObjectName("ribbon");
setProperty("ribbon", true); setProperty("ribbon", true);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
parent = parent_; parent = parent_;
if (parent_) if (parent_) parent_->installEventFilter(this);
parent_->installEventFilter(this);
init(); init();
} }
Ribbon::~Ribbon() { Ribbon::~Ribbon() {}
}
bool Ribbon::eventFilter(QObject * o, QEvent * e) { bool Ribbon::eventFilter(QObject * o, QEvent * e) {
//qDebug() << e; // qDebug() << e;
if (o == parent) { if (o == parent) {
if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate) if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate) _resize();
_resize(); if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) _setIconsSize();
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish)
_setIconsSize();
return QToolBar::eventFilter(o, e); return QToolBar::eventFilter(o, e);
} }
if (e->type() == QEvent::ActionChanged) { if (e->type() == QEvent::ActionChanged) {
QToolButton * b = qobject_cast<QToolButton * >((QObject * )o->property("ribbonButton").toLongLong()); QToolButton * b = qobject_cast<QToolButton *>((QObject *)o->property("ribbonButton").toLongLong());
if (b != 0) if (b != 0) b->setEnabled(qobject_cast<QAction *>(o)->isEnabled());
b->setEnabled(qobject_cast<QAction * >(o)->isEnabled());
} }
return QToolBar::eventFilter(o, e); return QToolBar::eventFilter(o, e);
} }
void Ribbon::timerEvent(QTimerEvent * e) { void Ribbon::timerEvent(QTimerEvent * e) {
if (hovers.value(e->timerId(), -1) == hovered) if (hovers.value(e->timerId(), -1) == hovered) tab->setCurrentIndex(hovered);
tab->setCurrentIndex(hovered);
hovers.remove(e->timerId()); hovers.remove(e->timerId());
killTimer(e->timerId()); killTimer(e->timerId());
} }
@@ -52,11 +48,8 @@ void Ribbon::timerEvent(QTimerEvent * e) {
void Ribbon::changeEvent(QEvent * e) { void Ribbon::changeEvent(QEvent * e) {
QToolBar::changeEvent(e); QToolBar::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: retranslate(); break;
retranslate(); default: break;
break;
default:
break;
} }
} }
@@ -64,16 +57,16 @@ void Ribbon::changeEvent(QEvent * e) {
void Ribbon::_resize() { void Ribbon::_resize() {
return; // WARNING return; // WARNING
for (int i = 0; i < tab->count(); ++i) { for (int i = 0; i < tab->count(); ++i) {
int h = ((QScrollArea*)(tab->widget(i)))->sizeHint().height(); int h = ((QScrollArea *)(tab->widget(i)))->sizeHint().height();
if (((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->isVisible()) if (((QScrollArea *)(tab->widget(i)))->horizontalScrollBar()->isVisible())
h += ((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->height(); h += ((QScrollArea *)(tab->widget(i)))->horizontalScrollBar()->height();
((QScrollArea*)(tab->widget(i)))->setMinimumHeight(h); ((QScrollArea *)(tab->widget(i)))->setMinimumHeight(h);
} }
} }
void Ribbon::_setIconsSize() { void Ribbon::_setIconsSize() {
//qDebug() << "resize" << preferredIconSize() << QApplication::font(); // qDebug() << "resize" << preferredIconSize() << QApplication::font();
setTabIconSize(preferredIconSize(2, this)); setTabIconSize(preferredIconSize(2, this));
setIconSize(preferredIconSize(3, this)); setIconSize(preferredIconSize(3, this));
} }
@@ -86,7 +79,6 @@ void Ribbon::_setButtonText(QToolButton * b, QAction * a) {
sc += "\n" + s.toString(QKeySequence::NativeText); sc += "\n" + s.toString(QKeySequence::NativeText);
} }
b->setToolTip(a->text() + sc); b->setToolTip(a->text() + sc);
} }
@@ -101,11 +93,10 @@ void Ribbon::setVisible(bool yes) {
void Ribbon::init() { void Ribbon::init() {
if (parent == 0) return; if (parent == 0) return;
if (parent->menuBar() == 0) return; if (parent->menuBar() == 0) return;
QList<QAction * > lm = parent->menuBar()->actions(), la; QList<QAction *> lm = parent->menuBar()->actions(), la;
QString prev_tab; QString prev_tab;
if (tab) { if (tab) {
if (tab->currentIndex() >= 0) if (tab->currentIndex() >= 0) prev_tab = tab->tabText(tab->currentIndex());
prev_tab = tab->tabText(tab->currentIndex());
tab->deleteLater(); tab->deleteLater();
} }
clear(); clear();
@@ -117,24 +108,24 @@ void Ribbon::init() {
connect(tab, SIGNAL(currentChanged(int)), this, SIGNAL(currentTabChanged(int))); connect(tab, SIGNAL(currentChanged(int)), this, SIGNAL(currentTabChanged(int)));
tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QFrame * g; QFrame * g;
QBoxLayout * l, * tl; QBoxLayout *l, *tl;
QToolButton * b; QToolButton * b;
//tab->setIconSize(QSize(32, 32)); // tab->setIconSize(QSize(32, 32));
for (QAction * i: lm) { for (QAction * i: lm) {
if (!i->menu()) continue; if (!i->menu()) continue;
//if (!i->menu()->isVisible()) continue; // if (!i->menu()->isVisible()) continue;
la = i->menu()->actions(); la = i->menu()->actions();
QIcon tic = i->icon(); QIcon tic = i->icon();
if (!tic.isNull()) if (!tic.isNull())
i->setProperty("__icon", QVariant::fromValue<QIcon>(tic)); i->setProperty("__icon", QVariant::fromValue<QIcon>(tic));
else else
tic = i->property("__icon").value<QIcon>(); tic = i->property("__icon").value<QIcon>();
//#ifdef Q_OS_MACOS // #ifdef Q_OS_MACOS
// tic = QIcon(); // tic = QIcon();
//#endif // #endif
tab->addTab(new QWidget(), tic, i->text()); tab->addTab(new QWidget(), tic, i->text());
//qDebug() << this << i->icon() << i->text(); // qDebug() << this << i->icon() << i->text();
//continue; // continue;
/*QScrollArea * sa = new QScrollArea(); /*QScrollArea * sa = new QScrollArea();
sa->setWidget(new QWidget()); sa->setWidget(new QWidget());
sa->setWidgetResizable(true); sa->setWidgetResizable(true);
@@ -143,7 +134,7 @@ void Ribbon::init() {
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
sa->setFrameShape(QFrame::NoFrame); sa->setFrameShape(QFrame::NoFrame);
tab->addTab(sa, i->icon(), i->text());*/ tab->addTab(sa, i->icon(), i->text());*/
tab->widget(tab->count() - 1)->setProperty("ribbonAction", qlonglong((void * )i)); tab->widget(tab->count() - 1)->setProperty("ribbonAction", qlonglong((void *)i));
i->setIcon(QIcon()); i->setIcon(QIcon());
tl = new QBoxLayout(QBoxLayout::LeftToRight); tl = new QBoxLayout(QBoxLayout::LeftToRight);
tl->setSpacing(2); tl->setSpacing(2);
@@ -152,7 +143,8 @@ void Ribbon::init() {
#else #else
tl->setContentsMargins(2, 0, 2, 2); tl->setContentsMargins(2, 0, 2, 2);
#endif #endif
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel); g = new QFrame();
g->setFrameShape(QFrame::StyledPanel);
l = new QBoxLayout(QBoxLayout::LeftToRight); l = new QBoxLayout(QBoxLayout::LeftToRight);
g->setLayout(l); g->setLayout(l);
l->setSpacing(2); l->setSpacing(2);
@@ -161,24 +153,25 @@ void Ribbon::init() {
if (j->isSeparator()) { if (j->isSeparator()) {
if (l->isEmpty()) continue; if (l->isEmpty()) continue;
tl->addWidget(g); tl->addWidget(g);
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel); g = new QFrame();
g->setFrameShape(QFrame::StyledPanel);
l = new QBoxLayout(QBoxLayout::LeftToRight); l = new QBoxLayout(QBoxLayout::LeftToRight);
l->setSpacing(2); l->setSpacing(2);
l->setContentsMargins(2, 2, 2, 2); l->setContentsMargins(2, 2, 2, 2);
g->setLayout(l); g->setLayout(l);
continue; continue;
} }
if (qobject_cast<QWidgetAction*>(j)) { if (qobject_cast<QWidgetAction *>(j)) {
QWidget * _w = qobject_cast<QWidgetAction*>(j)->defaultWidget(); QWidget * _w = qobject_cast<QWidgetAction *>(j)->defaultWidget();
l->addWidget(_w); l->addWidget(_w);
_w->show(); _w->show();
continue; continue;
} }
b = new QToolButton(); b = new QToolButton();
//b->setVisible(j->isVisible()); // b->setVisible(j->isVisible());
b->setEnabled(j->isEnabled()); b->setEnabled(j->isEnabled());
b->setProperty("ribbonAction", qlonglong((void * )j)); b->setProperty("ribbonAction", qlonglong((void *)j));
j->setProperty("ribbonButton", qlonglong((void * )b)); j->setProperty("ribbonButton", qlonglong((void *)b));
j->installEventFilter(this); j->installEventFilter(this);
if (j->menu() != 0) { if (j->menu() != 0) {
b->setPopupMode(QToolButton::InstantPopup); b->setPopupMode(QToolButton::InstantPopup);
@@ -193,11 +186,11 @@ void Ribbon::init() {
} else } else
connect(b, SIGNAL(clicked()), j, SLOT(trigger())); connect(b, SIGNAL(clicked()), j, SLOT(trigger()));
} }
//b->setIconSize(QSize(16, 16)); // b->setIconSize(QSize(16, 16));
b->setIcon(j->icon()); b->setIcon(j->icon());
_setButtonText(b, j); _setButtonText(b, j);
//b->addAction(j); // b->addAction(j);
//b->setShortcut(j->shortcut()); // b->setShortcut(j->shortcut());
b->setAutoRaise(true); b->setAutoRaise(true);
b->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); b->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
@@ -206,10 +199,9 @@ void Ribbon::init() {
} }
tl->addWidget(g); tl->addWidget(g);
tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed)); tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
//sa->widget()->setLayout(tl); // sa->widget()->setLayout(tl);
tab->widget(tab->count() - 1)->setLayout(tl); tab->widget(tab->count() - 1)->setLayout(tl);
if (i->text() == prev_tab) if (i->text() == prev_tab) tab->setCurrentIndex(tab->count() - 1);
tab->setCurrentIndex(tab->count() - 1);
} }
setFloatable(false); setFloatable(false);
setMovable(false); setMovable(false);
@@ -219,7 +211,7 @@ void Ribbon::init() {
scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scroll_area->setWidget(tab);*/ scroll_area->setWidget(tab);*/
_resize(); _resize();
//addWidget(scroll_area); // addWidget(scroll_area);
addWidget(tab); addWidget(tab);
parent->addToolBar(Qt::TopToolBarArea, this); parent->addToolBar(Qt::TopToolBarArea, this);
parent->menuBar()->hide(); parent->menuBar()->hide();
@@ -231,13 +223,13 @@ void Ribbon::init() {
void Ribbon::retranslate() { void Ribbon::retranslate() {
QAction * a; QAction * a;
for (QToolButton * i: buttons) { for (QToolButton * i: buttons) {
a = (QAction * )(i->property("ribbonAction").toLongLong()); a = (QAction *)(i->property("ribbonAction").toLongLong());
if (a == 0) continue; if (a == 0) continue;
_setButtonText(i, a); _setButtonText(i, a);
//i->setShortcut(a->shortcut()); // i->setShortcut(a->shortcut());
} }
for (int i = 0; i < tab->count(); ++i) { for (int i = 0; i < tab->count(); ++i) {
a = (QAction * )(tab->widget(i)->property("ribbonAction").toLongLong()); a = (QAction *)(tab->widget(i)->property("ribbonAction").toLongLong());
if (a == 0) continue; if (a == 0) continue;
tab->setTabText(i, a->text()); tab->setTabText(i, a->text());
} }
+48 -37
View File
@@ -1,42 +1,43 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef RIBBON_H #ifndef RIBBON_H
#define RIBBON_H #define RIBBON_H
#include <QMainWindow>
#include <QActionGroup>
#include <QWidgetAction>
#include <QMenuBar>
#include <QTabWidget>
#include <QGroupBox>
#include <QDockWidget>
#include <QToolBar>
#include <QToolButton>
#include <QScrollArea>
#include "etabwidget.h" #include "etabwidget.h"
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QActionGroup>
#include <QDockWidget>
#include <QGroupBox>
#include <QMainWindow>
#include <QMenuBar>
#include <QScrollArea>
#include <QTabWidget>
#include <QToolBar>
#include <QToolButton>
#include <QWidgetAction>
class QAD_APPLICATION_EXPORT Ribbon: public QToolBar
{ class QAD_APPLICATION_EXPORT Ribbon: public QToolBar {
Q_OBJECT Q_OBJECT
public: public:
explicit Ribbon(QMainWindow * parent = 0); explicit Ribbon(QMainWindow * parent = 0);
~Ribbon(); ~Ribbon();
@@ -45,41 +46,51 @@ public:
void retranslate(); void retranslate();
void setIconSize(const QSize & size); void setIconSize(const QSize & size);
void setTabIconSize(const QSize & size); void setTabIconSize(const QSize & size);
void setButtonStyle(const Qt::ToolButtonStyle & style) {foreach (QToolButton * i, buttons) i->setToolButtonStyle(style);} void setButtonStyle(const Qt::ToolButtonStyle & style) {
void setAutoSwitchEnabled(bool yes) {delay_e = yes;} foreach(QToolButton * i, buttons)
void setAutoSwitchDelay(float delay_s) {delay = delay_s * 1000;} i->setToolButtonStyle(style);
void setCurrentTab(int tab_) {if (tab_ < 0 || tab_ >= tab->count()) return; tab->setCurrentIndex(tab_);} }
int currentTab() const {return tab->currentIndex();} void setAutoSwitchEnabled(bool yes) { delay_e = yes; }
QTabWidget * tabWidget() const {return tab;} void setAutoSwitchDelay(float delay_s) { delay = delay_s * 1000; }
void setCurrentTab(int tab_) {
if (tab_ < 0 || tab_ >= tab->count()) return;
tab->setCurrentIndex(tab_);
}
int currentTab() const { return tab->currentIndex(); }
QTabWidget * tabWidget() const { return tab; }
private: private:
bool eventFilter(QObject * o, QEvent * e); bool eventFilter(QObject * o, QEvent * e);
void timerEvent(QTimerEvent * e); void timerEvent(QTimerEvent * e);
void changeEvent(QEvent *e); void changeEvent(QEvent * e);
void _resize(); void _resize();
void _setIconsSize(); void _setIconsSize();
void _setButtonText(QToolButton * b, QAction * a); void _setButtonText(QToolButton * b, QAction * a);
int hovered, delay; int hovered, delay;
bool delay_e; bool delay_e;
QList<QToolButton * > buttons; QList<QToolButton *> buttons;
QMap<int, int> hovers; QMap<int, int> hovers;
ETabWidget * tab; ETabWidget * tab;
QScrollArea * scroll_area; QScrollArea * scroll_area;
QMainWindow * parent; QMainWindow * parent;
private slots: private slots:
void tabHovered(int tab) {if (!delay_e) return; hovers.clear(); hovered = tab; hovers.insert(startTimer(delay), tab);} void tabHovered(int tab) {
if (!delay_e) return;
hovers.clear();
hovered = tab;
hovers.insert(startTimer(delay), tab);
}
public slots: public slots:
void setVisible(bool yes); void setVisible(bool yes);
void setHidden(bool yes) {setVisible(!yes);} void setHidden(bool yes) { setVisible(!yes); }
void show() {setVisible(true);} void show() { setVisible(true); }
void hide() {setVisible(false);} void hide() { setVisible(false); }
signals: signals:
void currentTabChanged(int); void currentTabChanged(int);
}; };
#endif // RIBBON_H #endif // RIBBON_H
+4 -2
View File
@@ -1,8 +1,10 @@
#include "alignedtextitem.h" #include "alignedtextitem.h"
#include "blockbase.h" #include "blockbase.h"
#include <QApplication> #include <QApplication>
#include <QPainter>
#include <QDebug> #include <QDebug>
#include <QPainter>
AlignedTextItem::AlignedTextItem(QGraphicsItem * parent): QGraphicsItem(parent), text_(this) { AlignedTextItem::AlignedTextItem(QGraphicsItem * parent): QGraphicsItem(parent), text_(this) {
@@ -28,7 +30,7 @@ void AlignedTextItem::setFont(const QFont & f) {
QFont AlignedTextItem::sceneFont(const QFont & f) { QFont AlignedTextItem::sceneFont(const QFont & f) {
QFont ret = f; QFont ret = f;
double scl = 16. / fontHeight(); double scl = 16. / fontHeight();
ret.setPointSizeF(ret.pointSizeF() * scl); ret.setPointSizeF(ret.pointSizeF() * scl);
return ret; return ret;
+44 -30
View File
@@ -1,30 +1,31 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef ALIGNEDTEXTITEM_H #ifndef ALIGNEDTEXTITEM_H
#define ALIGNEDTEXTITEM_H #define ALIGNEDTEXTITEM_H
#include <QGraphicsSimpleTextItem> #include "qad_blockview_export.h"
#include <QPen>
#include <QBrush> #include <QBrush>
#include <QFont> #include <QFont>
#include "qad_blockview_export.h" #include <QGraphicsSimpleTextItem>
#include <QPen>
class QAD_BLOCKVIEW_EXPORT AlignedTextItem: public QGraphicsItem { class QAD_BLOCKVIEW_EXPORT AlignedTextItem: public QGraphicsItem {
@@ -32,36 +33,49 @@ public:
AlignedTextItem(QGraphicsItem * parent = 0); AlignedTextItem(QGraphicsItem * parent = 0);
AlignedTextItem(const QString & text, QGraphicsItem * parent = 0); AlignedTextItem(const QString & text, QGraphicsItem * parent = 0);
void setText(const QString & t) {text_.setText(t); _move();} void setText(const QString & t) {
text_.setText(t);
_move();
}
void setFont(const QFont & f); void setFont(const QFont & f);
void setPen(const QPen & p) {text_.setPen(p); _move();} void setPen(const QPen & p) {
void setBrush(const QBrush & b) {text_.setBrush(b); _move();} text_.setPen(p);
void setAlignment(Qt::Alignment align) {align_ = align; _move();} _move();
}
void setBrush(const QBrush & b) {
text_.setBrush(b);
_move();
}
void setAlignment(Qt::Alignment align) {
align_ = align;
_move();
}
QString text() const {return text_.text();} QString text() const { return text_.text(); }
QFont font() const {return font_;} QFont font() const { return font_; }
QPen pen() const {return text_.pen();} QPen pen() const { return text_.pen(); }
QBrush brush() const {return text_.brush();} QBrush brush() const { return text_.brush(); }
Qt::Alignment alignment() const {return align_;} Qt::Alignment alignment() const { return align_; }
void clear() {setText(QString());} void clear() { setText(QString()); }
enum {Type = UserType + 0x100}; enum {
Type = UserType + 0x100
};
static QFont sceneFont(const QFont & f); static QFont sceneFont(const QFont & f);
protected: protected:
virtual QRectF boundingRect() const {return text_.boundingRect().translated(text_.pos());} virtual QRectF boundingRect() const { return text_.boundingRect().translated(text_.pos()); }
virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0); virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);
virtual int type() const {return Type;} virtual int type() const { return Type; }
void _move() {text_.setPos(-_point(align_));} void _move() { text_.setPos(-_point(align_)); }
QPointF _point(Qt::Alignment a) const; QPointF _point(Qt::Alignment a) const;
QGraphicsSimpleTextItem text_; QGraphicsSimpleTextItem text_;
Qt::Alignment align_; Qt::Alignment align_;
QFont font_; QFont font_;
}; };
+160 -50
View File
@@ -1,20 +1,21 @@
#include "blockbase.h" #include "blockbase.h"
#include "alignedtextitem.h" #include "alignedtextitem.h"
#include "qvariantedit.h" #include "qvariantedit.h"
QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) { QDataStream & operator<<(QDataStream & s, const QGraphicsItem * item) {
if (!item) { if (!item) {
s << int(-1); s << int(-1);
return s; return s;
} }
const QGraphicsRectItem * irect = qgraphicsitem_cast<const QGraphicsRectItem*>(item); const QGraphicsRectItem * irect = qgraphicsitem_cast<const QGraphicsRectItem *>(item);
const QGraphicsEllipseItem * iell = qgraphicsitem_cast<const QGraphicsEllipseItem*>(item); const QGraphicsEllipseItem * iell = qgraphicsitem_cast<const QGraphicsEllipseItem *>(item);
const QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<const QGraphicsSimpleTextItem*>(item); const QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<const QGraphicsSimpleTextItem *>(item);
const AlignedTextItem * iatext = qgraphicsitem_cast<const AlignedTextItem*>(item); const AlignedTextItem * iatext = qgraphicsitem_cast<const AlignedTextItem *>(item);
const QGraphicsLineItem * iline = qgraphicsitem_cast<const QGraphicsLineItem*>(item); const QGraphicsLineItem * iline = qgraphicsitem_cast<const QGraphicsLineItem *>(item);
const QGraphicsPathItem * ipath = qgraphicsitem_cast<const QGraphicsPathItem*>(item); const QGraphicsPathItem * ipath = qgraphicsitem_cast<const QGraphicsPathItem *>(item);
const QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<const QGraphicsPixmapItem*>(item); const QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<const QGraphicsPixmapItem *>(item);
if (irect) { if (irect) {
s << int(0) << (irect->pen()) << (irect->brush()) << (irect->rect()); s << int(0) << (irect->pen()) << (irect->brush()) << (irect->rect());
} else if (iell) { } else if (iell) {
@@ -38,72 +39,181 @@ QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
} }
QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item) { QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item) {
int type_; s >> type_; int type_;
s >> type_;
if (type_ < 0) { if (type_ < 0) {
item = 0; item = 0;
return s; return s;
} }
QGraphicsRectItem * nrect = 0; QGraphicsRectItem * nrect = 0;
QGraphicsEllipseItem * nell = 0; QGraphicsEllipseItem * nell = 0;
QGraphicsSimpleTextItem * ntext = 0; QGraphicsSimpleTextItem * ntext = 0;
AlignedTextItem * natext = 0; AlignedTextItem * natext = 0;
QGraphicsLineItem * nline = 0; QGraphicsLineItem * nline = 0;
QGraphicsPathItem * npath = 0; QGraphicsPathItem * npath = 0;
QGraphicsPixmapItem * npixmap = 0; QGraphicsPixmapItem * npixmap = 0;
item = 0; item = 0;
switch (type_) { switch (type_) {
case 0: case 0:
nrect = new QGraphicsRectItem(); item = nrect; nrect = new QGraphicsRectItem();
{QPen _v; s >> _v; nrect->setPen(_v);} item = nrect;
{QBrush _v; s >> _v; nrect->setBrush(_v);} {
{QRectF _v; s >> _v; nrect->setRect(_v);} QPen _v;
s >> _v;
nrect->setPen(_v);
}
{
QBrush _v;
s >> _v;
nrect->setBrush(_v);
}
{
QRectF _v;
s >> _v;
nrect->setRect(_v);
}
break; break;
case 1: case 1:
nell = new QGraphicsEllipseItem(); item = nell; nell = new QGraphicsEllipseItem();
{QPen _v; s >> _v; nell->setPen(_v);} item = nell;
{QBrush _v; s >> _v; nell->setBrush(_v);} {
{QRectF _v; s >> _v; nell->setRect(_v);} QPen _v;
s >> _v;
nell->setPen(_v);
}
{
QBrush _v;
s >> _v;
nell->setBrush(_v);
}
{
QRectF _v;
s >> _v;
nell->setRect(_v);
}
break; break;
case 2: case 2:
ntext = new QGraphicsSimpleTextItem(); item = ntext; ntext = new QGraphicsSimpleTextItem();
{QPen _v; s >> _v; ntext->setPen(_v);} item = ntext;
{QBrush _v; s >> _v; ntext->setBrush(_v);} {
{QFont _v; s >> _v; ntext->setFont(_v);} QPen _v;
{QString _v; s >> _v; ntext->setText(_v);} s >> _v;
ntext->setPen(_v);
}
{
QBrush _v;
s >> _v;
ntext->setBrush(_v);
}
{
QFont _v;
s >> _v;
ntext->setFont(_v);
}
{
QString _v;
s >> _v;
ntext->setText(_v);
}
break; break;
case 6: case 6:
natext = new AlignedTextItem(); item = natext; natext = new AlignedTextItem();
{QPen _v; s >> _v; natext->setPen(_v);} item = natext;
{QBrush _v; s >> _v; natext->setBrush(_v);} {
{QFont _v; s >> _v; natext->setFont(_v);} QPen _v;
{QString _v; s >> _v; natext->setText(_v);} s >> _v;
{int _v; s >> _v; natext->setAlignment((Qt::AlignmentFlag)_v);} natext->setPen(_v);
}
{
QBrush _v;
s >> _v;
natext->setBrush(_v);
}
{
QFont _v;
s >> _v;
natext->setFont(_v);
}
{
QString _v;
s >> _v;
natext->setText(_v);
}
{
int _v;
s >> _v;
natext->setAlignment((Qt::AlignmentFlag)_v);
}
break; break;
case 3: case 3:
nline = new QGraphicsLineItem(); item = nline; nline = new QGraphicsLineItem();
{QPen _v; s >> _v; nline->setPen(_v);} item = nline;
{QLineF _v; s >> _v; nline->setLine(_v);} {
QPen _v;
s >> _v;
nline->setPen(_v);
}
{
QLineF _v;
s >> _v;
nline->setLine(_v);
}
break; break;
case 4: case 4:
npath = new QGraphicsPathItem(); item = npath; npath = new QGraphicsPathItem();
{QPen _v; s >> _v; npath->setPen(_v);} item = npath;
{QPainterPath _v; s >> _v; npath->setPath(_v);} {
QPen _v;
s >> _v;
npath->setPen(_v);
}
{
QPainterPath _v;
s >> _v;
npath->setPath(_v);
}
break; break;
case 5: case 5:
npixmap = new QGraphicsPixmapItem(); item = npixmap; npixmap = new QGraphicsPixmapItem();
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);} item = npixmap;
{
QPixmap _v;
s >> _v;
npixmap->setPixmap(_v);
}
break; break;
case 7: case 7:
npixmap = new QGraphicsPixmapItem(); item = npixmap; npixmap = new QGraphicsPixmapItem();
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);} item = npixmap;
{QTransform _t; s >> _t; npixmap->setTransform(_t);} {
QPixmap _v;
s >> _v;
npixmap->setPixmap(_v);
}
{
QTransform _t;
s >> _t;
npixmap->setTransform(_t);
}
break; break;
} }
if (item) { if (item) {
{QPointF _v; s >> _v; item->setPos(_v);} {
{qreal _v; s >> _v; item->setRotation(_v);} QPointF _v;
{int _v; s >> _v; item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);} s >> _v;
item->setPos(_v);
}
{
qreal _v;
s >> _v;
item->setRotation(_v);
}
{
int _v;
s >> _v;
item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);
}
} }
return s; return s;
} }
+33 -34
View File
@@ -1,52 +1,53 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKBASE_H #ifndef BLOCKBASE_H
#define BLOCKBASE_H #define BLOCKBASE_H
#include <QGraphicsView> #include "qad_blockview_export.h"
#include <QGraphicsScene> #include "qad_types.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QGraphicsEllipseItem> #include <QGraphicsScene>
#include <QGraphicsSceneHoverEvent> #include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QStack> #include <QStack>
#include "qad_types.h"
#include "qad_blockview_export.h"
static const int _blockitem_current_version_ = 1; static const int _blockitem_current_version_ = 1;
enum BlockviewItemData { enum BlockviewItemData {
bvidSelected = 1000, // bool bvidSelected = 1000, // bool
bvidType , // BlockviewItemType bvidType, // BlockviewItemType
bvidItemPos , // QPointF bvidItemPos, // QPointF
bvidDecorText , // QString src text for QGraphicsSimpleTextItem bvidDecorText, // QString src text for QGraphicsSimpleTextItem
bvidMoveParent , // bool flag for move parent bvidMoveParent, // bool flag for move parent
bvidVisualizeSelection , // bool flag for visualize selection bvidVisualizeSelection, // bool flag for visualize selection
bvidItemSelection , // bool BlockItem selection bvidItemSelection, // bool BlockItem selection
bvidTmpItem , // bool item is temporary, ignore bvidTmpItem, // bool item is temporary, ignore
bvidBlockDecor , // bool item is BlockItem decor bvidBlockDecor, // bool item is BlockItem decor
bvidDTHandle , // bool bvidDTHandle, // bool
bvidCorrectMove , // bool bvidCorrectMove, // bool
}; };
enum BlockviewItemType { enum BlockviewItemType {
@@ -57,16 +58,15 @@ enum BlockviewItemType {
bvitDecor, bvitDecor,
}; };
QAD_BLOCKVIEW_EXPORT QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item); QAD_BLOCKVIEW_EXPORT QDataStream & operator<<(QDataStream & s, const QGraphicsItem * item);
QAD_BLOCKVIEW_EXPORT QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item); QAD_BLOCKVIEW_EXPORT QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item);
class QAD_BLOCKVIEW_EXPORT BlockItemBase: public QObject class QAD_BLOCKVIEW_EXPORT BlockItemBase: public QObject {
{
Q_OBJECT Q_OBJECT
Q_ENUMS(Action) Q_ENUMS(Action)
public:
public:
enum Action { enum Action {
BlockAdd = 1, BlockAdd = 1,
BlockMove, BlockMove,
@@ -82,7 +82,6 @@ public:
BusSegmentRemove, BusSegmentRemove,
Paste Paste
}; };
}; };
#endif // BLOCKBASE_H #endif // BLOCKBASE_H
+154 -144
View File
@@ -1,12 +1,15 @@
#include "blockview.h" #include "blockview.h"
#include <QApplication> #include <QApplication>
BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() { BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() {
temp_ = temp; temp_ = temp;
_init(); _init();
if (!temp) setData(bvidType, bvitBus); if (!temp)
else hide(); setData(bvidType, bvitBus);
else
hide();
} }
@@ -17,12 +20,12 @@ BlockBusItem::BlockBusItem(const BlockBusItem & other): QGraphicsObject(), Prope
setPen(other.pen()); setPen(other.pen());
setBrush(other.brush()); setBrush(other.brush());
setBusType(other.busType()); setBusType(other.busType());
square_node = other.square_node; square_node = other.square_node;
max_ep = other.max_ep; max_ep = other.max_ep;
pol = other.pol; pol = other.pol;
segments = other.segments; segments = other.segments;
im_bus = other.im_bus; im_bus = other.im_bus;
im_end = other.im_end; im_end = other.im_end;
im_bus_scale = other.im_bus_scale; im_bus_scale = other.im_bus_scale;
im_end_scale = other.im_end_scale; im_end_scale = other.im_end_scale;
updateGeometry(); updateGeometry();
@@ -33,26 +36,34 @@ void BlockBusItem::_init() {
setZValue(1.); setZValue(1.);
setBusType(-1); setBusType(-1);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
ph.setColor(Qt::blue); ph.setJoinStyle(Qt::MiterJoin); ph.setColor(Qt::blue);
bh.setColor(Qt::blue); bh.setStyle(Qt::SolidPattern); ph.setJoinStyle(Qt::MiterJoin);
pu = pa = pr = ph; bu = ba = br = bh; bh.setColor(Qt::blue);
grid_step = 10.; bh.setStyle(Qt::SolidPattern);
pu = pa = pr = ph;
bu = ba = br = bh;
grid_step = 10.;
pu.setWidth(1); pu.setWidth(1);
pu.setColor(Qt::black); bu.setColor(Qt::black); pu.setColor(Qt::black);
pa.setColor(Qt::darkGreen); ba.setColor(Qt::darkGreen); bu.setColor(Qt::black);
pr.setColor(Qt::darkRed); br.setColor(Qt::darkRed); pa.setColor(Qt::darkGreen);
pn.setColor(Qt::gray); pn.setStyle(Qt::DashLine); ba.setColor(Qt::darkGreen);
pr.setColor(Qt::darkRed);
br.setColor(Qt::darkRed);
pn.setColor(Qt::gray);
pn.setStyle(Qt::DashLine);
if (temp_) { if (temp_) {
pu.setStyle(Qt::DashLine); pu.setStyle(Qt::DashLine);
pu.setColor(Qt::darkGray); pu.setColor(Qt::darkGray);
bu.setColor(Qt::darkGray); bu.setColor(Qt::darkGray);
} }
setPen(pu); setBrush(bu); setPen(pu);
setBrush(bu);
square_node = false; square_node = false;
max_ep = 0; max_ep = 0;
selPoint = selSegment = state_ = -1; selPoint = selSegment = state_ = -1;
pen_width = 2.; pen_width = 2.;
point_size = 3.; point_size = 3.;
im_bus_scale = im_end_scale = 1.; im_bus_scale = im_end_scale = 1.;
moved = deleted = mark_in = mark_out = new_segment = mm_cancel = lm_point = false; moved = deleted = mark_in = mark_out = new_segment = mm_cancel = lm_point = false;
anim_point_size.setTargetObject(this); anim_point_size.setTargetObject(this);
@@ -68,19 +79,19 @@ void BlockBusItem::reconnect() {
if (temp_) return; if (temp_) return;
if (!scene()) return; if (!scene()) return;
if (scene()->views().isEmpty()) return; if (scene()->views().isEmpty()) return;
qobject_cast<BlockView*>(scene()->views().back())->reconnectAll(); qobject_cast<BlockView *>(scene()->views().back())->reconnectAll();
} }
bool BlockBusItem::sceneEvent(QEvent * e) { bool BlockBusItem::sceneEvent(QEvent * e) {
if (temp_) return QGraphicsObject::sceneEvent(e); if (temp_) return QGraphicsObject::sceneEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::GraphicsSceneHoverEnter: hoverEnterEvent((QGraphicsSceneHoverEvent * )e); break; case QEvent::GraphicsSceneHoverEnter: hoverEnterEvent((QGraphicsSceneHoverEvent *)e); break;
case QEvent::GraphicsSceneHoverMove: hoverMoveEvent((QGraphicsSceneHoverEvent * )e); break; case QEvent::GraphicsSceneHoverMove: hoverMoveEvent((QGraphicsSceneHoverEvent *)e); break;
case QEvent::GraphicsSceneHoverLeave: hoverLeaveEvent((QGraphicsSceneHoverEvent * )e); break; case QEvent::GraphicsSceneHoverLeave: hoverLeaveEvent((QGraphicsSceneHoverEvent *)e); break;
case QEvent::GraphicsSceneMousePress: mousePressEvent((QGraphicsSceneMouseEvent * )e); break; case QEvent::GraphicsSceneMousePress: mousePressEvent((QGraphicsSceneMouseEvent *)e); break;
case QEvent::GraphicsSceneMouseMove: mouseMoveEvent((QGraphicsSceneMouseEvent * )e); break; case QEvent::GraphicsSceneMouseMove: mouseMoveEvent((QGraphicsSceneMouseEvent *)e); break;
case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent((QGraphicsSceneMouseEvent * )e); break; case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent((QGraphicsSceneMouseEvent *)e); break;
default: break; default: break;
} }
return QGraphicsObject::sceneEvent(e); return QGraphicsObject::sceneEvent(e);
@@ -95,7 +106,7 @@ int BlockBusItem::addPoint(const QPointF & point, bool update) {
selPoint = pol.size() - 1; selPoint = pol.size() - 1;
segments << QPair<int, int>(selPoint, segments[selSegment].second); segments << QPair<int, int>(selPoint, segments[selSegment].second);
segments[selSegment].second = selPoint; segments[selSegment].second = selPoint;
selSegment = -1; selSegment = -1;
updateGeometry(); updateGeometry();
if (scene() != 0 && update) scene()->update(); if (scene() != 0 && update) scene()->update();
return pol.size() - 1; return pol.size() - 1;
@@ -122,32 +133,33 @@ void BlockBusItem::removePoint(int index) {
if (index < 0 || index > pol.size() - 1) return; if (index < 0 || index > pol.size() - 1) return;
int sc = 0, fs = -1, ss = -1; int sc = 0, fs = -1, ss = -1;
for (int i = 0; i < segments.size(); ++i) for (int i = 0; i < segments.size(); ++i)
if (segments[i].first == index || if (segments[i].first == index || segments[i].second == index) {
segments[i].second == index) { sc++;
sc++; if (fs < 0)
if (fs < 0) fs = i; fs = i;
else ss = i; else
ss = i;
} }
int ei(0); int ei(0);
switch (sc) { switch (sc) {
case 1: case 1: segments.removeAt(fs); break;
segments.removeAt(fs);
break;
case 2: case 2:
if (segments[ss].first == index) ei = segments[ss].second; if (segments[ss].first == index)
else ei = segments[ss].first; ei = segments[ss].second;
if (segments[fs].first == index) segments[fs].first = ei; else
else segments[fs].second = ei; ei = segments[ss].first;
if (segments[fs].first == index)
segments[fs].first = ei;
else
segments[fs].second = ei;
segments.removeAt(ss); segments.removeAt(ss);
break; break;
default: return; default: return;
} }
pol.remove(index); pol.remove(index);
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (segments[i].first >= index) if (segments[i].first >= index) segments[i].first--;
segments[i].first--; if (segments[i].second >= index) segments[i].second--;
if (segments[i].second >= index)
segments[i].second--;
} }
selPoint = -1; selPoint = -1;
checkDelete(); checkDelete();
@@ -162,25 +174,19 @@ void BlockBusItem::removeSegment(int index) {
if (pif > pis) qSwap<int>(pif, pis); if (pif > pis) qSwap<int>(pif, pis);
int scf = 0, scs = 0; int scf = 0, scs = 0;
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (segments[i].first == pif || if (segments[i].first == pif || segments[i].second == pif) scf++;
segments[i].second == pif) if (segments[i].first == pis || segments[i].second == pis) scs++;
scf++;
if (segments[i].first == pis ||
segments[i].second == pis)
scs++;
} }
if (scs <= 2) removePoint(pis); if (scs <= 2) removePoint(pis);
if (scf <= 2) removePoint(pif); if (scf <= 2) removePoint(pif);
if (scs <= 2 || scf <= 2) selSegment = -1; if (scs <= 2 || scf <= 2) selSegment = -1;
if (scene() != 0) scene()->update(); if (scene() != 0) scene()->update();
} }
void BlockBusItem::appendPoint(const QPointF & p) { void BlockBusItem::appendPoint(const QPointF & p) {
pol << p; pol << p;
if (pol.size() > 1) if (pol.size() > 1) segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
updateGeometry(); updateGeometry();
} }
@@ -229,13 +235,13 @@ void BlockBusItem::setSquareNodes(bool yes) {
void BlockBusItem::markAsInput() { void BlockBusItem::markAsInput() {
mark_in = true; mark_in = true;
mark_out = false; mark_out = false;
} }
void BlockBusItem::markAsOutput() { void BlockBusItem::markAsOutput() {
mark_in = false; mark_in = false;
mark_out = true; mark_out = true;
} }
@@ -266,17 +272,23 @@ void BlockBusItem::simplify(bool full) {
int s0 = segs[0], s1 = segs[1]; int s0 = segs[0], s1 = segs[1];
QPointF cp = pol[p], sp[2]; QPointF cp = pol[p], sp[2];
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
if (segments[segs[i]].first == p) sp[i] = pol[segments[segs[i]].second]; if (segments[segs[i]].first == p)
else sp[i] = pol[segments[segs[i]].first]; sp[i] = pol[segments[segs[i]].second];
else
sp[i] = pol[segments[segs[i]].first];
} }
QLineF l0(sp[0], cp), l1(cp, sp[1]); QLineF l0(sp[0], cp), l1(cp, sp[1]);
if (qAbs(l0.angle() - l1.angle()) > 0.1) continue; if (qAbs(l0.angle() - l1.angle()) > 0.1) continue;
if (segments[s0].first == p) { if (segments[s0].first == p) {
if (segments[s1].first == p) segments[s0].first = segments[s1].second; if (segments[s1].first == p)
else segments[s0].first = segments[s1].first; segments[s0].first = segments[s1].second;
else
segments[s0].first = segments[s1].first;
} else { } else {
if (segments[s1].first == p) segments[s0].second = segments[s1].second; if (segments[s1].first == p)
else segments[s0].second = segments[s1].first; segments[s0].second = segments[s1].second;
else
segments[s0].second = segments[s1].first;
} }
segments.removeAt(s1); segments.removeAt(s1);
pol.remove(p); pol.remove(p);
@@ -292,8 +304,7 @@ void BlockBusItem::simplify(bool full) {
} }
void BlockBusItem::adjustLine() { void BlockBusItem::adjustLine() {}
}
int BlockBusItem::endpointCount() const { int BlockBusItem::endpointCount() const {
@@ -301,16 +312,16 @@ int BlockBusItem::endpointCount() const {
} }
QList<BlockItem * > BlockBusItem::connectedBlocks() const { QList<BlockItem *> BlockBusItem::connectedBlocks() const {
QList<BlockItemPin * > pins = connections_.values(); QList<BlockItemPin *> pins = connections_.values();
QSet<BlockItem * > ret; QSet<BlockItem *> ret;
foreach (BlockItemPin * p, pins) foreach(BlockItemPin * p, pins)
ret << p->parent(); ret << p->parent();
return ret.values(); return ret.values();
} }
QList<BlockItemPin * > BlockBusItem::connectedPins() const { QList<BlockItemPin *> BlockBusItem::connectedPins() const {
return connections_.values(); return connections_.values();
} }
@@ -318,14 +329,14 @@ QList<BlockItemPin * > BlockBusItem::connectedPins() const {
BlockBusItem::PointInfo BlockBusItem::pointInfo(QPointF pos) const { BlockBusItem::PointInfo BlockBusItem::pointInfo(QPointF pos) const {
PointInfo ret; PointInfo ret;
int pi = -1, si = -1; int pi = -1, si = -1;
testPoint(pos, &pi, & si); testPoint(pos, &pi, &si);
if (pi < 0 && si < 0) return ret; if (pi < 0 && si < 0) return ret;
if (si >= 0) { if (si >= 0) {
ret.type = PointInfo::Type::Segment; ret.type = PointInfo::Type::Segment;
} else { } else {
if (endpoints().contains(pi)) { if (endpoints().contains(pi)) {
ret.type = PointInfo::Type::Endpoint; ret.type = PointInfo::Type::Endpoint;
ret.pin = connections_.value(pi, nullptr); ret.pin = connections_.value(pi, nullptr);
} else } else
ret.type = PointInfo::Type::Node; ret.type = PointInfo::Type::Node;
} }
@@ -350,9 +361,8 @@ void BlockBusItem::clearBusState() {
QByteArray BlockBusItem::save() const { QByteArray BlockBusItem::save() const {
ChunkStream cs; ChunkStream cs;
cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen()) cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen()) << cs.chunk(5, brush())
<< cs.chunk(5, brush()) << cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props) << cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props) << cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale);
<< cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale);
return cs.data(); return cs.data();
} }
@@ -369,9 +379,9 @@ void BlockBusItem::load(const QByteArray & data) {
case 4: setPen(cs.getData<QPen>()); break; case 4: setPen(cs.getData<QPen>()); break;
case 5: setBrush(cs.getData<QBrush>()); break; case 5: setBrush(cs.getData<QBrush>()); break;
case 6: pol = cs.getData<QPolygonF>(); break; case 6: pol = cs.getData<QPolygonF>(); break;
case 7: segments = cs.getData<QList<QPair<int, int> > >(); break; case 7: segments = cs.getData<QList<QPair<int, int>>>(); break;
case 8: props = cs.getData<QList<BlockItem::Property> >(); break; case 8: props = cs.getData<QList<BlockItem::Property>>(); break;
case 9: im_bus_scale = cs.getData<double>(); break; case 9: im_bus_scale = cs.getData<double>(); break;
case 10: im_end_scale = cs.getData<double>(); break; case 10: im_end_scale = cs.getData<double>(); break;
} }
} }
@@ -387,16 +397,16 @@ BlockBusItem * BlockBusItem::copy() const {
void BlockBusItem::saveState() { void BlockBusItem::saveState() {
segments_s = segments; segments_s = segments;
ends_ind_s = ends_ind; ends_ind_s = ends_ind;
ends_s = ends; ends_s = ends;
pol_s = pol; pol_s = pol;
} }
void BlockBusItem::restoreState() { void BlockBusItem::restoreState() {
segments = segments_s; segments = segments_s;
ends_ind = ends_ind_s; ends_ind = ends_ind_s;
ends = ends_s; ends = ends_s;
pol = pol_s; pol = pol_s;
} }
@@ -429,8 +439,8 @@ bool BlockBusItem::checkDelete() {
void BlockBusItem::emitAction(BlockItemBase::Action a) { void BlockBusItem::emitAction(BlockItemBase::Action a) {
qobject_cast<BlockView*>(scene()->views().back())->schemeAction(a, QList<QGraphicsItem*>() << this); qobject_cast<BlockView *>(scene()->views().back())->schemeAction(a, QList<QGraphicsItem *>() << this);
qobject_cast<BlockView*>(scene()->views().back())->connectionsChanged(); qobject_cast<BlockView *>(scene()->views().back())->connectionsChanged();
} }
@@ -441,8 +451,7 @@ QVector<int> BlockBusItem::endpoints() const {
counts[segments[i].second]++; counts[segments[i].second]++;
} }
for (int i = 0; i < counts.size(); ++i) { for (int i = 0; i < counts.size(); ++i) {
if (counts[i] == 1) if (counts[i] == 1) ret << i;
ret << i;
} }
return ret; return ret;
} }
@@ -455,16 +464,16 @@ QVector<int> BlockBusItem::endpointLine(int ep, double angle) const {
if (ep < 0 || np < 0) return ret; if (ep < 0 || np < 0) return ret;
if (pol[np] == pol[ep]) return ret; if (pol[np] == pol[ep]) return ret;
QLineF l(pol[ep], pol[np]); QLineF l(pol[ep], pol[np]);
//qDebug() << "first" << l.angle() << angle << (l.angle() != angle); // qDebug() << "first" << l.angle() << angle << (l.angle() != angle);
if (qAbs(l.angle() - angle) > 0.1) return ret; if (qAbs(l.angle() - angle) > 0.1) return ret;
//qDebug() << "check next" << segments.size(); // qDebug() << "check next" << segments.size();
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
//qDebug() << i << np << pointSegmentsCount(np); // qDebug() << i << np << pointSegmentsCount(np);
if (np < 0) break; if (np < 0) break;
if (pointSegmentsCount(np) != 2) break; if (pointSegmentsCount(np) != 2) break;
if (i > 0) { if (i > 0) {
QLineF l(pol[pp], pol[np]); QLineF l(pol[pp], pol[np]);
//qDebug() << i << l.angle() << angle; // qDebug() << i << l.angle() << angle;
if (qAbs(l.angle() - angle) > 0.1) break; if (qAbs(l.angle() - angle) > 0.1) break;
} }
ret << np; ret << np;
@@ -472,7 +481,6 @@ QVector<int> BlockBusItem::endpointLine(int ep, double angle) const {
np = neighborSegmentPoint(np, &seg); np = neighborSegmentPoint(np, &seg);
} }
return ret; return ret;
} }
@@ -492,8 +500,14 @@ int BlockBusItem::neighborSegmentPoint(int point, int * seg) const {
if (point < 0 || !seg) return -1; if (point < 0 || !seg) return -1;
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (i == *seg) continue; if (i == *seg) continue;
if (segments[i].first == point) {*seg = i; return segments[i].second;} if (segments[i].first == point) {
if (segments[i].second == point) {*seg = i; return segments[i].first ;} *seg = i;
return segments[i].second;
}
if (segments[i].second == point) {
*seg = i;
return segments[i].first;
}
} }
return -1; return -1;
} }
@@ -502,57 +516,58 @@ int BlockBusItem::neighborSegmentPoint(int point, int * seg) const {
void BlockBusItem::testPoint(QPointF pos, int * sel_point, int * sel_segment, bool for_trace) const { void BlockBusItem::testPoint(QPointF pos, int * sel_point, int * sel_segment, bool for_trace) const {
for (int i = 0; i < pol.size(); ++i) { for (int i = 0; i < pol.size(); ++i) {
if ((pol[i] - pos).manhattanLength() <= (for_trace ? 5. : 10.)) { // Point if ((pol[i] - pos).manhattanLength() <= (for_trace ? 5. : 10.)) { // Point
*sel_point = i; *sel_point = i;
*sel_segment = -1; *sel_segment = -1;
return; return;
} }
} }
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (distPointToLine(pol[segments[i].first], pol[segments[i].second], pos) <= (for_trace ? 5. : 7.)) { // Segment if (distPointToLine(pol[segments[i].first], pol[segments[i].second], pos) <= (for_trace ? 5. : 7.)) { // Segment
*sel_point = -1; *sel_point = -1;
*sel_segment = i; *sel_segment = i;
return; return;
} }
} }
*sel_point = -1; *sel_point = -1;
*sel_segment = -1; *sel_segment = -1;
} }
void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n") tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n") +
+ tr("Add point: Ctrl + LeftClick\n" tr("Add point: Ctrl + LeftClick\n"
"Remove point\\segment: Ctrl + RightClick\n" "Remove point\\segment: Ctrl + RightClick\n"
"Remove connection: Shift + RightClick\n" "Remove connection: Shift + RightClick\n"
"Move point\\segment: Shift + LeftPress\n" "Move point\\segment: Shift + LeftPress\n"
"Change trace mode: press Shift, when mouse move"); "Change trace mode: press Shift, when mouse move");
} }
void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) { void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
if (temp_) return; if (temp_) return;
QPointF sp = e->scenePos(); QPointF sp = e->scenePos();
int pp = selPoint; int pp = selPoint;
int ps = selSegment; int ps = selSegment;
bool empt = !(selPoint >= 0 || selSegment >= 0); bool empt = !(selPoint >= 0 || selSegment >= 0);
testPoint(sp, &selPoint, &selSegment); testPoint(sp, &selPoint, &selSegment);
BlockView * bv = 0; BlockView * bv = 0;
if (!scene()->views().isEmpty()) { if (!scene()->views().isEmpty()) {
bv = qobject_cast<BlockView*>(scene()->views().back()); bv = qobject_cast<BlockView *>(scene()->views().back());
} }
if ((selPoint >= 0 && pp != selPoint) || (selSegment >= 0 && ps != selSegment)) { if ((selPoint >= 0 && pp != selPoint) || (selSegment >= 0 && ps != selSegment)) {
if (bv) { if (bv) {
if (bv->isBlockAnimationEnabled()) { if (bv->isBlockAnimationEnabled()) {
setPointSize(0); setPointSize(0);
anim_point_size.start(); anim_point_size.start();
} }
} else setPointSize(anim_point_size.endValue().toDouble()); } else
setPointSize(anim_point_size.endValue().toDouble());
} }
if (selPoint >= 0 || selSegment >= 0) { if (selPoint >= 0 || selSegment >= 0) {
if (empt) { if (empt) {
QList<BlockItemPin * > pins = connectedPins(); QList<BlockItemPin *> pins = connectedPins();
foreach (BlockItemPin * p, pins) { foreach(BlockItemPin * p, pins) {
p->animAccept(); p->animAccept();
} }
} }
@@ -563,15 +578,15 @@ void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
} }
if (bv) bv->cur_bus = 0; if (bv) bv->cur_bus = 0;
setToolTip(QString()); setToolTip(QString());
QList<QGraphicsItem * > il = scene()->items(sp, Qt::ContainsItemBoundingRect, Qt::DescendingOrder), bil; QList<QGraphicsItem *> il = scene()->items(sp, Qt::ContainsItemBoundingRect, Qt::DescendingOrder), bil;
bil << this; bil << this;
for (int i = 0; i < il.size(); ++i) { for (int i = 0; i < il.size(); ++i) {
QGraphicsItem * b = il[i]; QGraphicsItem * b = il[i];
if ((b->data(bvidType).toInt() == bvitBus) && b != this) { if ((b->data(bvidType).toInt() == bvitBus) && b != this) {
int tp = -1, ts = -1; int tp = -1, ts = -1;
((BlockBusItem*)b)->testPoint(sp, &tp, &ts); ((BlockBusItem *)b)->testPoint(sp, &tp, &ts);
if (tp >= 0 || ts >= 0) { if (tp >= 0 || ts >= 0) {
foreach (QGraphicsItem * b2, bil) foreach(QGraphicsItem * b2, bil)
b2->stackBefore(b); b2->stackBefore(b);
break; break;
} }
@@ -585,14 +600,13 @@ void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
if (temp_) return; if (temp_) return;
selPoint = selSegment = -1; selPoint = selSegment = -1;
setPen(pu); setBrush(bu); setPen(pu);
setBrush(bu);
setToolTip(QString()); setToolTip(QString());
anim_point_size.stop(); anim_point_size.stop();
BlockView * bv = 0; BlockView * bv = 0;
if (!scene()->views().isEmpty()) if (!scene()->views().isEmpty()) bv = qobject_cast<BlockView *>(scene()->views().back());
bv = qobject_cast<BlockView*>(scene()->views().back()); if (bv && (QApplication::mouseButtons() == 0)) bv->cur_bus = 0;
if (bv && (QApplication::mouseButtons() == 0))
bv->cur_bus = 0;
update(); update();
QGraphicsObject::hoverLeaveEvent(e); QGraphicsObject::hoverLeaveEvent(e);
} }
@@ -601,18 +615,16 @@ void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
if (temp_) return; if (temp_) return;
lp = quantize(e->scenePos(), grid_step); lp = quantize(e->scenePos(), grid_step);
if (e->button() != Qt::RightButton) if (e->button() != Qt::RightButton) bpol = pol;
bpol = pol;
BlockView * bv = 0; BlockView * bv = 0;
if (!scene()->views().isEmpty()) { if (!scene()->views().isEmpty()) {
bv = qobject_cast<BlockView*>(scene()->views().back()); bv = qobject_cast<BlockView *>(scene()->views().back());
} }
if (bv) { if (bv) {
if (selPoint >= 0 || selSegment >= 0) if (selPoint >= 0 || selSegment >= 0) bv->cur_bus = this;
bv->cur_bus = this;
} }
if (new_segment) { if (new_segment) {
qobject_cast<BlockView*>(scene()->views().back())->newBranchCancel(); qobject_cast<BlockView *>(scene()->views().back())->newBranchCancel();
} }
new_segment = false; new_segment = false;
if ((selPoint < 0 || selPoint > pol.size() - 1) && (selSegment < 0) && e->modifiers().testFlag(Qt::ShiftModifier)) { if ((selPoint < 0 || selPoint > pol.size() - 1) && (selSegment < 0) && e->modifiers().testFlag(Qt::ShiftModifier)) {
@@ -621,23 +633,24 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
} }
int btncnt = 0; int btncnt = 0;
if ((e->button() == Qt::LeftButton) && e->modifiers().testFlag(Qt::ShiftModifier)) { if ((e->button() == Qt::LeftButton) && e->modifiers().testFlag(Qt::ShiftModifier)) {
if (endpoints().contains(selPoint)) qobject_cast<BlockView*>(scene()->views().back())->startBusPointMove(bus_type); if (endpoints().contains(selPoint)) qobject_cast<BlockView *>(scene()->views().back())->startBusPointMove(bus_type);
} }
if (e->buttons().testFlag(Qt::LeftButton )) btncnt++; if (e->buttons().testFlag(Qt::LeftButton)) btncnt++;
if (e->buttons().testFlag(Qt::RightButton)) btncnt++; if (e->buttons().testFlag(Qt::RightButton)) btncnt++;
if (e->buttons().testFlag(QT_MID_BUTTON )) btncnt++; if (e->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
if (btncnt > 0) mm_mods = e->modifiers(); if (btncnt > 0) mm_mods = e->modifiers();
if (btncnt >= 2 && e->button() == Qt::RightButton) { if (btncnt >= 2 && e->button() == Qt::RightButton) {
//qDebug() << "bus revert"; // qDebug() << "bus revert";
mm_cancel = true; mm_cancel = true;
moved = false; moved = false;
pol = bpol; pol = bpol;
prepareGeometryChange(); prepareGeometryChange();
return; return;
} }
if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) { if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) {
if (selSegment >= 0) if (selSegment >= 0)
press_pos = quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], e->scenePos()), grid_step); press_pos =
quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], e->scenePos()), grid_step);
else { else {
if (selPoint >= 0) if (selPoint >= 0)
press_pos = pol[selPoint]; press_pos = pol[selPoint];
@@ -646,10 +659,9 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
} }
if (max_ep >= 2) { if (max_ep >= 2) {
if (endpointCount() >= max_ep) if (endpointCount() >= max_ep)
if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) return;
return;
} }
qobject_cast<BlockView*>(scene()->views().back())->newBranch(this); qobject_cast<BlockView *>(scene()->views().back())->newBranch(this);
new_segment = true; new_segment = true;
return; return;
} }
@@ -657,7 +669,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
deleteLater(); deleteLater();
} }
if (e->modifiers().testFlag(Qt::ControlModifier)) { if (e->modifiers().testFlag(Qt::ControlModifier)) {
//qDebug() << "remove" << selPoint << selSegment; // qDebug() << "remove" << selPoint << selSegment;
if (e->buttons().testFlag(Qt::RightButton)) { if (e->buttons().testFlag(Qt::RightButton)) {
if (selPoint >= 0 && selPoint <= pol.size() - 1) { if (selPoint >= 0 && selPoint <= pol.size() - 1) {
removePoint(selPoint); removePoint(selPoint);
@@ -673,8 +685,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
} }
} }
if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) { if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) {
if (addPoint(e->scenePos()) >= 0) if (addPoint(e->scenePos()) >= 0) emitAction(BlockItemBase::BusPointAdd);
emitAction(BlockItemBase::BusPointAdd);
return; return;
} }
} }
@@ -693,12 +704,12 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
} }
BlockView * bv = 0; BlockView * bv = 0;
if (!scene()->views().isEmpty()) { if (!scene()->views().isEmpty()) {
bv = qobject_cast<BlockView*>(scene()->views().back()); bv = qobject_cast<BlockView *>(scene()->views().back());
} }
qp = quantize(e->scenePos(), grid_step); qp = quantize(e->scenePos(), grid_step);
lp = qp - lp; lp = qp - lp;
if (e->buttons().testFlag(Qt::LeftButton) && mm_mods.testFlag(Qt::NoModifier) && new_segment) { if (e->buttons().testFlag(Qt::LeftButton) && mm_mods.testFlag(Qt::NoModifier) && new_segment) {
if (bv) qobject_cast<BlockView*>(scene()->views().back())->newBranchTrace(this, e->scenePos()); if (bv) qobject_cast<BlockView *>(scene()->views().back())->newBranchTrace(this, e->scenePos());
return; return;
} }
if (new_segment) { if (new_segment) {
@@ -707,8 +718,7 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
} else { } else {
if (e->buttons().testFlag(Qt::LeftButton)) { if (e->buttons().testFlag(Qt::LeftButton)) {
lm_point = selPoint >= 0; lm_point = selPoint >= 0;
if (selPoint >= 0 && selPoint <= pol.size() - 1) if (selPoint >= 0 && selPoint <= pol.size() - 1) pol[selPoint] += lp;
pol[selPoint] += lp;
if (selSegment >= 0 && selSegment <= segments.size() - 1) { if (selSegment >= 0 && selSegment <= segments.size() - 1) {
pol[segments[selSegment].first] += lp; pol[segments[selSegment].first] += lp;
pol[segments[selSegment].second] += lp; pol[segments[selSegment].second] += lp;
@@ -722,14 +732,14 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) { void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) {
mm_mods = Qt::KeyboardModifiers(); mm_mods = Qt::KeyboardModifiers();
int btncnt = 0; int btncnt = 0;
if (e->buttons().testFlag(Qt::LeftButton )) btncnt++; if (e->buttons().testFlag(Qt::LeftButton)) btncnt++;
if (e->buttons().testFlag(Qt::RightButton)) btncnt++; if (e->buttons().testFlag(Qt::RightButton)) btncnt++;
if (e->buttons().testFlag(QT_MID_BUTTON )) btncnt++; if (e->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
if (btncnt == 0) mm_cancel = false; if (btncnt == 0) mm_cancel = false;
if (new_segment) { if (new_segment) {
qobject_cast<BlockView*>(scene()->views().back())->newBranchAccept(this); qobject_cast<BlockView *>(scene()->views().back())->newBranchAccept(this);
updateGeometry(); updateGeometry();
selPoint = selSegment = -1; selPoint = selSegment = -1;
} }
@@ -739,7 +749,7 @@ void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) {
emitAction(BlockItemBase::BusPointMove); emitAction(BlockItemBase::BusPointMove);
} else { } else {
reconnect(); reconnect();
emitAction( BlockItemBase::BusSegmentMove); emitAction(BlockItemBase::BusSegmentMove);
} }
} }
moved = new_segment = false; moved = new_segment = false;
+68 -43
View File
@@ -1,20 +1,20 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKBUSITEM_H #ifndef BLOCKBUSITEM_H
@@ -24,15 +24,18 @@
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
class QAD_BLOCKVIEW_EXPORT BlockBusItem: public QGraphicsObject, public PropertyStorage { class QAD_BLOCKVIEW_EXPORT BlockBusItem
: public QGraphicsObject
, public PropertyStorage {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QGraphicsItem) Q_INTERFACES(QGraphicsItem)
Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false)
friend class BlockView; friend class BlockView;
public: public:
BlockBusItem(bool temp = false); BlockBusItem(bool temp = false);
BlockBusItem(const BlockBusItem & other); BlockBusItem(const BlockBusItem & other);
~BlockBusItem() {;} ~BlockBusItem() { ; }
struct QAD_BLOCKVIEW_EXPORT PointInfo { struct QAD_BLOCKVIEW_EXPORT PointInfo {
enum class Type { enum class Type {
@@ -41,30 +44,46 @@ public:
Endpoint, Endpoint,
Segment Segment
}; };
Type type = Type::None; Type type = Type::None;
BlockItemPin * pin = nullptr; // if tEndpoint and pin connected BlockItemPin * pin = nullptr; // if tEndpoint and pin connected
}; };
void setGridStep(double gs) {grid_step = gs;} void setGridStep(double gs) { grid_step = gs; }
void setEndpointsNumber(int num) {max_ep = num;} void setEndpointsNumber(int num) { max_ep = num; }
void setImages(const QImage & bus, const QImage & end = QImage()) {im_bus = bus; im_end = end; update();} void setImages(const QImage & bus, const QImage & end = QImage()) {
void setBusImageScale(double s) {im_bus_scale = s; update();} im_bus = bus;
void setEndpointImageScale(double s) {im_end_scale = s; update();} im_end = end;
void setBusType(int type_) {bus_type = type_;} update();
void setBusName(const QString & name) {bus_name = name;} }
int busType() const {return bus_type;} void setBusImageScale(double s) {
QString busName() const {return bus_name;} im_bus_scale = s;
double busImageScale() const {return im_bus_scale;} update();
double endpointImageScale() const {return im_end_scale;} }
void setEndpointImageScale(double s) {
im_end_scale = s;
update();
}
void setBusType(int type_) { bus_type = type_; }
void setBusName(const QString & name) { bus_name = name; }
int busType() const { return bus_type; }
QString busName() const { return bus_name; }
double busImageScale() const { return im_bus_scale; }
double endpointImageScale() const { return im_end_scale; }
void appendPoint(const QPointF & p); void appendPoint(const QPointF & p);
void appendPoint(qreal x, qreal y); void appendPoint(qreal x, qreal y);
void movePolyline(const QPointF & dp); void movePolyline(const QPointF & dp);
void clear(); void clear();
void setPen(const QPen & p) {p_ = p; update();} void setPen(const QPen & p) {
QPen pen() const {return p_;} p_ = p;
void setBrush(const QBrush & b) {b_ = b; update();} update();
QBrush brush() const {return b_;} }
double width() const {return pen_width;} QPen pen() const { return p_; }
void setBrush(const QBrush & b) {
b_ = b;
update();
}
QBrush brush() const { return b_; }
double width() const { return pen_width; }
void setWidth(const double & w); void setWidth(const double & w);
void setColor(const QColor & c); void setColor(const QColor & c);
void setSquareNodes(bool yes); void setSquareNodes(bool yes);
@@ -74,13 +93,13 @@ public:
void simplify(bool full = true); void simplify(bool full = true);
void adjustLine(); void adjustLine();
int endpointCount() const; int endpointCount() const;
bool isBusSelected() const {return selSegment >= 0 || selPoint >= 0;} bool isBusSelected() const { return selSegment >= 0 || selPoint >= 0; }
QList<BlockItem * > connectedBlocks() const; QList<BlockItem *> connectedBlocks() const;
QList<BlockItemPin * > connectedPins() const; QList<BlockItemPin *> connectedPins() const;
PointInfo pointInfo(QPointF pos) const; PointInfo pointInfo(QPointF pos) const;
void setBusState(bool state); void setBusState(bool state);
bool busState() const {return state_ > 0;} bool busState() const { return state_ > 0; }
void clearBusState(); void clearBusState();
QByteArray save() const; QByteArray save() const;
@@ -90,7 +109,9 @@ public:
void saveState(); void saveState();
void restoreState(); void restoreState();
enum {Type = UserType + 2}; enum {
Type = UserType + 2
};
protected: protected:
void _init(); void _init();
@@ -108,7 +129,7 @@ protected:
QVector<int> endpoints() const; QVector<int> endpoints() const;
QVector<int> endpointLine(int ep, double angle) const; QVector<int> endpointLine(int ep, double angle) const;
int neighborSegmentPoint(int point, int * seg) const; int neighborSegmentPoint(int point, int * seg) const;
int type() const {return Type;} int type() const { return Type; }
QRectF boundingRect() const; QRectF boundingRect() const;
bool sceneEvent(QEvent * e); bool sceneEvent(QEvent * e);
void hoverEnterEvent(QGraphicsSceneHoverEvent * e); void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
@@ -123,8 +144,8 @@ protected:
QPen p_, ph, pu, pa, pr, pn; QPen p_, ph, pu, pa, pr, pn;
QBrush b_, bh, bu, ba, br; QBrush b_, bh, bu, ba, br;
QString tt, bus_name; QString tt, bus_name;
QList<QPair<int, int> > segments, ends_ind, segments_s, ends_ind_s; QList<QPair<int, int>> segments, ends_ind, segments_s, ends_ind_s;
QMap<int, BlockItemPin * > connections_; QMap<int, BlockItemPin *> connections_;
QVector<int> ends, ends_s; QVector<int> ends, ends_s;
QImage im_bus, im_end; QImage im_bus, im_end;
QPolygonF pol, bpol, pol_s; QPolygonF pol, bpol, pol_s;
@@ -135,7 +156,7 @@ protected:
bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point; bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point;
private: private:
double pointSize() const {return point_size;} double pointSize() const { return point_size; }
void setPointSize(double s); void setPointSize(double s);
double point_size; double point_size;
@@ -143,9 +164,13 @@ private:
}; };
inline QDataStream & operator <<(QDataStream & s, const BlockBusItem * b) {s << b->save(); return s;} inline QDataStream & operator<<(QDataStream & s, const BlockBusItem * b) {
inline QDataStream & operator >>(QDataStream & s, BlockBusItem *& b) { s << b->save();
QByteArray ba; s >> ba; return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockBusItem *& b) {
QByteArray ba;
s >> ba;
b = new BlockBusItem(); b = new BlockBusItem();
b->load(ba); b->load(ba);
return s; return s;
+54 -46
View File
@@ -1,17 +1,19 @@
#include "blockeditor.h" #include "blockeditor.h"
#include "ui_blockeditor.h"
#include "drawtools.h"
#include "blockview.h" #include "blockview.h"
#include <QToolBar> #include "drawtools.h"
#include "ui_blockeditor.h"
#include <QComboBox> #include <QComboBox>
#include <QFileDialog>
#include <QFile> #include <QFile>
#include <QFileDialog>
#include <QTimer> #include <QTimer>
#include <QToolBar>
BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEditor) { BlockEditor::BlockEditor(QWidget * parent): QWidget(parent), ui(new Ui::BlockEditor) {
init = false; init = false;
m_editorMode = false; m_editorMode = false;
m_pinsEditable = true; m_pinsEditable = true;
ui->setupUi(this); ui->setupUi(this);
src_title = windowTitle(); src_title = windowTitle();
@@ -20,13 +22,15 @@ BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEdi
ui->blockView->addItem(&block); ui->blockView->addItem(&block);
ui->blockView->viewport()->installEventFilter(this); ui->blockView->viewport()->installEventFilter(this);
DrawTools * drawtools = new DrawTools(ui->blockView); DrawTools * drawtools = new DrawTools(ui->blockView);
connect(drawtools, SIGNAL(itemCreated(QGraphicsItem*)), this, SLOT(addItem(QGraphicsItem*))); connect(drawtools, SIGNAL(itemCreated(QGraphicsItem *)), this, SLOT(addItem(QGraphicsItem *)));
drawtools->textEditCombo()->addItems(QStringList() << "%name" << "%value" << "%id"); drawtools->textEditCombo()->addItems(QStringList() << "%name"
<< "%value"
<< "%id");
ui->layoutProperties->addWidget(drawtools->propertyWidget()); ui->layoutProperties->addWidget(drawtools->propertyWidget());
ui->actionRemove_items->setEnabled(false); ui->actionRemove_items->setEnabled(false);
ui->button_color->setColor(Qt::lightGray); ui->button_color->setColor(Qt::lightGray);
ui->treePins->setItemDelegateForColumn(1, new PinBusDelegate()); ui->treePins->setItemDelegateForColumn(1, new PinBusDelegate());
connect(ui->treePins, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(updateBlock())); connect(ui->treePins, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(updateBlock()));
ui->treePins->viewport()->installEventFilter(this); ui->treePins->viewport()->installEventFilter(this);
QToolBar * bar; QToolBar * bar;
@@ -39,7 +43,7 @@ BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEdi
bar->setOrientation(Qt::Vertical); bar->setOrientation(Qt::Vertical);
bar->addActions(drawtools->actionsForZ()); bar->addActions(drawtools->actionsForZ());
bar->addSeparator(); bar->addSeparator();
bar->addActions(QList<QAction*>() << ui->actionRemove_items); bar->addActions(QList<QAction *>() << ui->actionRemove_items);
ui->widgetBarZ->setMinimumSize(bar->sizeHint()); ui->widgetBarZ->setMinimumSize(bar->sizeHint());
init = true; init = true;
on_buttonClear_clicked(); on_buttonClear_clicked();
@@ -64,7 +68,7 @@ void BlockEditor::loadFile(QString path) {
} }
void BlockEditor::loadModel(const QByteArray &model) { void BlockEditor::loadModel(const QByteArray & model) {
BlockItem b; BlockItem b;
b.loadModel(model); b.loadModel(model);
ui->spin_w->setValue(b.width()); ui->spin_w->setValue(b.width());
@@ -74,15 +78,15 @@ void BlockEditor::loadModel(const QByteArray &model) {
block.loadModel(model); block.loadModel(model);
treePinsClear(); treePinsClear();
ui->treePins->blockSignals(true); ui->treePins->blockSignals(true);
QVector<BlockItemPin * > pins = block.pins(); QVector<BlockItemPin *> pins = block.pins();
foreach (BlockItemPin * p, pins) { foreach(BlockItemPin * p, pins) {
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << p->text() << QString::number(p->busType())); QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << p->text() << QString::number(p->busType()));
ti->setData(0, Qt::UserRole, qulonglong(p)); ti->setData(0, Qt::UserRole, qulonglong(p));
ti->setData(0, Qt::UserRole + 1, (int)p->alignment()); ti->setData(0, Qt::UserRole + 1, (int)p->alignment());
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled); ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
pin_tli[p->alignment()]->addChild(ti); pin_tli[p->alignment()]->addChild(ti);
} }
foreach (QGraphicsItem * i, block.decors()) { foreach(QGraphicsItem * i, block.decors()) {
i->setData(bvidMoveParent, false); i->setData(bvidMoveParent, false);
i->setData(bvidCorrectMove, true); i->setData(bvidCorrectMove, true);
} }
@@ -121,7 +125,7 @@ void BlockEditor::selectionChanged() {
} }
void BlockEditor::addItem(QGraphicsItem *item) { void BlockEditor::addItem(QGraphicsItem * item) {
block.addDecor(item); block.addDecor(item);
item->setData(bvidMoveParent, false); item->setData(bvidMoveParent, false);
item->setData(bvidCorrectMove, true); item->setData(bvidCorrectMove, true);
@@ -138,9 +142,13 @@ void BlockEditor::updateBlock() {
void BlockEditor::treePinsClear() { void BlockEditor::treePinsClear() {
ui->treePins->blockSignals(true); ui->treePins->blockSignals(true);
ui->treePins->clear(); ui->treePins->clear();
QFont bf(font()); bf.setBold(true); QFont bf(font());
QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom; bf.setBold(true);
QStringList an = QStringList() << "Left" << "Right" << "Top" << "Bottom"; QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom;
QStringList an = QStringList() << "Left"
<< "Right"
<< "Top"
<< "Bottom";
pin_tli.clear(); pin_tli.clear();
for (int i = 0; i < al.size(); ++i) { for (int i = 0; i < al.size(); ++i) {
QTreeWidgetItem * ti = new QTreeWidgetItem(); QTreeWidgetItem * ti = new QTreeWidgetItem();
@@ -157,7 +165,7 @@ void BlockEditor::treePinsClear() {
} }
bool BlockEditor::eventFilter(QObject *o, QEvent *e) { bool BlockEditor::eventFilter(QObject * o, QEvent * e) {
if (!init) QWidget::eventFilter(o, e); if (!init) QWidget::eventFilter(o, e);
if (o == ui->treePins->viewport()) { if (o == ui->treePins->viewport()) {
if (e->type() == QEvent::Drop) { if (e->type() == QEvent::Drop) {
@@ -176,17 +184,15 @@ bool BlockEditor::eventFilter(QObject *o, QEvent *e) {
void BlockEditor::changeEvent(QEvent * e) { void BlockEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this);
break;
default: break; default: break;
} }
} }
void BlockEditor::on_actionRemove_items_triggered() { void BlockEditor::on_actionRemove_items_triggered() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
foreach (QGraphicsItem * i, si) foreach(QGraphicsItem * i, si)
block.removeDecor(i); block.removeDecor(i);
} }
@@ -233,10 +239,10 @@ void BlockEditor::on_buttonClear_clicked() {
} }
void BlockEditor::on_buttonPinAdd_clicked() { void BlockEditor::on_buttonPinAdd_clicked() {
ui->treePins->blockSignals(true); ui->treePins->blockSignals(true);
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << "" << "0"); QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << ""
<< "0");
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled); ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
ti->setData(0, Qt::UserRole, qulonglong(block.addPin(Qt::AlignLeft, ti->text(1).toInt(), ti->text(0)))); ti->setData(0, Qt::UserRole, qulonglong(block.addPin(Qt::AlignLeft, ti->text(1).toInt(), ti->text(0))));
ti->setData(0, Qt::UserRole + 1, (int)Qt::AlignLeft); ti->setData(0, Qt::UserRole + 1, (int)Qt::AlignLeft);
@@ -265,10 +271,10 @@ void BlockEditor::on_buttonPinDup_clicked() {
void BlockEditor::on_buttonPinDelete_clicked() { void BlockEditor::on_buttonPinDelete_clicked() {
ui->treePins->blockSignals(true); ui->treePins->blockSignals(true);
QList<QTreeWidgetItem*> si = ui->treePins->selectedItems(); QList<QTreeWidgetItem *> si = ui->treePins->selectedItems();
foreach (QTreeWidgetItem * i, si) { foreach(QTreeWidgetItem * i, si) {
if (!i->parent()) continue; if (!i->parent()) continue;
block.removePin((BlockItemPin*)(i->data(0, Qt::UserRole).toLongLong())); block.removePin((BlockItemPin *)(i->data(0, Qt::UserRole).toLongLong()));
delete i; delete i;
} }
ui->treePins->blockSignals(false); ui->treePins->blockSignals(false);
@@ -283,7 +289,7 @@ void BlockEditor::on_buttonPinClear_clicked() {
void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) { void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
if (!item) return; if (!item) return;
BlockItemPin * pin = (BlockItemPin*)item->data(0, Qt::UserRole).toULongLong(); BlockItemPin * pin = (BlockItemPin *)item->data(0, Qt::UserRole).toULongLong();
if (!pin) return; if (!pin) return;
switch (column) { switch (column) {
case 0: case 0:
@@ -297,16 +303,15 @@ void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
} }
void BlockEditor::arrangePins() { void BlockEditor::arrangePins() {
QVector<BlockItemPin * > pins = block.pins(); QVector<BlockItemPin *> pins = block.pins();
QList<QTreeWidgetItem*> tli = pin_tli.values(); QList<QTreeWidgetItem *> tli = pin_tli.values();
foreach (QTreeWidgetItem * ti, tli) { foreach(QTreeWidgetItem * ti, tli) {
for (int i = 0; i < ti->childCount(); ++i) { for (int i = 0; i < ti->childCount(); ++i) {
foreach (BlockItemPin * p, pins) foreach(BlockItemPin * p, pins)
if (p == (BlockItemPin*)(ti->child(i)->data(0, Qt::UserRole).toULongLong())) { if (p == (BlockItemPin *)(ti->child(i)->data(0, Qt::UserRole).toULongLong())) {
p->setAlignment((Qt::Alignment)ti->data(0, Qt::UserRole).toInt()); p->setAlignment((Qt::Alignment)ti->data(0, Qt::UserRole).toInt());
BlockItemPin * np = block.addPin(p, false); BlockItemPin * np = block.addPin(p, false);
ti->child(i)->setData(0, Qt::UserRole, qulonglong(np)); ti->child(i)->setData(0, Qt::UserRole, qulonglong(np));
ti->child(i)->setData(0, Qt::UserRole + 1, ti->data(0, Qt::UserRole).toInt()); ti->child(i)->setData(0, Qt::UserRole + 1, ti->data(0, Qt::UserRole).toInt());
break; break;
@@ -325,11 +330,15 @@ void BlockEditor::arrangePins() {
QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const { QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QComboBox * combo = new QComboBox(parent); QComboBox * combo = new QComboBox(parent);
int cv = index.data().toInt(); int cv = index.data().toInt();
combo->addItem("Left", int(Qt::AlignLeft)); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0); combo->addItem("Left", int(Qt::AlignLeft));
combo->addItem("Right", int(Qt::AlignRight)); if (cv == Qt::AlignRight) combo->setCurrentIndex(1); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0);
combo->addItem("Top", int(Qt::AlignTop)); if (cv == Qt::AlignTop) combo->setCurrentIndex(2); combo->addItem("Right", int(Qt::AlignRight));
combo->addItem("Bottom", int(Qt::AlignBottom)); if (cv == Qt::AlignBottom) combo->setCurrentIndex(3); if (cv == Qt::AlignRight) combo->setCurrentIndex(1);
combo->addItem("Top", int(Qt::AlignTop));
if (cv == Qt::AlignTop) combo->setCurrentIndex(2);
combo->addItem("Bottom", int(Qt::AlignBottom));
if (cv == Qt::AlignBottom) combo->setCurrentIndex(3);
combo->setGeometry(option.rect); combo->setGeometry(option.rect);
return combo; return combo;
} }
@@ -348,7 +357,7 @@ QString PinAlignDelegate::displayText(const QVariant & value, const QLocale & lo
void PinAlignDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const { void PinAlignDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
model->setData(index, ((QComboBox*)editor)->itemData(((QComboBox*)editor)->currentIndex()).toInt()); model->setData(index, ((QComboBox *)editor)->itemData(((QComboBox *)editor)->currentIndex()).toInt());
} }
@@ -374,6 +383,5 @@ QString PinBusDelegate::displayText(const QVariant & value, const QLocale & loca
void PinBusDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const { void PinBusDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
model->setData(index, ((QSpinBox*)editor)->value()); model->setData(index, ((QSpinBox *)editor)->value());
} }
+30 -27
View File
@@ -1,49 +1,50 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKEDITOR_H #ifndef BLOCKEDITOR_H
#define BLOCKEDITOR_H #define BLOCKEDITOR_H
#include <QWidget>
#include <QTreeWidgetItem>
#include <QStyledItemDelegate>
#include "blockitem.h" #include "blockitem.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QStyledItemDelegate>
#include <QTreeWidgetItem>
#include <QWidget>
namespace Ui { namespace Ui {
class BlockEditor; class BlockEditor;
} }
class QAD_BLOCKVIEW_EXPORT BlockEditor : public QWidget class QAD_BLOCKVIEW_EXPORT BlockEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool editorMode READ editorMode WRITE setEditorMode) Q_PROPERTY(bool editorMode READ editorMode WRITE setEditorMode)
Q_PROPERTY(bool pinsEditable READ pinsEditable WRITE setPinsEditable) Q_PROPERTY(bool pinsEditable READ pinsEditable WRITE setPinsEditable)
public: public:
explicit BlockEditor(QWidget *parent = 0); explicit BlockEditor(QWidget * parent = 0);
~BlockEditor(); ~BlockEditor();
bool editorMode() const {return m_editorMode;} bool editorMode() const { return m_editorMode; }
bool pinsEditable() const {return m_pinsEditable;} bool pinsEditable() const { return m_pinsEditable; }
public slots: public slots:
void loadFile(QString path); void loadFile(QString path);
@@ -67,14 +68,14 @@ private slots:
void on_buttonPinDup_clicked(); void on_buttonPinDup_clicked();
void on_buttonPinDelete_clicked(); void on_buttonPinDelete_clicked();
void on_buttonPinClear_clicked(); void on_buttonPinClear_clicked();
void on_treePins_itemChanged(QTreeWidgetItem *item, int column); void on_treePins_itemChanged(QTreeWidgetItem * item, int column);
private: private:
bool eventFilter(QObject * o, QEvent * e); bool eventFilter(QObject * o, QEvent * e);
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
Ui::BlockEditor *ui; Ui::BlockEditor * ui;
QMap<int, QTreeWidgetItem*> pin_tli; QMap<int, QTreeWidgetItem *> pin_tli;
BlockItem block; BlockItem block;
QString src_title, cur_file; QString src_title, cur_file;
bool init; bool init;
@@ -83,26 +84,28 @@ private:
}; };
class QAD_BLOCKVIEW_EXPORT PinAlignDelegate: public QStyledItemDelegate { class QAD_BLOCKVIEW_EXPORT PinAlignDelegate: public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {} PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const; QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QString displayText(const QVariant & value, const QLocale & locale) const; QString displayText(const QVariant & value, const QLocale & locale) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {return QSize(60, 26);} QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { return QSize(60, 26); }
}; };
class QAD_BLOCKVIEW_EXPORT PinBusDelegate: public QStyledItemDelegate { class QAD_BLOCKVIEW_EXPORT PinBusDelegate: public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {} PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const; QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QString displayText(const QVariant & value, const QLocale & locale) const; QString displayText(const QVariant & value, const QLocale & locale) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {return QSize(60, 26);} QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { return QSize(60, 26); }
private: private:
typedef QPair<int, QString> ISPair; typedef QPair<int, QString> ISPair;
QVector<ISPair> buses; QVector<ISPair> buses;
+91 -90
View File
@@ -1,11 +1,11 @@
#include "blockview.h" #include "blockview.h"
#include <QApplication> #include <QApplication>
#define BLOCKITEM_DEFAULT_PIN_MARGIN 20 #define BLOCKITEM_DEFAULT_PIN_MARGIN 20
BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(), BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(), g_main(this), g_selection(this) {
g_main(this), g_selection(this) {
setData(bvidType, bvitBlock); setData(bvidType, bvitBlock);
setZValue(2.); setZValue(2.);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
@@ -58,11 +58,9 @@ void BlockItem::_resize(QSizeF s) {
void BlockItem::_moveToTop(bool only_decors) { void BlockItem::_moveToTop(bool only_decors) {
qreal dy = -g_main.rect().center().y() + 10; qreal dy = -g_main.rect().center().y() + 10;
if (!only_decors) if (!only_decors) moveBy(0., dy);
moveBy(0., dy); foreach(QGraphicsItem * d, decors_)
foreach (QGraphicsItem * d, decors_)
d->moveBy(0., -dy); d->moveBy(0., -dy);
} }
@@ -70,30 +68,27 @@ BlockItemPin * BlockItem::addPin(BlockItemPin * pin, bool update_) {
pin->setParentItem(this); pin->setParentItem(this);
if (!pins_[pin->alignment()].contains(pin)) pins_[pin->alignment()] << pin; if (!pins_[pin->alignment()].contains(pin)) pins_[pin->alignment()] << pin;
pin->parent_ = this; pin->parent_ = this;
if (update_) if (update_) arrangePins();
arrangePins();
return pin; return pin;
} }
BlockItemPin * BlockItem::addPin(Qt::Alignment align, int bus_type, const QString & text, bool update_) { BlockItemPin * BlockItem::addPin(Qt::Alignment align, int bus_type, const QString & text, bool update_) {
BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this); BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this);
pin->parent_ = this; pin->parent_ = this;
pins_[pin->alignment()] << pin; pins_[pin->alignment()] << pin;
if (update_) if (update_) arrangePins();
arrangePins();
return pin; return pin;
} }
void BlockItem::removePin(BlockItemPin * pin) { void BlockItem::removePin(BlockItemPin * pin) {
if (!pin) return; if (!pin) return;
QMutableMapIterator<Qt::Alignment, QVector<BlockItemPin * > > it(pins_); QMutableMapIterator<Qt::Alignment, QVector<BlockItemPin *>> it(pins_);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
QVector<BlockItemPin * > & pv(it.value()); QVector<BlockItemPin *> & pv(it.value());
if (pv.contains(pin)) if (pv.contains(pin)) pv.remove(it.value().indexOf(pin));
pv.remove(it.value().indexOf(pin));
} }
delete pin; delete pin;
arrangePins(); arrangePins();
@@ -102,12 +97,13 @@ void BlockItem::removePin(BlockItemPin * pin) {
void BlockItem::addDecor(QGraphicsItem * item) { void BlockItem::addDecor(QGraphicsItem * item) {
if (decors_.contains(item)) return; if (decors_.contains(item)) return;
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(item)) if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item))
qgraphicsitem_cast<QGraphicsPixmapItem*>(item)->setTransformationMode(Qt::SmoothTransformation); qgraphicsitem_cast<QGraphicsPixmapItem *>(item)->setTransformationMode(Qt::SmoothTransformation);
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)) if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item))
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->setData(bvidDecorText, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->text()); qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)->setData(bvidDecorText,
if (qgraphicsitem_cast<AlignedTextItem*>(item)) qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)->text());
qgraphicsitem_cast<AlignedTextItem*>(item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem*>(item)->text()); if (qgraphicsitem_cast<AlignedTextItem *>(item))
qgraphicsitem_cast<AlignedTextItem *>(item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(item)->text());
item->setData(bvidMoveParent, true); item->setData(bvidMoveParent, true);
item->setData(bvidBlockDecor, true); item->setData(bvidBlockDecor, true);
decors_ << item; decors_ << item;
@@ -117,12 +113,13 @@ void BlockItem::addDecor(QGraphicsItem * item) {
void BlockItem::addDecor(QGraphicsItem & item) { void BlockItem::addDecor(QGraphicsItem & item) {
if (decors_.contains(&item)) return; if (decors_.contains(&item)) return;
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(&item)) if (qgraphicsitem_cast<QGraphicsPixmapItem *>(&item))
qgraphicsitem_cast<QGraphicsPixmapItem*>(&item)->setTransformationMode(Qt::SmoothTransformation); qgraphicsitem_cast<QGraphicsPixmapItem *>(&item)->setTransformationMode(Qt::SmoothTransformation);
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)) if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item))
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->setData(bvidDecorText, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->text()); qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)->setData(bvidDecorText,
if (qgraphicsitem_cast<AlignedTextItem*>(&item)) qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)->text());
qgraphicsitem_cast<AlignedTextItem*>(&item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem*>(&item)->text()); if (qgraphicsitem_cast<AlignedTextItem *>(&item))
qgraphicsitem_cast<AlignedTextItem *>(&item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(&item)->text());
item.setData(bvidMoveParent, true); item.setData(bvidMoveParent, true);
item.setData(bvidBlockDecor, true); item.setData(bvidBlockDecor, true);
item.setParentItem(this); item.setParentItem(this);
@@ -130,22 +127,21 @@ void BlockItem::addDecor(QGraphicsItem & item) {
void BlockItem::removeDecor(QGraphicsItem * item) { void BlockItem::removeDecor(QGraphicsItem * item) {
if (scene() && item) if (scene() && item) scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
decors_.removeAll(item); decors_.removeAll(item);
delete item; delete item;
} }
QVector<BlockItemPin * > BlockItem::takePins() { QVector<BlockItemPin *> BlockItem::takePins() {
QVector<BlockItemPin * > ret = pins(); QVector<BlockItemPin *> ret = pins();
pins_.clear(); pins_.clear();
return ret; return ret;
} }
void BlockItem::clearPins() { void BlockItem::clearPins() {
QList<QVector<BlockItemPin * > > mp = pins_.values(); QList<QVector<BlockItemPin *>> mp = pins_.values();
for (int i = 0; i < mp.size(); ++i) for (int i = 0; i < mp.size(); ++i)
qDeleteAll(mp[i]); qDeleteAll(mp[i]);
pins_.clear(); pins_.clear();
@@ -156,7 +152,7 @@ void BlockItem::clearDecors() {
bool pbs = false; bool pbs = false;
if (scene()) pbs = scene()->blockSignals(true); if (scene()) pbs = scene()->blockSignals(true);
if (scene()) { if (scene()) {
foreach (QGraphicsItem * i, decors_) foreach(QGraphicsItem * i, decors_)
scene()->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close)); scene()->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
} }
qDeleteAll(decors_); qDeleteAll(decors_);
@@ -168,9 +164,9 @@ void BlockItem::clearDecors() {
} }
QVector<BlockItemPin * > BlockItem::pins() const { QVector<BlockItemPin *> BlockItem::pins() const {
QList<QVector<BlockItemPin * > > mp = pins_.values(); QList<QVector<BlockItemPin *>> mp = pins_.values();
QVector<BlockItemPin * > ret; QVector<BlockItemPin *> ret;
for (int i = 0; i < mp.size(); ++i) for (int i = 0; i < mp.size(); ++i)
ret << mp[i]; ret << mp[i];
return ret; return ret;
@@ -186,15 +182,15 @@ QByteArray BlockItem::saveModel() {
void BlockItem::loadModel(const QByteArray & data) { void BlockItem::loadModel(const QByteArray & data) {
//qDebug() << "load from" << data.size() << "bytes"; // qDebug() << "load from" << data.size() << "bytes";
clearPins(); clearPins();
clearDecors(); clearDecors();
col = Qt::lightGray; col = Qt::lightGray;
_resize(QSizeF(100., 60.)); _resize(QSizeF(100., 60.));
if (data.isEmpty()) return; if (data.isEmpty()) return;
ChunkStream cs(data); ChunkStream cs(data);
QVector<BlockItemPin * > tp; QVector<BlockItemPin *> tp;
QList<QGraphicsItem * > dl; QList<QGraphicsItem *> dl;
int version = -1; int version = -1;
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
@@ -204,30 +200,32 @@ void BlockItem::loadModel(const QByteArray & data) {
case 4: setColor(cs.getData<QColor>()); break; case 4: setColor(cs.getData<QColor>()); break;
case 5: case 5:
cs.get(tp); cs.get(tp);
foreach (BlockItemPin * p, tp) addPin(p); foreach(BlockItemPin * p, tp)
addPin(p);
break; break;
case 6: case 6:
cs.get(dl); cs.get(dl);
foreach (QGraphicsItem * d, dl) addDecor(d); foreach(QGraphicsItem * d, dl)
addDecor(d);
break; break;
case 7: setPinsMargin(cs.getData<int>()); break; case 7: setPinsMargin(cs.getData<int>()); break;
case 0xFF: cs.get(version); break; case 0xFF: cs.get(version); break;
} }
} }
if (version <= 0) if (version <= 0) _moveToTop(true);
_moveToTop(true);
} }
QByteArray BlockItem::save() const { QByteArray BlockItem::save() const {
ChunkStream cs; ChunkStream cs;
QMap<QString, QList<BlockItem::Property> > pp; QMap<QString, QList<BlockItem::Property>> pp;
foreach (BlockItemPin * p, pins()) { foreach(BlockItemPin * p, pins()) {
//qDebug() << "save pin" << p->text() << "->" << p->properties().size(); // qDebug() << "save pin" << p->text() << "->" << p->properties().size();
pp[p->text()] = p->properties(); pp[p->text()] = p->properties();
} }
cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, props) << cs.chunk(5, pp) << cs.chunk(6, size()); cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, props) << cs.chunk(5, pp) << cs.chunk(6, size());
cs << cs.chunk(10, data(2000)) << cs.chunk(11, data(2001)) << cs.chunk(12, prop_bindings) << cs.chunk(0xFF, _blockitem_current_version_); cs << cs.chunk(10, data(2000)) << cs.chunk(11, data(2001)) << cs.chunk(12, prop_bindings)
<< cs.chunk(0xFF, _blockitem_current_version_);
return cs.data(); return cs.data();
} }
@@ -235,7 +233,7 @@ QByteArray BlockItem::save() const {
void BlockItem::load(const QByteArray & data) { void BlockItem::load(const QByteArray & data) {
if (data.isEmpty()) return; if (data.isEmpty()) return;
ChunkStream cs(data); ChunkStream cs(data);
QMap<QString, QList<BlockItem::Property> > _p; QMap<QString, QList<BlockItem::Property>> _p;
int version = -1; int version = -1;
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
@@ -244,17 +242,16 @@ void BlockItem::load(const QByteArray & data) {
case 3: cs.get(props); break; case 3: cs.get(props); break;
case 5: case 5:
cs.get(_p); cs.get(_p);
//qDebug() << "load pins" << _p.size(); // qDebug() << "load pins" << _p.size();
foreach (BlockItemPin * p, pins()) { foreach(BlockItemPin * p, pins()) {
//qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text()); // qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text());
if (_p.contains(p->text())) if (_p.contains(p->text())) p->properties() = _p[p->text()];
p->properties() = _p[p->text()];
} }
break; break;
case 6: setSize(cs.getData<QSizeF>()); break; case 6: setSize(cs.getData<QSizeF>()); break;
case 10: setData(2000, cs.getData<QVariant>()); break; case 10: setData(2000, cs.getData<QVariant>()); break;
case 11: setData(2001, cs.getData<QVariant>()); break; case 11: setData(2001, cs.getData<QVariant>()); break;
case 12: prop_bindings = cs.getData<QList<QPair<QString, QString> > >(); break; case 12: prop_bindings = cs.getData<QList<QPair<QString, QString>>>(); break;
case 0xFF: cs.get(version); break; case 0xFF: cs.get(version); break;
} }
} }
@@ -272,8 +269,8 @@ BlockItem * BlockItem::copy() const {
ret->setSelected(false); ret->setSelected(false);
ret->props = props; ret->props = props;
ret->setPinsMargin(pinsMargin()); ret->setPinsMargin(pinsMargin());
QVector<BlockItemPin * > mp = pins(); QVector<BlockItemPin *> mp = pins();
foreach (BlockItemPin * p, mp) { foreach(BlockItemPin * p, mp) {
BlockItemPin * np = new BlockItemPin(); BlockItemPin * np = new BlockItemPin();
np->setBusType(p->busType()); np->setBusType(p->busType());
np->setAlignment(p->alignment()); np->setAlignment(p->alignment());
@@ -283,39 +280,38 @@ BlockItem * BlockItem::copy() const {
ret->addPin(np); ret->addPin(np);
} }
QByteArray ba; QByteArray ba;
foreach (QGraphicsItem * i, decors_) { foreach(QGraphicsItem * i, decors_) {
ba.clear(); ba.clear();
QGraphicsItem * ni = 0; QGraphicsItem * ni = 0;
QDataStream s(&ba, QIODevice::ReadWrite); s << i; QDataStream s(&ba, QIODevice::ReadWrite);
QDataStream s2(ba); s2 >> ni; s << i;
if (ni) QDataStream s2(ba);
ret->addDecor(ni); s2 >> ni;
if (ni) ret->addDecor(ni);
} }
return ret; return ret;
} }
QList<BlockBusItem * > BlockItem::connectedBuses() const { QList<BlockBusItem *> BlockItem::connectedBuses() const {
QList<BlockBusItem * > ret; QList<BlockBusItem *> ret;
foreach (BlockItemPin * p, pins()) foreach(BlockItemPin * p, pins())
ret << p->connectedBuses(); ret << p->connectedBuses();
return ret; return ret;
} }
BlockItemPin * BlockItem::pinByText(const QString & t) const { BlockItemPin * BlockItem::pinByText(const QString & t) const {
foreach (BlockItemPin * p, pins()) foreach(BlockItemPin * p, pins())
if (p->text() == t) if (p->text() == t) return p;
return p;
return 0; return 0;
} }
BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const { BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const {
if (bus == 0) return 0; if (bus == 0) return 0;
foreach (BlockItemPin * p, pins()) foreach(BlockItemPin * p, pins())
if (p->connectedBuses().contains(bus)) if (p->connectedBuses().contains(bus)) return p;
return p;
return 0; return 0;
} }
@@ -337,7 +333,8 @@ void BlockItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
anim_thick.setStartValue(thickness()); anim_thick.setStartValue(thickness());
anim_thick.setEndValue(2.5); anim_thick.setEndValue(2.5);
anim_thick.start(); anim_thick.start();
} else setThickness(2.5); } else
setThickness(2.5);
emit blockHoverEnter(this); emit blockHoverEnter(this);
} }
@@ -349,7 +346,8 @@ void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
anim_thick.setStartValue(thickness()); anim_thick.setStartValue(thickness());
anim_thick.setEndValue(1); anim_thick.setEndValue(1);
anim_thick.start(); anim_thick.start();
} else setThickness(1); } else
setThickness(1);
emit blockHoverLeave(this); emit blockHoverLeave(this);
} }
@@ -357,25 +355,29 @@ void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
#define _POS(m) (i - ((cp.size() - 1) / 2)) * m #define _POS(m) (i - ((cp.size() - 1) / 2)) * m
void BlockItem::arrangePins() { void BlockItem::arrangePins() {
QVector<BlockItemPin * > pl = pins(); QVector<BlockItemPin *> pl = pins();
pins_.clear(); pins_.clear();
foreach (BlockItemPin * p, pl) foreach(BlockItemPin * p, pl)
pins_[p->alignment()] << p; pins_[p->alignment()] << p;
QVector<BlockItemPin * > cp = pins_.value(Qt::AlignBottom); QVector<BlockItemPin *> cp = pins_.value(Qt::AlignBottom);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), bottom()); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(_POS(pins_margin), bottom());
cp = pins_.value(Qt::AlignTop); cp = pins_.value(Qt::AlignTop);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), top()); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(_POS(pins_margin), top());
cp = pins_.value(Qt::AlignLeft); cp = pins_.value(Qt::AlignLeft);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(left(), i * pins_margin); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(left(), i * pins_margin);
cp = pins_.value(Qt::AlignRight); cp = pins_.value(Qt::AlignRight);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(right(), i * pins_margin); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(right(), i * pins_margin);
} }
#undef _POS #undef _POS
void BlockItem::removeBindings(const QString & bind_name) { void BlockItem::removeBindings(const QString & bind_name) {
for(int i=0; i<prop_bindings.size(); ++i) { for (int i = 0; i < prop_bindings.size(); ++i) {
if (prop_bindings[i].second == bind_name) { if (prop_bindings[i].second == bind_name) {
prop_bindings.removeAt(i); prop_bindings.removeAt(i);
i--; i--;
@@ -385,7 +387,7 @@ void BlockItem::removeBindings(const QString & bind_name) {
void BlockItem::removeBindingByProperty(const QString & prop_name) { void BlockItem::removeBindingByProperty(const QString & prop_name) {
for(int i=0; i<prop_bindings.size(); ++i) { for (int i = 0; i < prop_bindings.size(); ++i) {
if (prop_bindings[i].first == prop_name) { if (prop_bindings[i].first == prop_name) {
prop_bindings.removeAt(i); prop_bindings.removeAt(i);
i--; i--;
@@ -402,7 +404,7 @@ void BlockItem::addBinding(const QString & prop_name, const QString & bind_name)
void BlockItem::applyBinding(const QString & bind_name, const QVariant & bind_value) { void BlockItem::applyBinding(const QString & bind_name, const QVariant & bind_value) {
for(int i=0; i<prop_bindings.size(); ++i) { for (int i = 0; i < prop_bindings.size(); ++i) {
if (prop_bindings[i].second == bind_name) { if (prop_bindings[i].second == bind_name) {
setPropertyValue(prop_bindings[i].first, bind_value); setPropertyValue(prop_bindings[i].first, bind_value);
} }
@@ -411,7 +413,7 @@ void BlockItem::applyBinding(const QString & bind_name, const QVariant & bind_va
void BlockItem::applyBindings(const PropertyStorage & bindings) { void BlockItem::applyBindings(const PropertyStorage & bindings) {
for(int i=0; i<prop_bindings.size(); ++i) { for (int i = 0; i < prop_bindings.size(); ++i) {
if (bindings.isPropertyExists(prop_bindings[i].second)) { if (bindings.isPropertyExists(prop_bindings[i].second)) {
setPropertyValue(prop_bindings[i].first, bindings.propertyValueByName(prop_bindings[i].second)); setPropertyValue(prop_bindings[i].first, bindings.propertyValueByName(prop_bindings[i].second));
} }
@@ -419,18 +421,18 @@ void BlockItem::applyBindings(const PropertyStorage & bindings) {
} }
void BlockItem::setBindings(const QList<QPair<QString, QString> > & bindings) { void BlockItem::setBindings(const QList<QPair<QString, QString>> & bindings) {
prop_bindings = bindings; prop_bindings = bindings;
} }
QList<QPair<QString, QString> > BlockItem::getBindings() { QList<QPair<QString, QString>> BlockItem::getBindings() {
return prop_bindings; return prop_bindings;
} }
QString BlockItem::getBindName(const QString & prop_name) const { QString BlockItem::getBindName(const QString & prop_name) const {
for(int i=0; i<prop_bindings.size(); ++i) { for (int i = 0; i < prop_bindings.size(); ++i) {
if (prop_bindings[i].first == prop_name) { if (prop_bindings[i].first == prop_name) {
return prop_bindings[i].second; return prop_bindings[i].second;
} }
@@ -441,14 +443,14 @@ QString BlockItem::getBindName(const QString & prop_name) const {
QStringList BlockItem::getBindNames() const { QStringList BlockItem::getBindNames() const {
QStringList ret; QStringList ret;
for(int i=0; i<prop_bindings.size(); ++i) for (int i = 0; i < prop_bindings.size(); ++i)
if (!ret.contains(prop_bindings[i].second)) ret << prop_bindings[i].second; if (!ret.contains(prop_bindings[i].second)) ret << prop_bindings[i].second;
return ret; return ret;
} }
QStringList BlockItem::getBindProps() const { QStringList BlockItem::getBindProps() const {
QStringList ret; QStringList ret;
for(int i=0; i<prop_bindings.size(); ++i) for (int i = 0; i < prop_bindings.size(); ++i)
ret << prop_bindings[i].first; ret << prop_bindings[i].first;
return ret; return ret;
} }
@@ -456,7 +458,7 @@ QStringList BlockItem::getBindProps() const {
QVariant BlockItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) { QVariant BlockItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
if (change == QGraphicsItem::ItemSelectedChange) { if (change == QGraphicsItem::ItemSelectedChange) {
// qDebug() << "select" << value.toBool(); // qDebug() << "select" << value.toBool();
if (value.toBool() && !isSelected() && ((BlockView *)scene()->views().back())->isBlockAnimationEnabled() && t_sel.elapsed() > 50) { if (value.toBool() && !isSelected() && ((BlockView *)scene()->views().back())->isBlockAnimationEnabled() && t_sel.elapsed() > 50) {
g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 16)); g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 16));
anim_sel.setStartValue(selectionRect()); anim_sel.setStartValue(selectionRect());
@@ -490,4 +492,3 @@ QRectF BlockItem::selectionRect() const {
void BlockItem::setSelectionRect(const QRectF & r) { void BlockItem::setSelectionRect(const QRectF & r) {
g_selection.setRect(r); g_selection.setRect(r);
} }
+68 -51
View File
@@ -1,38 +1,41 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKITEM_H #ifndef BLOCKITEM_H
#define BLOCKITEM_H #define BLOCKITEM_H
#include <QElapsedTimer>
#include "blockitempin.h" #include "blockitempin.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QElapsedTimer>
class QAD_BLOCKVIEW_EXPORT BlockItem: public QGraphicsObject, public PropertyStorage
{ class QAD_BLOCKVIEW_EXPORT BlockItem
: public QGraphicsObject
, public PropertyStorage {
friend class BlockView; friend class BlockView;
friend class BlockItemPin; friend class BlockItemPin;
friend class DrawTools; friend class DrawTools;
Q_OBJECT Q_OBJECT
Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false)
Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false)
public: public:
BlockItem(QGraphicsItem * parent = 0); BlockItem(QGraphicsItem * parent = 0);
~BlockItem(); ~BlockItem();
@@ -44,26 +47,32 @@ public:
void addDecor(QGraphicsItem * item); void addDecor(QGraphicsItem * item);
void addDecor(QGraphicsItem & item); void addDecor(QGraphicsItem & item);
void removeDecor(QGraphicsItem * item); void removeDecor(QGraphicsItem * item);
QVector<BlockItemPin * > takePins(); QVector<BlockItemPin *> takePins();
void clearPins(); void clearPins();
void clearDecors(); void clearDecors();
QVector<BlockItemPin * > pins() const; QVector<BlockItemPin *> pins() const;
QList<QGraphicsItem * > decors() const {return decors_;} QList<QGraphicsItem *> decors() const { return decors_; }
QList<BlockBusItem * > connectedBuses() const; QList<BlockBusItem *> connectedBuses() const;
BlockItemPin * pinByText(const QString & t) const; BlockItemPin * pinByText(const QString & t) const;
BlockItemPin * pinAtBus(BlockBusItem * bus) const; BlockItemPin * pinAtBus(BlockBusItem * bus) const;
QColor color() const {return col;} QColor color() const { return col; }
void setColor(QColor c) {col = c; _resize(size());} void setColor(QColor c) {
QSizeF size() const {return g_main.rect().size();} col = c;
_resize(size());
}
QSizeF size() const { return g_main.rect().size(); }
QRectF sceneRect() const; QRectF sceneRect() const;
qreal width() const {return size().width();} qreal width() const { return size().width(); }
qreal height() const {return size().height();} qreal height() const { return size().height(); }
int pinsMargin() const {return pins_margin;} int pinsMargin() const { return pins_margin; }
void setSize(QSizeF s) {_resize(s);} void setSize(QSizeF s) { _resize(s); }
void setSize(qreal w, qreal h) {setSize(QSizeF(w, h));} void setSize(qreal w, qreal h) { setSize(QSizeF(w, h)); }
void setWidth(qreal w) {setSize(QSizeF(w, size().height()));} void setWidth(qreal w) { setSize(QSizeF(w, size().height())); }
void setHeight(qreal h) {setSize(QSizeF(size().width(), h));} void setHeight(qreal h) { setSize(QSizeF(size().width(), h)); }
void setPinsMargin(int marg) {if (marg > 1 && marg < 256) pins_margin = marg; arrangePins();} void setPinsMargin(int marg) {
if (marg > 1 && marg < 256) pins_margin = marg;
arrangePins();
}
QByteArray saveModel(); QByteArray saveModel();
void loadModel(const QByteArray & data); void loadModel(const QByteArray & data);
@@ -76,34 +85,36 @@ public:
void addBinding(const QString & prop_name, const QString & bind_name); void addBinding(const QString & prop_name, const QString & bind_name);
void applyBinding(const QString & bind_name, const QVariant & bind_value); void applyBinding(const QString & bind_name, const QVariant & bind_value);
void applyBindings(const PropertyStorage & bindings); void applyBindings(const PropertyStorage & bindings);
void setBindings(const QList<QPair<QString, QString> > & bindings); void setBindings(const QList<QPair<QString, QString>> & bindings);
QList<QPair<QString, QString> > getBindings(); QList<QPair<QString, QString>> getBindings();
QString getBindName(const QString & prop_name) const; QString getBindName(const QString & prop_name) const;
QStringList getBindNames() const; QStringList getBindNames() const;
QStringList getBindProps() const; QStringList getBindProps() const;
enum {Type = UserType + 1}; enum {
Type = UserType + 1
};
protected: protected:
void _resize(QSizeF s); void _resize(QSizeF s);
void _moveToTop(bool only_decors = false); void _moveToTop(bool only_decors = false);
int type() const {return Type;} int type() const { return Type; }
QRectF boundingRect() const; QRectF boundingRect() const;
void hoverEnterEvent(QGraphicsSceneHoverEvent * event); void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent * event); void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
double left() const {return boundingRect().left();} double left() const { return boundingRect().left(); }
double right() const {return boundingRect().right();} double right() const { return boundingRect().right(); }
double top() const {return boundingRect().top();} double top() const { return boundingRect().top(); }
double bottom() const {return boundingRect().bottom();} double bottom() const { return boundingRect().bottom(); }
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = nullptr) {} void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = nullptr) {}
QVariant itemChange(GraphicsItemChange change, const QVariant & value); QVariant itemChange(GraphicsItemChange change, const QVariant & value);
QGraphicsRectItem g_main, g_selection; QGraphicsRectItem g_main, g_selection;
int pins_margin; int pins_margin;
QColor col; QColor col;
QMap<Qt::Alignment, QVector<BlockItemPin * > > pins_; QMap<Qt::Alignment, QVector<BlockItemPin *>> pins_;
QList<QGraphicsItem * > decors_; QList<QGraphicsItem *> decors_;
QList<QPair<QString, QString> > prop_bindings; // <property_name, binding_name> QList<QPair<QString, QString>> prop_bindings; // <property_name, binding_name>
private: private:
double thickness() const; double thickness() const;
@@ -120,28 +131,34 @@ signals:
}; };
inline QDataStream & operator <<(QDataStream & s, const BlockItemPin * p) { inline QDataStream & operator<<(QDataStream & s, const BlockItemPin * p) {
ChunkStream cs; ChunkStream cs;
cs << cs.chunk(1, int(p->alignment())) << cs.chunk(2, p->busType()) << cs.chunk(3, p->text()) << cs.chunk(4, p->toolTip()); cs << cs.chunk(1, int(p->alignment())) << cs.chunk(2, p->busType()) << cs.chunk(3, p->text()) << cs.chunk(4, p->toolTip());
s << cs.data(); return s;} s << cs.data();
inline QDataStream & operator >>(QDataStream & s, BlockItemPin *& p) { return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockItemPin *& p) {
ChunkStream cs(s); ChunkStream cs(s);
p = new BlockItemPin(); p = new BlockItemPin();
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1: p->setAlignment((Qt::Alignment)cs.getData<int>()); break; case 1: p->setAlignment((Qt::Alignment)cs.getData<int>()); break;
case 2: p->setBusType(cs.getData<int>()); break; case 2: p->setBusType(cs.getData<int>()); break;
case 3: p->setText(cs.getData<QString>()); break; case 3: p->setText(cs.getData<QString>()); break;
case 4: p->setToolTip(cs.getData<QString>()); break; case 4: p->setToolTip(cs.getData<QString>()); break;
} }
} }
return s; return s;
} }
inline QDataStream & operator <<(QDataStream & s, const BlockItem * b) {s << b->save(); return s;} inline QDataStream & operator<<(QDataStream & s, const BlockItem * b) {
inline QDataStream & operator >>(QDataStream & s, BlockItem *& b) { s << b->save();
QByteArray ba; s >> ba; return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockItem *& b) {
QByteArray ba;
s >> ba;
b = new BlockItem(); b = new BlockItem();
b->load(ba); b->load(ba);
return s; return s;
+47 -27
View File
@@ -1,19 +1,23 @@
#include "blockview.h" #include "blockview.h"
#include <QApplication> #include <QApplication>
BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsObject * _parent): QGraphicsObject(_parent), ell_item(this), text_item(this) { BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsObject * _parent)
: QGraphicsObject(_parent)
, ell_item(this)
, text_item(this) {
parent_ = 0; parent_ = 0;
setData(bvidType, bvitPin); setData(bvidType, bvitPin);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
text_item.setData(bvidMoveParent, true); text_item.setData(bvidMoveParent, true);
ell_item.setData(bvidVisualizeSelection, true); ell_item.setData(bvidVisualizeSelection, true);
br[Disconnected] = QBrush(Qt::lightGray); br[Disconnected] = QBrush(Qt::lightGray);
br[Connected] = QBrush(Qt::darkGreen); br[Connected] = QBrush(Qt::darkGreen);
br[Hover] = QBrush(Qt::blue); br[Hover] = QBrush(Qt::blue);
br[Drop] = QBrush(Qt::green); br[Drop] = QBrush(Qt::green);
br[Accept] = QBrush(Qt::green); br[Accept] = QBrush(Qt::green);
br[Reject] = QBrush(Qt::red); br[Reject] = QBrush(Qt::red);
anim_pin_size.setTargetObject(this); anim_pin_size.setTargetObject(this);
anim_pin_size.setPropertyName("pinSize"); anim_pin_size.setPropertyName("pinSize");
anim_pin_size.setEasingCurve(QEasingCurve::OutElastic); anim_pin_size.setEasingCurve(QEasingCurve::OutElastic);
@@ -42,7 +46,7 @@ void BlockItemPin::animAccept() {
void BlockItemPin::setState(State s) { void BlockItemPin::setState(State s) {
State os = state_; State os = state_;
state_ = s; state_ = s;
setBrush(br[int(state_)]); setBrush(br[int(state_)]);
if (s == Accept && os != Accept) { if (s == Accept && os != Accept) {
animAccept(); animAccept();
@@ -61,8 +65,7 @@ void BlockItemPin::enlargePin(bool enlarge) {
resizePin(sz); resizePin(sz);
return; return;
} }
if (sz == anim_pin_size.endValue()) if (sz == anim_pin_size.endValue()) return;
return;
anim_pin_size.stop(); anim_pin_size.stop();
anim_pin_size.setStartValue(pinSize()); anim_pin_size.setStartValue(pinSize());
anim_pin_size.setEndValue(sz); anim_pin_size.setEndValue(sz);
@@ -71,7 +74,7 @@ void BlockItemPin::enlargePin(bool enlarge) {
void BlockItemPin::resizePin(double r) { void BlockItemPin::resizePin(double r) {
ell_item.setRect(-r, -r, r+r, r+r); ell_item.setRect(-r, -r, r + r, r + r);
} }
@@ -90,29 +93,44 @@ void BlockItemPin::animationAccept() {
void BlockItemPin::_init(bool affect_parent) { void BlockItemPin::_init(bool affect_parent) {
text_item.setFont(AlignedTextItem::sceneFont(QApplication::font())); text_item.setFont(AlignedTextItem::sceneFont(QApplication::font()));
QRectF tbr = text_item.boundingRect(); QRectF tbr = text_item.boundingRect();
const double r = 7.; const double r = 7.;
ell_item.setRect(-r, -r, r+r, r+r); ell_item.setRect(-r, -r, r + r, r + r);
ell_item.setSpanAngle(16*180); ell_item.setSpanAngle(16 * 180);
text_item.resetTransform(); text_item.resetTransform();
text_item.setPos(0, -tbr.height() / 2.); text_item.setPos(0, -tbr.height() / 2.);
text_item.setTransformOriginPoint(0, tbr.height() / 2.); text_item.setTransformOriginPoint(0, tbr.height() / 2.);
switch (align) { switch (align) {
case Qt::AlignBottom: ell_item.setStartAngle(16*0); text_item.setRotation(-90.); text_item.moveBy(0, -r * 1.5); break; case Qt::AlignBottom:
case Qt::AlignRight: ell_item.setStartAngle(16*90); text_item.setRotation(0.); text_item.moveBy(-tbr.width() - r * 1.5, 0); break; ell_item.setStartAngle(16 * 0);
case Qt::AlignTop: ell_item.setStartAngle(16*180); text_item.setRotation(-90.); text_item.moveBy(0, tbr.width() + r * 1.5); break; text_item.setRotation(-90.);
case Qt::AlignLeft: ell_item.setStartAngle(16*270); text_item.setRotation(0.); text_item.moveBy(r * 1.5, 0); break; text_item.moveBy(0, -r * 1.5);
break;
case Qt::AlignRight:
ell_item.setStartAngle(16 * 90);
text_item.setRotation(0.);
text_item.moveBy(-tbr.width() - r * 1.5, 0);
break;
case Qt::AlignTop:
ell_item.setStartAngle(16 * 180);
text_item.setRotation(-90.);
text_item.moveBy(0, tbr.width() + r * 1.5);
break;
case Qt::AlignLeft:
ell_item.setStartAngle(16 * 270);
text_item.setRotation(0.);
text_item.moveBy(r * 1.5, 0);
break;
default: break; default: break;
} }
if (affect_parent && parent_) if (affect_parent && parent_) parent_->arrangePins();
parent_->arrangePins();
} }
void BlockItemPin::_reparent() { void BlockItemPin::_reparent() {
if (parentItem() == 0) return; if (parentItem() == 0) return;
if (qgraphicsitem_cast<BlockItem*>(parentItem()) == 0) return; if (qgraphicsitem_cast<BlockItem *>(parentItem()) == 0) return;
QPen p = qgraphicsitem_cast<BlockItem*>(parentItem())->g_main.pen(); QPen p = qgraphicsitem_cast<BlockItem *>(parentItem())->g_main.pen();
ell_item.setPen(p); ell_item.setPen(p);
if (scene()) { if (scene()) {
text_item.setFont(AlignedTextItem::sceneFont(scene()->font())); text_item.setFont(AlignedTextItem::sceneFont(scene()->font()));
@@ -132,18 +150,20 @@ QGraphicsView * BlockItemPin::_view() const {
QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) { QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
if (change == QGraphicsItem::ItemParentChange) if (change == QGraphicsItem::ItemParentChange) _reparent();
_reparent();
return QGraphicsItem::itemChange(change, value); return QGraphicsItem::itemChange(change, value);
} }
void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
QGraphicsView * v = _view(); QGraphicsView * v = _view();
bool m_pin_mc = false; bool m_pin_mc = false;
if (v) { if (v) {
qobject_cast<BlockView*>(v)->getPinMC(&m_pin_mc); qobject_cast<BlockView *>(v)->getPinMC(&m_pin_mc);
QMetaObject::invokeMethod(v, [this, v](){qobject_cast<BlockView*>(v)->pinHoverInOut(this);}, Qt::QueuedConnection); QMetaObject::invokeMethod(
v,
[this, v]() { qobject_cast<BlockView *>(v)->pinHoverInOut(this); },
Qt::QueuedConnection);
} }
if ((state() != Disconnected) && !m_pin_mc) return; if ((state() != Disconnected) && !m_pin_mc) return;
saveState(); saveState();
@@ -159,6 +179,6 @@ void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
enlargePin(false); enlargePin(false);
update(); update();
if (v) { if (v) {
qobject_cast<BlockView*>(v)->pinHoverInOut(nullptr); qobject_cast<BlockView *>(v)->pinHoverInOut(nullptr);
} }
} }
+62 -46
View File
@@ -1,50 +1,53 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKITEMPIN_H #ifndef BLOCKITEMPIN_H
#define BLOCKITEMPIN_H #define BLOCKITEMPIN_H
#include <QGraphicsView> #include "alignedtextitem.h"
#include <QGraphicsScene> #include "blockbase.h"
#include <QGraphicsObject> #include "qad_blockview_export.h"
#include <QDebug>
#include <QGraphicsEllipseItem> #include <QGraphicsEllipseItem>
#include <QGraphicsObject>
#include <QGraphicsScene>
#include <QGraphicsSceneHoverEvent> #include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QStack> #include <QGraphicsView>
#include <QDebug>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QStack>
#include <qmath.h> #include <qmath.h>
#include "blockbase.h"
#include "alignedtextitem.h"
#include "qad_blockview_export.h"
class BlockItem; class BlockItem;
class BlockBusItem; class BlockBusItem;
class QAD_BLOCKVIEW_EXPORT BlockItemPin: public QGraphicsObject, public PropertyStorage class QAD_BLOCKVIEW_EXPORT BlockItemPin
{ : public QGraphicsObject
, public PropertyStorage {
friend class BlockView; friend class BlockView;
friend class BlockItem; friend class BlockItem;
Q_OBJECT Q_OBJECT
Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false)
public: public:
BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0); BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0);
@@ -58,45 +61,59 @@ public:
}; };
enum Direction { enum Direction {
None = 0x0, None = 0x0,
Input = 0x1, Input = 0x1,
Output = 0x2, Output = 0x2,
InputOutput = 0x3 InputOutput = 0x3
}; };
void setPen(const QPen & p) {ell_item.setPen(p);} void setPen(const QPen & p) { ell_item.setPen(p); }
QPen pen() const {return ell_item.pen();} QPen pen() const { return ell_item.pen(); }
void setBrush(const QBrush & b) {ell_item.setBrush(b);} void setBrush(const QBrush & b) { ell_item.setBrush(b); }
QBrush brush() const {return ell_item.brush();} QBrush brush() const { return ell_item.brush(); }
int busType() const {return bus_type;} int busType() const { return bus_type; }
Qt::Alignment alignment() const {return align;} Qt::Alignment alignment() const { return align; }
QString text() const {return text_item.text();} QString text() const { return text_item.text(); }
State state() const {return state_;} State state() const { return state_; }
void setBusType(int type_) {bus_type = type_;} void setBusType(int type_) { bus_type = type_; }
void setAlignment(Qt::Alignment a) {align = a; _init(true);} void setAlignment(Qt::Alignment a) {
void setText(const QString & t) {text_item.setText(t); _init(true);} align = a;
_init(true);
}
void setText(const QString & t) {
text_item.setText(t);
_init(true);
}
void setState(State s); void setState(State s);
void saveState() {sstate_.push(state_);} void saveState() { sstate_.push(state_); }
bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;} bool restoreState() {
void clearStateStack() {sstate_.clear();} if (sstate_.isEmpty()) return false;
setState(sstate_.pop());
return true;
}
void clearStateStack() { sstate_.clear(); }
void enlargePin(bool enlarge); void enlargePin(bool enlarge);
BlockItem * parent() const {return parent_;} BlockItem * parent() const { return parent_; }
QList<BlockBusItem * > connectedBuses() const {return buses_;} QList<BlockBusItem *> connectedBuses() const { return buses_; }
enum {Type = UserType + 3}; enum {
Type = UserType + 3
};
public slots: public slots:
void animAccept(); void animAccept();
protected: protected:
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {} void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {}
QRectF boundingRect() const {return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());} QRectF boundingRect() const {
int type() const {return Type;} return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());
}
int type() const { return Type; }
QVariant itemChange(GraphicsItemChange change, const QVariant & value); QVariant itemChange(GraphicsItemChange change, const QVariant & value);
void hoverEnterEvent(QGraphicsSceneHoverEvent * e); void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
void hoverLeaveEvent(QGraphicsSceneHoverEvent * e); void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
@@ -108,7 +125,7 @@ protected:
QGraphicsEllipseItem ell_item; QGraphicsEllipseItem ell_item;
QGraphicsSimpleTextItem text_item; QGraphicsSimpleTextItem text_item;
QStack<State> sstate_; QStack<State> sstate_;
QList<BlockBusItem * > buses_; QList<BlockBusItem *> buses_;
BlockItem * parent_; BlockItem * parent_;
Qt::Alignment align; Qt::Alignment align;
QBrush br[6]; QBrush br[6];
@@ -122,7 +139,6 @@ private:
QPropertyAnimation anim_pin_size; QPropertyAnimation anim_pin_size;
QPropertyAnimation anim_accept; QPropertyAnimation anim_accept;
}; };
+472 -487
View File
@@ -1,15 +1,17 @@
#include "blockview.h" #include "blockview.h"
#include "qad_types.h" #include "qad_types.h"
#include <qmath.h>
#include <QScrollBar>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>
#include <QAction> #include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QElapsedTimer>
#include <QGraphicsSceneMouseEvent>
#include <QMimeData>
#include <QScrollBar>
#include <QShortcut> #include <QShortcut>
#include <QVector2D> #include <QVector2D>
#include <QClipboard> #include <qmath.h>
#include <QMimeData>
#include <QElapsedTimer>
const QString _BlockView_Mime_ = "_BlockView_copypaste_"; const QString _BlockView_Mime_ = "_BlockView_copypaste_";
@@ -24,33 +26,32 @@ BlockView::BlockView(QGraphicsScene * scene, QWidget * parent): QGraphicsView(sc
} }
BlockView::~BlockView() { BlockView::~BlockView() {}
}
void BlockView::_init() { void BlockView::_init() {
qRegisterMetaType<BlockItem*>(); qRegisterMetaType<BlockItem *>();
qRegisterMetaType<BlockItemPin*>(); qRegisterMetaType<BlockItemPin *>();
qRegisterMetaType<BlockBusItem*>(); qRegisterMetaType<BlockBusItem *>();
grid_visible = grid_snap = pm_connect = navigation = m_connect = m_trace_with_buses = prev_tcb = minimap = true; grid_visible = grid_snap = pm_connect = navigation = m_connect = m_trace_with_buses = prev_tcb = minimap = true;
mm_drag = moved = new_branch = new_bus = mm_cancel = iconnect = mm_copy = m_pin_mc = mm_thumb = move_bus_point = wheel_zoom = false; mm_drag = moved = new_branch = new_bus = mm_cancel = iconnect = mm_copy = m_pin_mc = mm_thumb = move_bus_point = wheel_zoom = false;
match_bus = bus_from = cur_bus = 0; match_bus = bus_from = cur_bus = 0;
mm_ci = 0; mm_ci = 0;
hpin = 0; hpin = 0;
ghost_ = 0; ghost_ = 0;
grid_step = 10.; grid_step = 10.;
grid_points = 1; grid_points = 1;
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 1, Qt::NoPen); grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 1, Qt::NoPen);
thick = 1; thick = 1;
thumb_hide_delay = 500; thumb_hide_delay = 500;
timer_thumb = 0; timer_thumb = 0;
smode = BlockView::MultiSelection; smode = BlockView::MultiSelection;
cur_scl = thumb_scl = prev_app_scale = 1.; cur_scl = thumb_scl = prev_app_scale = 1.;
_talpha = 0.; _talpha = 0.;
ae_enabled = is_block_anim = is_nav_anim = true; ae_enabled = is_block_anim = is_nav_anim = true;
nav_prev_aa = nav_prev_imaa = nav_prev_grid = true; nav_prev_aa = nav_prev_imaa = nav_prev_grid = true;
square_node = block_emit_selection = false; square_node = block_emit_selection = false;
thumb_size = QSizeF(200, 200); thumb_size = QSizeF(200, 200);
if (scene() == 0) { if (scene() == 0) {
scene_ = new QGraphicsScene; scene_ = new QGraphicsScene;
setScene(scene_); setScene(scene_);
@@ -120,18 +121,12 @@ bool BlockView::event(QEvent * e) {
bool BlockView::eventFilter(QObject * o, QEvent * e) { bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (o == &widget_thumb) { if (o == &widget_thumb) {
QMouseEvent * me = (QMouseEvent*)e; QMouseEvent * me = (QMouseEvent *)e;
if(!me) return true; if (!me) return true;
switch (e->type()) { switch (e->type()) {
case QEvent::Paint: case QEvent::Paint: drawThumb(); return true;
drawThumb(); case QEvent::Enter: thumbShow(); break;
return true; case QEvent::Leave: restartTimer(timer_thumb, thumb_hide_delay); break;
case QEvent::Enter:
thumbShow();
break;
case QEvent::Leave:
restartTimer(timer_thumb, thumb_hide_delay);
break;
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:
thumb_press = me->pos(); thumb_press = me->pos();
widget_thumb.setCursor(Qt::ClosedHandCursor); widget_thumb.setCursor(Qt::ClosedHandCursor);
@@ -140,12 +135,9 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
scrollFromThumb(); scrollFromThumb();
} }
break; break;
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease: widget_thumb.setCursor(Qt::OpenHandCursor); break;
widget_thumb.setCursor(Qt::OpenHandCursor);
break;
case QEvent::MouseMove: case QEvent::MouseMove:
if (me->buttons() == 0) if (me->buttons() == 0) widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
if (me->buttons().testFlag(Qt::LeftButton)) { if (me->buttons().testFlag(Qt::LeftButton)) {
thumb_vr.translate(me->pos() - thumb_press); thumb_vr.translate(me->pos() - thumb_press);
scrollFromThumb(); scrollFromThumb();
@@ -157,24 +149,30 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
return QGraphicsView::eventFilter(o, e); return QGraphicsView::eventFilter(o, e);
} }
if (o == scene_) { if (o == scene_) {
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent*)e; QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent *)e;
QList<QGraphicsItem * > mil; QList<QGraphicsItem *> mil;
QPointF mdp; QPointF mdp;
bool fmm_drag = false; bool fmm_drag = false;
int btncnt = 0; int btncnt = 0;
switch (e->type()) { switch (e->type()) {
case QEvent::GraphicsSceneMouseDoubleClick: case QEvent::GraphicsSceneMouseDoubleClick:
scene_point = me->scenePos(); scene_point = me->scenePos();
mil = scene_->items(scene_point); mil = scene_->items(scene_point);
foreach (QGraphicsItem * i, mil) { foreach(QGraphicsItem * i, mil) {
if (i->data(bvidTmpItem).toBool()) continue; if (i->data(bvidTmpItem).toBool()) continue;
if (i->data(bvidType).toInt() == bvitBlock) { if (i->data(bvidType).toInt() == bvitBlock) {
QMetaObject::invokeMethod(this, [this, i](){blockDoubleClicked(qgraphicsitem_cast<BlockItem*>(i));}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this, i]() { blockDoubleClicked(qgraphicsitem_cast<BlockItem *>(i)); },
Qt::QueuedConnection);
return true; return true;
} }
if (i->data(bvidType).toInt() == bvitBus) { if (i->data(bvidType).toInt() == bvitBus) {
if (qgraphicsitem_cast<BlockBusItem*>(i)->isBusSelected()) { if (qgraphicsitem_cast<BlockBusItem *>(i)->isBusSelected()) {
QMetaObject::invokeMethod(this, [this, i](){busDoubleClicked(qgraphicsitem_cast<BlockBusItem*>(i));}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this, i]() { busDoubleClicked(qgraphicsitem_cast<BlockBusItem *>(i)); },
Qt::QueuedConnection);
return true; return true;
} }
} }
@@ -187,23 +185,23 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
break; break;
} }
} }
if (me->buttons().testFlag(Qt::LeftButton )) btncnt++; if (me->buttons().testFlag(Qt::LeftButton)) btncnt++;
if (me->buttons().testFlag(Qt::RightButton)) btncnt++; if (me->buttons().testFlag(Qt::RightButton)) btncnt++;
if (me->buttons().testFlag(QT_MID_BUTTON )) btncnt++; if (me->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
mm_cancel = btncnt >= 2; mm_cancel = btncnt >= 2;
match_bus = bus_from = 0; match_bus = bus_from = 0;
hpin = 0; hpin = 0;
copy_dp = QPointF(); copy_dp = QPointF();
//qDebug() << mm_cancel << moved << sel_rect.isVisible(); // qDebug() << mm_cancel << moved << sel_rect.isVisible();
if (sel_rect.isVisible()) { if (sel_rect.isVisible()) {
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
block_emit_selection = true; block_emit_selection = true;
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
i->setSelected(i->data(bvidSelected).toBool()); i->setSelected(i->data(bvidSelected).toBool());
block_emit_selection = false; block_emit_selection = false;
emit selectionChanged(); emit selectionChanged();
} }
//qDebug() << "cur_bus" << cur_bus; // qDebug() << "cur_bus" << cur_bus;
if (cur_bus) { if (cur_bus) {
return false; return false;
} }
@@ -235,30 +233,30 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
mm_mods = me->modifiers(); mm_mods = me->modifiers();
mm_drag = moved = false; mm_drag = moved = false;
screen_point = me->screenPos(); screen_point = me->screenPos();
scene_point = me->scenePos(); scene_point = me->scenePos();
if ((me->button() == QT_MID_BUTTON) || (me->button() == Qt::RightButton)) { if ((me->button() == QT_MID_BUTTON) || (me->button() == Qt::RightButton)) {
thumbShow(); thumbShow();
restartTimer(timer_thumb, thumb_hide_delay); restartTimer(timer_thumb, thumb_hide_delay);
return true; return true;
} }
mil = scene_->items(scene_point); mil = scene_->items(scene_point);
//qDebug() << "mil" << mil; // qDebug() << "mil" << mil;
while (!mil.isEmpty()) { while (!mil.isEmpty()) {
mm_ci = mil.front(); mm_ci = mil.front();
if (mm_ci->data(bvidDTHandle).toBool()) return QGraphicsView::eventFilter(o, e); if (mm_ci->data(bvidDTHandle).toBool()) return QGraphicsView::eventFilter(o, e);
if (mm_ci->data(bvidTmpItem).toBool() || mm_ci->data(bvidItemSelection).toBool()) { if (mm_ci->data(bvidTmpItem).toBool() || mm_ci->data(bvidItemSelection).toBool()) {
mil.pop_front(); mil.pop_front();
} else break; } else
break;
} }
if (mil.isEmpty()) { if (mil.isEmpty()) {
mm_ci = 0; mm_ci = 0;
return true; return true;
} }
while (mm_ci->data(bvidType).toInt() == bvitBus) { while (mm_ci->data(bvidType).toInt() == bvitBus) {
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci)) if (qgraphicsitem_cast<BlockBusItem *>(mm_ci))
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci)->isBusSelected()) if (qgraphicsitem_cast<BlockBusItem *>(mm_ci)->isBusSelected()) break;
break;
if (mil.size() > 1) { if (mil.size() > 1) {
mm_ci = mil[1]; mm_ci = mil[1];
mil.pop_front(); mil.pop_front();
@@ -272,8 +270,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
mm_ci = mil[1]; mm_ci = mil[1];
mil.pop_front(); mil.pop_front();
if (mm_ci->data(bvidVisualizeSelection).toBool()) if (mm_ci->data(bvidVisualizeSelection).toBool())
if (mil.size() > 1) if (mil.size() > 1) mm_ci = mil[1];
mm_ci = mil[1];
} else } else
mm_ci = 0; mm_ci = 0;
} }
@@ -282,10 +279,10 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
while (mm_ci->parentItem() != 0) while (mm_ci->parentItem() != 0)
mm_ci = mm_ci->parentItem(); mm_ci = mm_ci->parentItem();
if (!ti->data(bvidDecorText).toString().isEmpty()) { // text item, check for rect if (!ti->data(bvidDecorText).toString().isEmpty()) { // text item, check for rect
BlockItem * bi = qgraphicsitem_cast<BlockItem*>(mm_ci); BlockItem * bi = qgraphicsitem_cast<BlockItem *>(mm_ci);
if (bi) { if (bi) {
if (!bi->sceneRect().contains(scene_point)) { if (!bi->sceneRect().contains(scene_point)) {
//qDebug() << "return"; // qDebug() << "return";
mm_ci = 0; mm_ci = 0;
} }
} }
@@ -294,27 +291,27 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
if (mm_ci) { if (mm_ci) {
if ((mm_ci->data(bvidType).toInt() == bvitPin) && m_connect) { if ((mm_ci->data(bvidType).toInt() == bvitPin) && m_connect) {
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->state() == BlockItemPin::Hover) { if (qgraphicsitem_cast<BlockItemPin *>(mm_ci)->state() == BlockItemPin::Hover) {
trace_from = mm_ci->scenePos(); trace_from = mm_ci->scenePos();
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->clearStateStack(); qgraphicsitem_cast<BlockItemPin *>(mm_ci)->clearStateStack();
hideTmpBuses(); hideTmpBuses();
tmp_bus.setBusType(qgraphicsitem_cast<BlockItemPin*>(mm_ci)->busType()); tmp_bus.setBusType(qgraphicsitem_cast<BlockItemPin *>(mm_ci)->busType());
tmp_bus.setEndpointsNumber(3); tmp_bus.setEndpointsNumber(3);
tmp_bus.show(); tmp_bus.show();
new_bus = true; new_bus = true;
qDeleteAll(tmp_buses); qDeleteAll(tmp_buses);
tmp_buses.clear(); tmp_buses.clear();
foreach (BlockItemPin * p, last_multiconnect_pl) { foreach(BlockItemPin * p, last_multiconnect_pl) {
tmp_buses << new BlockBusItem(true); tmp_buses << new BlockBusItem(true);
tmp_buses.back()->setBusType(p->busType()); tmp_buses.back()->setBusType(p->busType());
addItem(tmp_buses.back()); addItem(tmp_buses.back());
} }
//qDebug() << "new" << ; // qDebug() << "new" << ;
prev_tcb = m_trace_with_buses; prev_tcb = m_trace_with_buses;
newBusStarted(tmp_bus.busType()); newBusStarted(tmp_bus.busType());
markPins(tmp_bus.busType()); markPins(tmp_bus.busType());
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignLeft || if (qgraphicsitem_cast<BlockItemPin *>(mm_ci)->alignment() == Qt::AlignLeft ||
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignRight) qgraphicsitem_cast<BlockItemPin *>(mm_ci)->alignment() == Qt::AlignRight)
wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal); wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal);
else else
wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical); wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical);
@@ -325,11 +322,11 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
cur_scl = qSqrt(transform().determinant()); cur_scl = qSqrt(transform().determinant());
break; break;
case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseMove:
//qDebug() << "move" << (mm_ci != 0 ? mm_ci : 0) << mm_mods << mm_cancel << mm_drag; // qDebug() << "move" << (mm_ci != 0 ? mm_ci : 0) << mm_mods << mm_cancel << mm_drag;
if (cur_bus) { if (cur_bus) {
return false; return false;
} }
//qDebug() << "move mm_ci" << mm_ci << mm_cancel; // qDebug() << "move mm_ci" << mm_ci << mm_cancel;
if (mm_ci) if (mm_ci)
if (mm_ci->data(bvidTmpItem).toBool()) { if (mm_ci->data(bvidTmpItem).toBool()) {
mm_ci = 0; mm_ci = 0;
@@ -346,19 +343,21 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
} else { } else {
if (tmp_bus.isVisible()) { if (tmp_bus.isVisible()) {
mil = scene_->items(me->scenePos()); mil = scene_->items(me->scenePos());
hpin = 0; hpin = 0;
foreach (QGraphicsItem * i, mil) foreach(QGraphicsItem * i, mil)
if (i->data(bvidType).toInt() == bvitPin) { if (i->data(bvidType).toInt() == bvitPin) {
hpin = qgraphicsitem_cast<BlockItemPin*>(i); hpin = qgraphicsitem_cast<BlockItemPin *>(i);
break; break;
} }
if (hpin) { if (hpin) {
if (hpin->state() == BlockItemPin::Accept) { if (hpin->state() == BlockItemPin::Accept) {
unhoverPins(hpin); unhoverPins(hpin);
hoverAcceptedPin(hpin, true); hoverAcceptedPin(hpin, true);
} else hpin = 0; } else
} else unhoverPins(); hpin = 0;
} else
unhoverPins();
if (new_branch) { if (new_branch) {
matchBus(); matchBus();
break; break;
@@ -366,7 +365,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
trace(trace_from, me->scenePos(), &tmp_bus); trace(trace_from, me->scenePos(), &tmp_bus);
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) { for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
QPointF dp = last_multiconnect_pl[i]->scenePos() - trace_from; QPointF dp = last_multiconnect_pl[i]->scenePos() - trace_from;
//qDebug() << "trace" << i << dp; // qDebug() << "trace" << i << dp;
trace(trace_from + dp, me->scenePos() + dp, tmp_buses[i], false); trace(trace_from + dp, me->scenePos() + dp, tmp_buses[i], false);
tmp_buses[i]->show(); tmp_buses[i]->show();
} }
@@ -378,7 +377,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (fmm_drag) { if (fmm_drag) {
fmm_drag = false; fmm_drag = false;
if (mm_ci) { if (mm_ci) {
if ((mm_ci->data(bvidType).toInt() == bvitBlock) && !mm_ci->data(bvidTmpItem).toBool()) { if ((mm_ci->data(bvidType).toInt() == bvitBlock) && !mm_ci->data(bvidTmpItem).toBool()) {
if (!mm_ci->isSelected() && sel_items.isEmpty()) { if (!mm_ci->isSelected() && sel_items.isEmpty()) {
clearSelection(); clearSelection();
mm_ci->setSelected(true); mm_ci->setSelected(true);
@@ -392,21 +391,22 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
sel_items = scene_->selectedItems(); sel_items = scene_->selectedItems();
deleteCopyTemp(); deleteCopyTemp();
QList<BlockItem * > bi; QList<BlockItem *> bi;
foreach (QGraphicsItem * i, sel_items) { foreach(QGraphicsItem * i, sel_items) {
if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) { if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) {
//qDebug() << "copy"; // qDebug() << "copy";
bi << qgraphicsitem_cast<BlockItem*>(i); bi << qgraphicsitem_cast<BlockItem *>(i);
BlockItem * ti = bi.back()->copy(); BlockItem * ti = bi.back()->copy();
ti->g_main.setPen(QPen(ti->g_main.pen().color(), ti->g_main.pen().widthF(), Qt::DashLine)); ti->g_main.setPen(QPen(ti->g_main.pen().color(), ti->g_main.pen().widthF(), Qt::DashLine));
QColor bc = ti->g_main.brush().color(); bc.setAlphaF(bc.alphaF() * 0.5); QColor bc = ti->g_main.brush().color();
bc.setAlphaF(bc.alphaF() * 0.5);
ti->g_main.setBrush(bc); ti->g_main.setBrush(bc);
copy_items << ti; copy_items << ti;
scene_->addItem(ti); scene_->addItem(ti);
} }
} }
QList<BlockBusItem * > ibi = internalBuses(bi); QList<BlockBusItem *> ibi = internalBuses(bi);
foreach (BlockBusItem * i, ibi) { foreach(BlockBusItem * i, ibi) {
i = i->copy(); i = i->copy();
i->setOpacity(i->opacity() * 0.5); i->setOpacity(i->opacity() * 0.5);
copy_buses << i; copy_buses << i;
@@ -416,7 +416,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
setCursor(Qt::DragCopyCursor); setCursor(Qt::DragCopyCursor);
} }
} else { } else {
//qDebug() << "move smode" << smode; // qDebug() << "move smode" << smode;
if (smode == BlockView::SingleSelection) { if (smode == BlockView::SingleSelection) {
if (fmm_drag) { if (fmm_drag) {
clearSelection(); clearSelection();
@@ -432,8 +432,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (mm_ci == 0) { if (mm_ci == 0) {
scene_->addItem(&sel_rect); scene_->addItem(&sel_rect);
sel_rect.show(); sel_rect.show();
if (!mm_mods.testFlag(Qt::ControlModifier)) if (!mm_mods.testFlag(Qt::ControlModifier)) clearSelection();
clearSelection();
} else { } else {
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_ci->isSelected()) { if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_ci->isSelected()) {
clearSelection(); clearSelection();
@@ -442,8 +441,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
saveSelState(); saveSelState();
if (mm_ci != 0) if (mm_ci != 0)
if (!sel_items.contains(mm_ci)) if (!sel_items.contains(mm_ci)) mm_ci = 0;
mm_ci = 0;
} }
} }
} }
@@ -452,46 +450,39 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
else { else {
if (mm_drag && mm_ci != 0) { if (mm_drag && mm_ci != 0) {
mdp = (me->scenePos() - scene_point); mdp = (me->scenePos() - scene_point);
if (grid_snap) if (grid_snap) mdp = quantize(mdp, grid_step);
mdp = quantize(mdp, grid_step);
if (!mdp.isNull()) { if (!mdp.isNull()) {
scene_point += mdp; scene_point += mdp;
copy_dp += mdp; copy_dp += mdp;
} }
if (mm_copy) { if (mm_copy) {
if (!mdp.isNull()) if (!mdp.isNull()) moved = true;
moved = true; foreach(QGraphicsItem * i, copy_items)
foreach (QGraphicsItem * i, copy_items)
i->setPos(i->pos() + mdp); i->setPos(i->pos() + mdp);
foreach (BlockBusItem * i, copy_buses) foreach(BlockBusItem * i, copy_buses)
i->movePolyline(mdp); i->movePolyline(mdp);
} }
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) { if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) {
if (!mdp.isNull()) if (!mdp.isNull()) moved = true;
moved = true; foreach(QGraphicsItem * i, sel_items)
foreach (QGraphicsItem * i, sel_items) if (i->flags().testFlag(QGraphicsItem::ItemIsMovable)) i->setPos(i->pos() + mdp);
if (i->flags().testFlag(QGraphicsItem::ItemIsMovable)) if (!me->modifiers().testFlag(Qt::AltModifier)) moveBuses(sel_items, mdp);
i->setPos(i->pos() + mdp);
if (!me->modifiers().testFlag(Qt::AltModifier))
moveBuses(sel_items, mdp);
setCursor(Qt::ClosedHandCursor); setCursor(Qt::ClosedHandCursor);
} }
return true; return true;
} }
} }
if (mm_ci) if (mm_ci)
if (mm_ci->data(bvidBlockDecor).toBool()) if (mm_ci->data(bvidBlockDecor).toBool()) return true;
return true;
} }
if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0) if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0) return true;
return true; // qDebug() << "scene mouse";
//qDebug() << "scene mouse";
break; break;
case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseRelease:
if (me->buttons().testFlag(Qt::LeftButton)) btncnt++; if (me->buttons().testFlag(Qt::LeftButton)) btncnt++;
if (me->buttons().testFlag(Qt::RightButton)) btncnt++; if (me->buttons().testFlag(Qt::RightButton)) btncnt++;
if (me->buttons().testFlag(QT_MID_BUTTON)) btncnt++; if (me->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
cur_bus = 0; cur_bus = 0;
mm_cancel = btncnt > 0; mm_cancel = btncnt > 0;
if (mm_cancel || (me->button() == QT_MID_BUTTON) || (me->button() == Qt::RightButton)) { if (mm_cancel || (me->button() == QT_MID_BUTTON) || (me->button() == Qt::RightButton)) {
mm_ci = 0; mm_ci = 0;
@@ -504,15 +495,15 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
if (mm_ci->data(bvidItemSelection).toBool()) break; if (mm_ci->data(bvidItemSelection).toBool()) break;
if (mm_copy) { if (mm_copy) {
QList<QGraphicsItem*> ai; QList<QGraphicsItem *> ai;
blockSignals(true); blockSignals(true);
if (moved) { if (moved) {
QList<BlockItem*> ci; QList<BlockItem *> ci;
QList<BlockBusItem*> bi; QList<BlockBusItem *> bi;
foreach (QGraphicsItem * b, sel_items) foreach(QGraphicsItem * b, sel_items)
if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) { if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) {
ci << qgraphicsitem_cast<BlockItem*>(b); ci << qgraphicsitem_cast<BlockItem *>(b);
ai << qgraphicsitem_cast<QGraphicsItem*>(b); ai << qgraphicsitem_cast<QGraphicsItem *>(b);
} }
bi = internalBuses(ci); bi = internalBuses(ci);
if (!ci.isEmpty()) copyBlocks(ci, copy_dp); if (!ci.isEmpty()) copyBlocks(ci, copy_dp);
@@ -530,10 +521,9 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
hideTmpBuses(false); hideTmpBuses(false);
} }
if (moved && pm_connect) { if (moved && pm_connect) {
QList<QGraphicsItem*> ci; QList<QGraphicsItem *> ci;
foreach (QGraphicsItem * b, sel_items) foreach(QGraphicsItem * b, sel_items)
if (b->data(bvidType).toInt() == bvitBlock) if (b->data(bvidType).toInt() == bvitBlock) ci << b;
ci << b;
simplifyBuses(); simplifyBuses();
emitActionEvent(BlockItemBase::BlockMove, ci); emitActionEvent(BlockItemBase::BlockMove, ci);
reconnectAll(); reconnectAll();
@@ -545,7 +535,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
BlockBusItem * nb = new BlockBusItem(tmp_bus); BlockBusItem * nb = new BlockBusItem(tmp_bus);
addItem(nb, tmp_buses.isEmpty()); addItem(nb, tmp_buses.isEmpty());
newBusCreated(nb); newBusCreated(nb);
foreach (BlockBusItem * b, tmp_buses) { foreach(BlockBusItem * b, tmp_buses) {
nb = new BlockBusItem(*b); nb = new BlockBusItem(*b);
addItem(nb, b == tmp_buses.back()); addItem(nb, b == tmp_buses.back());
newBusCreated(nb); newBusCreated(nb);
@@ -553,7 +543,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} else { } else {
if (connectTmpToBus(match_bus)) { if (connectTmpToBus(match_bus)) {
newBusCreated(match_bus); newBusCreated(match_bus);
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << match_bus); emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << match_bus);
emit connectionsChanged(); emit connectionsChanged();
} }
} }
@@ -570,34 +560,28 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
switch (smode) { switch (smode) {
case SingleSelection: case SingleSelection:
clearSelection(); clearSelection();
if (mm_ci) if (mm_ci) mm_ci->setSelected(true);
mm_ci->setSelected(true);
break; break;
case MultiSelection: case MultiSelection:
if (mm_ci == 0 || !me->modifiers().testFlag(Qt::ControlModifier)) { if (mm_ci == 0 || !me->modifiers().testFlag(Qt::ControlModifier)) {
clearSelection(); clearSelection();
if (mm_ci) if (mm_ci) mm_ci->setSelected(true);
mm_ci->setSelected(true);
} else { } else {
if (mm_ci != 0) { if (mm_ci != 0) {
if (me->modifiers().testFlag(Qt::ControlModifier)) { if (me->modifiers().testFlag(Qt::ControlModifier)) {
if (mm_ci->data(bvidType).toInt() == bvitBlock) if (mm_ci->data(bvidType).toInt() == bvitBlock) mm_ci->setSelected(!mm_ci->isSelected());
mm_ci->setSelected(!mm_ci->isSelected());
} else } else
mm_ci->setSelected(true); mm_ci->setSelected(true);
} }
} }
break; break;
default: default: clearSelection(); break;
clearSelection();
break;
} }
} }
sel_rect.hide(); sel_rect.hide();
if (sel_rect.scene()) if (sel_rect.scene()) scene_->removeItem(&sel_rect);
scene_->removeItem(&sel_rect);
mm_drag = false; mm_drag = false;
mm_ci = 0; mm_ci = 0;
unsetCursor(); unsetCursor();
break; break;
default: break; default: break;
@@ -637,9 +621,8 @@ void BlockView::wheelEvent(QWheelEvent * e) {
#else #else
double scl = 1. - e->angleDelta().y() / 500.; double scl = 1. - e->angleDelta().y() / 500.;
#endif #endif
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) nav_target = _nav();
nav_target = _nav(); QRectF r = nav_target;
QRectF r = nav_target;
double vw = viewport()->width(), vh = viewport()->height(); double vw = viewport()->width(), vh = viewport()->height();
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
double cx = double(e->pos().x()) / vw, cy = double(e->pos().y()) / vh; double cx = double(e->pos().x()) / vw, cy = double(e->pos().y()) / vh;
@@ -661,8 +644,7 @@ void BlockView::mousePressEvent(QMouseEvent * event) {
press_point = event->pos(); press_point = event->pos();
if (event->buttons().testFlag(QT_MID_BUTTON) || event->buttons().testFlag(Qt::RightButton)) { if (event->buttons().testFlag(QT_MID_BUTTON) || event->buttons().testFlag(Qt::RightButton)) {
setCursor(Qt::ClosedHandCursor); setCursor(Qt::ClosedHandCursor);
if (sel_rect.scene()) if (sel_rect.scene()) scene_->removeItem(&sel_rect);
scene_->removeItem(&sel_rect);
} }
QGraphicsView::mousePressEvent(event); QGraphicsView::mousePressEvent(event);
} }
@@ -677,7 +659,7 @@ void BlockView::mouseReleaseEvent(QMouseEvent * event) {
void BlockView::updateNavRect() { void BlockView::updateNavRect() {
QPointF t = mapToScene(viewport()->rect().topLeft()); QPointF t = mapToScene(viewport()->rect().topLeft());
QPointF b = mapToScene(viewport()->rect().bottomRight()); QPointF b = mapToScene(viewport()->rect().bottomRight());
nav_rect = QRectF(t, b); nav_rect = QRectF(t, b);
} }
@@ -717,7 +699,7 @@ void BlockView::mouseDoubleClickEvent(QMouseEvent * event) {
void BlockView::keyPressEvent(QKeyEvent * e) { void BlockView::keyPressEvent(QKeyEvent * e) {
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos()))); BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
if (pin) { if (pin) {
//qDebug() << "pin" << pin->state(); // qDebug() << "pin" << pin->state();
if (pin->state() == BlockItemPin::Hover) { if (pin->state() == BlockItemPin::Hover) {
highlightNearPins(pin, e->modifiers()); highlightNearPins(pin, e->modifiers());
} }
@@ -727,20 +709,20 @@ void BlockView::keyPressEvent(QKeyEvent * e) {
if (e->key() == Qt::Key_Shift) { if (e->key() == Qt::Key_Shift) {
retrace = true; retrace = true;
switch (wavetrace.preferredDirection()) { switch (wavetrace.preferredDirection()) {
case BlockViewWavetrace::NoTrace: wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal); break; case BlockViewWavetrace::NoTrace: wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal); break;
case BlockViewWavetrace::Horizontal: wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical); break; case BlockViewWavetrace::Horizontal: wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical); break;
case BlockViewWavetrace::Vertical: wavetrace.setPreferredDirection(BlockViewWavetrace::NoTrace); break; case BlockViewWavetrace::Vertical: wavetrace.setPreferredDirection(BlockViewWavetrace::NoTrace); break;
} }
} }
if (e->key() == Qt::Key_Alt) { if (e->key() == Qt::Key_Alt) {
retrace = true; retrace = true;
m_trace_with_buses = !m_trace_with_buses; m_trace_with_buses = !m_trace_with_buses;
} }
if (retrace) { if (retrace) {
trace(last_trace_from, trace_to, &tmp_bus); trace(last_trace_from, trace_to, &tmp_bus);
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) { for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
QPointF dp = last_multiconnect_pl[i]->scenePos() - last_trace_from; QPointF dp = last_multiconnect_pl[i]->scenePos() - last_trace_from;
//qDebug() << "trace" << i << dp; // qDebug() << "trace" << i << dp;
trace(last_trace_from + dp, trace_to + dp, tmp_buses[i], false); trace(last_trace_from + dp, trace_to + dp, tmp_buses[i], false);
tmp_buses[i]->show(); tmp_buses[i]->show();
} }
@@ -754,7 +736,7 @@ void BlockView::keyPressEvent(QKeyEvent * e) {
void BlockView::keyReleaseEvent(QKeyEvent * e) { void BlockView::keyReleaseEvent(QKeyEvent * e) {
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos()))); BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
if (pin) { if (pin) {
//qDebug() << "pin" << pin->state(); // qDebug() << "pin" << pin->state();
if (pin->state() == BlockItemPin::Hover) { if (pin->state() == BlockItemPin::Hover) {
highlightNearPins(pin, e->modifiers()); highlightNearPins(pin, e->modifiers());
} }
@@ -781,7 +763,10 @@ void BlockView::scrollContentsBy(int dx, int dy) {
thumbShow(); thumbShow();
restartTimer(timer_thumb, thumb_hide_delay); restartTimer(timer_thumb, thumb_hide_delay);
QWidget * w = &widget_thumb; QWidget * w = &widget_thumb;
QMetaObject::invokeMethod(this, [w](){w->update();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[w]() { w->update(); },
Qt::QueuedConnection);
} }
@@ -796,26 +781,26 @@ void BlockView::drawBackground(QPainter * painter, const QRectF & rect) {
sy *= scl; sy *= scl;
} }
if (!grid_visible) return; if (!grid_visible) return;
rx = quantize(rect.left(), sx); rx = quantize(rect.left(), sx);
ry = quantize(rect.top(), sy); ry = quantize(rect.top(), sy);
bool gp = grid_points > 0.5; bool gp = grid_points > 0.5;
if (gp) { if (gp) {
QPen pp(grid_pen.color(), qMax<int>(grid_points, thick), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QPen pp(grid_pen.color(), qMax<int>(grid_points, thick), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
pp.setCosmetic(true); pp.setCosmetic(true);
painter->setPen(pp); painter->setPen(pp);
for(int i = 0; i < qCeil(rect.width() / sx) + 1; ++i) for (int i = 0; i < qCeil(rect.width() / sx) + 1; ++i)
for(int j = 0; j < qCeil(rect.height() / sy) + 1; ++j) for (int j = 0; j < qCeil(rect.height() / sy) + 1; ++j)
painter->drawPoint(rx + i * sx, ry + j * sy); painter->drawPoint(rx + i * sx, ry + j * sy);
} }
if (grid_pen.style() == Qt::NoPen) return; if (grid_pen.style() == Qt::NoPen) return;
QPen pen = grid_pen; QPen pen = grid_pen;
pen.setWidth(qMax<int>(pen.width(), thick)); pen.setWidth(qMax<int>(pen.width(), thick));
painter->setPen(grid_pen); painter->setPen(grid_pen);
for(int i = 0; i < qCeil(rect.width() / sx) + 1; ++i) { for (int i = 0; i < qCeil(rect.width() / sx) + 1; ++i) {
double cx = rx + i * sx; double cx = rx + i * sx;
painter->drawLine(cx, ry, cx, ry + rect.height()); painter->drawLine(cx, ry, cx, ry + rect.height());
} }
for(int j = 0; j < qCeil(rect.height() / sy) + 1; ++j) { for (int j = 0; j < qCeil(rect.height() / sy) + 1; ++j) {
double cy = ry + j * sy; double cy = ry + j * sy;
painter->drawLine(rx, cy, rx + rect.width(), cy); painter->drawLine(rx, cy, rx + rect.width(), cy);
} }
@@ -838,7 +823,7 @@ void BlockView::deleteCopyTemp() {
} }
void BlockView::emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem * > items) { void BlockView::emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem *> items) {
if (!ae_enabled) return; if (!ae_enabled) return;
emit schemeAction(action, items); emit schemeAction(action, items);
} }
@@ -868,18 +853,20 @@ void BlockView::getPinMC(bool * v) {
void BlockView::drawThumb() { void BlockView::drawThumb() {
if (!minimap) return; if (!minimap) return;
QPainter p(&widget_thumb); QPainter p(&widget_thumb);
QRect wr = widget_thumb.rect().adjusted(0, 0, -1, -1); QRect wr = widget_thumb.rect().adjusted(0, 0, -1, -1);
QSizeF sr = sceneRect().size(), tr; QSizeF sr = sceneRect().size(), tr;
if (sr.width() >= sr.height()) if (sr.width() >= sr.height())
thumb_scl = thumb_size.width() / sr.width(); thumb_scl = thumb_size.width() / sr.width();
else else
thumb_scl = thumb_size.height() / sr.height(); thumb_scl = thumb_size.height() / sr.height();
tr = sr * thumb_scl; tr = sr * thumb_scl;
cur_scl = qSqrt(transform().determinant()); cur_scl = qSqrt(transform().determinant());
thumb_scl /= cur_scl; thumb_scl /= cur_scl;
QSizeF vs(size().width() - verticalScrollBar()->width(), size().height() - horizontalScrollBar()->height()); QSizeF vs(size().width() - verticalScrollBar()->width(), size().height() - horizontalScrollBar()->height());
QRectF vr(QPointF(horizontalScrollBar()->value() - horizontalScrollBar()->minimum(), QRectF vr(QPointF(horizontalScrollBar()->value() - horizontalScrollBar()->minimum(),
verticalScrollBar()->value() - verticalScrollBar()->minimum()) * thumb_scl, vs * thumb_scl); verticalScrollBar()->value() - verticalScrollBar()->minimum()) *
thumb_scl,
vs * thumb_scl);
vr.adjust(0, 0, -1, -1); vr.adjust(0, 0, -1, -1);
p.setBrush(Qt::lightGray); p.setBrush(Qt::lightGray);
@@ -920,7 +907,7 @@ void BlockView::thumbHide() {
thumb_anim.setStartValue(_thumb()); thumb_anim.setStartValue(_thumb());
thumb_anim.setEndValue(0.); thumb_anim.setEndValue(0.);
thumb_anim.start(); thumb_anim.start();
//qDebug() << "hide" << thumb_anim.startValue() << thumb_anim.endValue(); // qDebug() << "hide" << thumb_anim.startValue() << thumb_anim.endValue();
} }
@@ -929,20 +916,19 @@ void BlockView::thumbShow() {
if (widget_thumb.isHidden() || (_talpha < 0.1)) drawSceneThumb(); if (widget_thumb.isHidden() || (_talpha < 0.1)) drawSceneThumb();
thumb_anim.stop(); thumb_anim.stop();
_setThumb(1.); _setThumb(1.);
//qDebug() << "show" << thumb_anim.startValue() << thumb_anim.endValue(); // qDebug() << "show" << thumb_anim.startValue() << thumb_anim.endValue();
} }
void BlockView::clearSelection() { void BlockView::clearSelection() {
bool pb = block_emit_selection; bool pb = block_emit_selection;
block_emit_selection = true; block_emit_selection = true;
sel_items.clear(); sel_items.clear();
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(false); if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(false);
block_emit_selection = pb; block_emit_selection = pb;
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
@@ -950,84 +936,80 @@ void BlockView::addItem(QGraphicsItem * item, bool emit_action) {
scene_->addItem(item); scene_->addItem(item);
applyGridStep(); applyGridStep();
if (item->data(bvidType).toInt() == bvitBus) { if (item->data(bvidType).toInt() == bvitBus) {
loadBus(qgraphicsitem_cast<BlockBusItem*>(item)); loadBus(qgraphicsitem_cast<BlockBusItem *>(item));
((BlockBusItem*)item)->setSquareNodes(square_node); ((BlockBusItem *)item)->setSquareNodes(square_node);
connect((BlockBusItem*)item, SIGNAL(destroyed(QObject*)), this, SLOT(removedBus(QObject*)), Qt::UniqueConnection); connect((BlockBusItem *)item, SIGNAL(destroyed(QObject *)), this, SLOT(removedBus(QObject *)), Qt::UniqueConnection);
if (emit_action) emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << item); if (emit_action) emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << item);
emit connectionsChanged(); emit connectionsChanged();
return; return;
} }
if (item->data(bvidType).toInt() == bvitBlock) { if (item->data(bvidType).toInt() == bvitBlock) {
connect((BlockItem*)item, SIGNAL(destroyed(QObject*)), this, SLOT(removedBlock(QObject*)), Qt::UniqueConnection); connect((BlockItem *)item, SIGNAL(destroyed(QObject *)), this, SLOT(removedBlock(QObject *)), Qt::UniqueConnection);
connect((BlockItem*)item, SIGNAL(blockHoverEnter(BlockItem*)), this, SIGNAL(blockHoverEnter(BlockItem*)), Qt::UniqueConnection); connect((BlockItem *)item, SIGNAL(blockHoverEnter(BlockItem *)), this, SIGNAL(blockHoverEnter(BlockItem *)), Qt::UniqueConnection);
connect((BlockItem*)item, SIGNAL(blockHoverLeave(BlockItem*)), this, SIGNAL(blockHoverLeave(BlockItem*)), Qt::UniqueConnection); connect((BlockItem *)item, SIGNAL(blockHoverLeave(BlockItem *)), this, SIGNAL(blockHoverLeave(BlockItem *)), Qt::UniqueConnection);
if (emit_action) emitActionEvent(BlockItemBase::BlockAdd, QList<QGraphicsItem*>() << item); if (emit_action) emitActionEvent(BlockItemBase::BlockAdd, QList<QGraphicsItem *>() << item);
return; return;
} }
item->setData(bvidType, bvitDecor); item->setData(bvidType, bvitDecor);
} }
QList<BlockBusItem * > BlockView::buses() const { QList<BlockBusItem *> BlockView::buses() const {
QList<BlockBusItem * > ret; QList<BlockBusItem *> ret;
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if ((i->data(bvidType).toInt() == bvitBus) && !i->data(bvidTmpItem).toBool()) if ((i->data(bvidType).toInt() == bvitBus) && !i->data(bvidTmpItem).toBool())
if (!copy_buses.contains((BlockBusItem*)i)) if (!copy_buses.contains((BlockBusItem *)i)) ret << qgraphicsitem_cast<BlockBusItem *>(i);
ret << qgraphicsitem_cast<BlockBusItem*>(i);
return ret; return ret;
} }
QList<BlockBusItem * > BlockView::wrongConnectedBuses() const { QList<BlockBusItem *> BlockView::wrongConnectedBuses() const {
QList<BlockBusItem * > sl = buses(), ret; QList<BlockBusItem *> sl = buses(), ret;
QList<BlockItem * > bl = blocks(); QList<BlockItem *> bl = blocks();
foreach (BlockItem * b, bl) { foreach(BlockItem * b, bl) {
QVector<BlockItemPin * > pins = b->pins(); QVector<BlockItemPin *> pins = b->pins();
foreach (BlockItemPin * p, pins) foreach(BlockItemPin * p, pins)
if (p->state() == BlockItemPin::Reject) { if (p->state() == BlockItemPin::Reject) {
QPointF pp = p->scenePos(); QPointF pp = p->scenePos();
foreach (BlockBusItem * s, sl) foreach(BlockBusItem * s, sl)
if (s->pol.contains(pp)) if (s->pol.contains(pp))
if (!ret.contains(s)) if (!ret.contains(s)) ret << s;
ret << s;
} }
} }
return ret; return ret;
} }
QList<BlockItem * > BlockView::blocks() const { QList<BlockItem *> BlockView::blocks() const {
QList<BlockItem * > ret; QList<BlockItem *> ret;
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) ret << qgraphicsitem_cast<BlockItem *>(i);
ret << qgraphicsitem_cast<BlockItem*>(i);
return ret; return ret;
} }
QList<QGraphicsItem * > BlockView::decors() const { QList<QGraphicsItem *> BlockView::decors() const {
QList<QGraphicsItem*> ret, gi = scene_->items(); QList<QGraphicsItem *> ret, gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if ((i->data(bvidType).toInt() == bvitDecor) && !i->data(bvidTmpItem).toBool() && !i->data(bvidItemSelection).toBool() && (i->parentItem() == 0) if ((i->data(bvidType).toInt() == bvitDecor) && !i->data(bvidTmpItem).toBool() && !i->data(bvidItemSelection).toBool() &&
&& (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i)) (i->parentItem() == 0) && (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem *)i))
ret << i; ret << i;
return ret; return ret;
} }
BlockBusItem * BlockView::connectionBus(BlockItem * b0, BlockItem * b1) const { BlockBusItem * BlockView::connectionBus(BlockItem * b0, BlockItem * b1) const {
QList<BlockBusItem * > cbl = connectionBuses(b0, b1); QList<BlockBusItem *> cbl = connectionBuses(b0, b1);
if (cbl.isEmpty()) return 0; if (cbl.isEmpty()) return 0;
return cbl.front(); return cbl.front();
} }
QList<BlockBusItem * > BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const { QList<BlockBusItem *> BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const {
if (!b0 || !b1) return QList<BlockBusItem * >(); if (!b0 || !b1) return QList<BlockBusItem *>();
QSet<BlockBusItem * > bs0 = QList2QSet(b0->connectedBuses()), QSet<BlockBusItem *> bs0 = QList2QSet(b0->connectedBuses()), bs1 = QList2QSet(b1->connectedBuses());
bs1 = QList2QSet(b1->connectedBuses());
return (bs0 & bs1).values(); return (bs0 & bs1).values();
} }
@@ -1036,25 +1018,31 @@ bool BlockView::connectPins(BlockItemPin * p0, BlockItemPin * p1) {
if (!p0 || !p1) return false; if (!p0 || !p1) return false;
if (p0 == p1) return false; if (p0 == p1) return false;
if (p0->busType() != p1->busType()) return false; if (p0->busType() != p1->busType()) return false;
QList<BlockBusItem * > bl0 = p0->connectedBuses(), bl1 = p1->connectedBuses(); QList<BlockBusItem *> bl0 = p0->connectedBuses(), bl1 = p1->connectedBuses();
if (!(QList2QSet(bl0) & QList2QSet(bl1)).isEmpty()) return true; if (!(QList2QSet(bl0) & QList2QSet(bl1)).isEmpty()) return true;
BlockBusItem * nb = new BlockBusItem(); BlockBusItem * nb = new BlockBusItem();
nb->setBusType(p0->busType()); nb->setBusType(p0->busType());
loadBus(nb); loadBus(nb);
if (!bl0.isEmpty() && !bl1.isEmpty()) { // connect two existing buses if (!bl0.isEmpty() && !bl1.isEmpty()) { // connect two existing buses
} else { } else {
if ((bl0.isEmpty() && !bl1.isEmpty()) || (bl1.isEmpty() && !bl0.isEmpty())) { // connect empty pin to existing bus if ((bl0.isEmpty() && !bl1.isEmpty()) || (bl1.isEmpty() && !bl0.isEmpty())) { // connect empty pin to existing bus
BlockItemPin * ep = 0; BlockItemPin * ep = 0;
BlockBusItem * eb = 0; BlockBusItem * eb = 0;
if (bl0.isEmpty()) {ep = p0; eb = bl1[0];} if (bl0.isEmpty()) {
else {ep = p1; eb = bl0[0];} ep = p0;
double md = -1; int mi = -1; eb = bl1[0];
} else {
ep = p1;
eb = bl0[0];
}
double md = -1;
int mi = -1;
QPointF sp = ep->scenePos(); QPointF sp = ep->scenePos();
if (eb->pol.size() == 2) { if (eb->pol.size() == 2) {
eb->selSegment = 0; eb->selSegment = 0;
eb->addPoint((eb->pol[0] + eb->pol[1]) / 2.); eb->addPoint((eb->pol[0] + eb->pol[1]) / 2.);
eb->selPoint = -1; eb->selPoint = -1;
mi = 2; mi = 2;
} else { } else {
for (int i = 0; i < eb->pol.size(); ++i) { for (int i = 0; i < eb->pol.size(); ++i) {
if (eb->ends.contains(i)) continue; if (eb->ends.contains(i)) continue;
@@ -1092,7 +1080,7 @@ bool BlockView::connectPins(BlockItemPin * p0, BlockItemPin * p1) {
} }
reconnectAll(); reconnectAll();
newBusCreated(nb); newBusCreated(nb);
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << nb); emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << nb);
emit connectionsChanged(); emit connectionsChanged();
return true; return true;
} }
@@ -1159,17 +1147,19 @@ void BlockView::fitInView() {
QRectF BlockView::itemsBoundingRect() const { QRectF BlockView::itemsBoundingRect() const {
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
if (gi.isEmpty()) return QRectF(); if (gi.isEmpty()) return QRectF();
bool f = true; bool f = true;
QRectF ret; QRectF ret;
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->isVisible() && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i)) { if (i->isVisible() && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem *)i)) {
if (!(i->data(bvidItemSelection).toBool()) && !i->data(bvidTmpItem).toBool()) { if (!(i->data(bvidItemSelection).toBool()) && !i->data(bvidTmpItem).toBool()) {
QRectF br = i->mapRectToScene(i->boundingRect()); QRectF br = i->mapRectToScene(i->boundingRect());
if (br.width() <= 1 || br.height() <= 1) continue; if (br.width() <= 1 || br.height() <= 1) continue;
if (f) ret = br; if (f)
else ret |= br; ret = br;
else
ret |= br;
f = false; f = false;
} }
} }
@@ -1178,96 +1168,93 @@ QRectF BlockView::itemsBoundingRect() const {
void BlockView::restoreSelState() { void BlockView::restoreSelState() {
//qDebug() << "restoreSelState"; // qDebug() << "restoreSelState";
foreach (QGraphicsItem * i, sel_items) { foreach(QGraphicsItem * i, sel_items) {
i->setPos(i->data(bvidItemPos).toPointF()); i->setPos(i->data(bvidItemPos).toPointF());
} }
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->data(bvidType).toInt() == bvitBus) { if (i->data(bvidType).toInt() == bvitBus) {
BlockBusItem * bi = qgraphicsitem_cast<BlockBusItem*>(i); BlockBusItem * bi = qgraphicsitem_cast<BlockBusItem *>(i);
bi->pol = bi->bpol; bi->pol = bi->bpol;
bi->prepareGeometryChange(); bi->prepareGeometryChange();
} }
} }
void BlockView::saveSelState() { void BlockView::saveSelState() {
//qDebug() << "saveSelState"; // qDebug() << "saveSelState";
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
sel_items = scene_->selectedItems(); sel_items = scene_->selectedItems();
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
i->setData(bvidSelected, i->isSelected()); i->setData(bvidSelected, i->isSelected());
i->setData(bvidItemPos, i->pos()); i->setData(bvidItemPos, i->pos());
if (i->data(bvidType).toInt() == bvitBus) if (i->data(bvidType).toInt() == bvitBus) qgraphicsitem_cast<BlockBusItem *>(i)->bpol = qgraphicsitem_cast<BlockBusItem *>(i)->pol;
qgraphicsitem_cast<BlockBusItem*>(i)->bpol = qgraphicsitem_cast<BlockBusItem*>(i)->pol;
} }
} }
void BlockView::saveBusesState() { void BlockView::saveBusesState() {
QList<BlockBusItem*> bl = buses(); QList<BlockBusItem *> bl = buses();
foreach (BlockBusItem * b, bl) foreach(BlockBusItem * b, bl)
b->saveState(); b->saveState();
} }
void BlockView::restoreBusesState() { void BlockView::restoreBusesState() {
QList<BlockBusItem*> bl = buses(); QList<BlockBusItem *> bl = buses();
foreach (BlockBusItem * b, bl) foreach(BlockBusItem * b, bl)
b->restoreState(); b->restoreState();
} }
void BlockView::applySelRect(QGraphicsSceneMouseEvent * me) { void BlockView::applySelRect(QGraphicsSceneMouseEvent * me) {
QList<QGraphicsItem*> ci = sel_rect.collidingItems(Qt::IntersectsItemBoundingRect); QList<QGraphicsItem *> ci = sel_rect.collidingItems(Qt::IntersectsItemBoundingRect);
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
bool add = me->modifiers().testFlag(Qt::ControlModifier); bool add = me->modifiers().testFlag(Qt::ControlModifier);
QList<QGraphicsItem*> sil = scene_->selectedItems(); QList<QGraphicsItem *> sil = scene_->selectedItems();
block_emit_selection = true; block_emit_selection = true;
if (!add) clearSelection(); if (!add)
clearSelection();
else { else {
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
i->setSelected(i->data(bvidSelected).toBool()); i->setSelected(i->data(bvidSelected).toBool());
} }
foreach (QGraphicsItem * i, ci) { foreach(QGraphicsItem * i, ci) {
i->setSelected(!i->isSelected()); i->setSelected(!i->isSelected());
} }
block_emit_selection = false; block_emit_selection = false;
if (sil != scene_->selectedItems()) if (sil != scene_->selectedItems()) emit selectionChanged();
emit selectionChanged();
} }
void BlockView::applyGridStep() { void BlockView::applyGridStep() {
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->type() == QGraphicsItem::UserType + 2) if (i->type() == QGraphicsItem::UserType + 2) qgraphicsitem_cast<BlockBusItem *>(i)->setGridStep(grid_step);
qgraphicsitem_cast<BlockBusItem*>(i)->setGridStep(grid_step);
} }
void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) { void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) {
if (primary) { if (primary) {
if (hpin) if (hpin) scene_pos_to = hpin->scenePos();
scene_pos_to = hpin->scenePos();
last_trace_from = scene_pos_from; last_trace_from = scene_pos_from;
trace_to = scene_pos_to; trace_to = scene_pos_to;
} }
QRect sr = scene_->sceneRect().toRect(); QRect sr = scene_->sceneRect().toRect();
int dx = sr.left() / grid_step, dy = sr.top() / grid_step; int dx = sr.left() / grid_step, dy = sr.top() / grid_step;
QPoint dp(-dx, -dy), qpt = quantize(scene_pos_to, grid_step).toPoint() / grid_step + dp; QPoint dp(-dx, -dy), qpt = quantize(scene_pos_to, grid_step).toPoint() / grid_step + dp;
QElapsedTimer tm; QElapsedTimer tm;
tm.restart(); tm.restart();
wavetrace.resize(sr.size() / grid_step); wavetrace.resize(sr.size() / grid_step);
wavetrace.fill(BlockViewWavetrace::Empty); wavetrace.fill(BlockViewWavetrace::Empty);
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->data(bvidType).toInt() == bvitBlock) { if (i->data(bvidType).toInt() == bvitBlock) {
QRect ir = i->mapRectToScene(i->boundingRect()).toRect().normalized(); QRect ir = i->mapRectToScene(i->boundingRect()).toRect().normalized();
wavetrace.fill(QRect(ir.topLeft() / grid_step + dp, ir.bottomRight() / grid_step + dp), BlockViewWavetrace::Blocked); wavetrace.fill(QRect(ir.topLeft() / grid_step + dp, ir.bottomRight() / grid_step + dp), BlockViewWavetrace::Blocked);
QVector<BlockItemPin * > pins = qgraphicsitem_cast<BlockItem * >(i)->pins(); QVector<BlockItemPin *> pins = qgraphicsitem_cast<BlockItem *>(i)->pins();
foreach (BlockItemPin * p, pins) { foreach(BlockItemPin * p, pins) {
if (p->busType() == bus->busType()) if (p->busType() == bus->busType())
wavetrace.fill(quantize(p->scenePos(), grid_step).toPoint() / grid_step + dp, BlockViewWavetrace::Empty); wavetrace.fill(quantize(p->scenePos(), grid_step).toPoint() / grid_step + dp, BlockViewWavetrace::Empty);
if (!m_pin_mc && !p->connectedBuses().isEmpty()) if (!m_pin_mc && !p->connectedBuses().isEmpty())
@@ -1275,9 +1262,9 @@ void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem
} }
} }
if (m_trace_with_buses) { if (m_trace_with_buses) {
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->data(bvidType).toInt() == bvitBus) { if (i->data(bvidType).toInt() == bvitBus) {
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem * >(i); BlockBusItem * b = qgraphicsitem_cast<BlockBusItem *>(i);
if (!b) continue; if (!b) continue;
for (int s = 0; s < b->segments.size(); ++s) { for (int s = 0; s < b->segments.size(); ++s) {
QPointF p0 = b->pol[b->segments[s].first], p1 = b->pol[b->segments[s].second], cp = p0; QPointF p0 = b->pol[b->segments[s].first], p1 = b->pol[b->segments[s].second], cp = p0;
@@ -1287,24 +1274,23 @@ void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem
if ((dx + dy) < grid_step) continue; if ((dx + dy) < grid_step) continue;
BlockViewWavetrace::CellState cs = BlockViewWavetrace::Blocked; BlockViewWavetrace::CellState cs = BlockViewWavetrace::Blocked;
if (dx >= dy) { // by x if (dx >= dy) { // by x
sx = grid_step; sx = grid_step;
sy = sx * dy / dx; sy = sx * dy / dx;
steps = qRound(dx / grid_step); steps = qRound(dx / grid_step);
cs = BlockViewWavetrace::HorizontalBus; cs = BlockViewWavetrace::HorizontalBus;
} else { } else {
sy = grid_step; sy = grid_step;
sx = sy * dx / dy; sx = sy * dx / dy;
steps = qRound(dy / grid_step); steps = qRound(dy / grid_step);
cs = BlockViewWavetrace::VerticalBus; cs = BlockViewWavetrace::VerticalBus;
} }
sx *= signx; sx *= signx;
sy *= signy; sy *= signy;
//qDebug() << "fill" << p0 << "->" << p1 << "in" << steps << sx << sy; // qDebug() << "fill" << p0 << "->" << p1 << "in" << steps << sx << sy;
for (int j = 0; j <= steps; ++j) { for (int j = 0; j <= steps; ++j) {
QPoint tp = quantize(cp, grid_step).toPoint() / grid_step + dp; QPoint tp = quantize(cp, grid_step).toPoint() / grid_step + dp;
if (tp != qpt) if (tp != qpt) wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked); // qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
//qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
cp += QPointF(sx, sy); cp += QPointF(sx, sy);
} }
} }
@@ -1313,67 +1299,63 @@ void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem
bus->clear(); bus->clear();
if (wavetrace.trace(quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp, qpt)) { if (wavetrace.trace(quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp, qpt)) {
wavetrace.gatherPath(); wavetrace.gatherPath();
foreach (const QPoint & p, wavetrace.path()) { foreach(const QPoint & p, wavetrace.path()) {
bus->appendPoint((p - dp) * grid_step); bus->appendPoint((p - dp) * grid_step);
} }
} }
//qDebug() << quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp << qpt; // qDebug() << quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp << qpt;
scene_->update(); scene_->update();
} }
void BlockView::clearBusStates() { void BlockView::clearBusStates() {
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->data(bvidType).toInt() == bvitBus) { if (i->data(bvidType).toInt() == bvitBus) {
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem*>(i); BlockBusItem * b = qgraphicsitem_cast<BlockBusItem *>(i);
b->clearBusState(); b->clearBusState();
} }
} }
void BlockView::matchBus() { void BlockView::matchBus() {
match_bus = 0; match_bus = 0;
bool bv = tmp_bus.isVisible(); bool bv = tmp_bus.isVisible();
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
QList<BlockBusItem * > buses; QList<BlockBusItem *> buses;
QList<BlockItem * > blockl; QList<BlockItem *> blockl;
int sp = -1, ss = -1; int sp = -1, ss = -1;
QPointF point; QPointF point;
iconnect = false; iconnect = false;
if (!tmp_bus.pol.isEmpty()) if (!tmp_bus.pol.isEmpty()) point = tmp_bus.pol.back();
point = tmp_bus.pol.back(); foreach(QGraphicsItem * i, gi) {
foreach (QGraphicsItem * i, gi) {
if (i != bus_from) { if (i != bus_from) {
if (i->data(bvidType).toInt() == bvitBus) if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
buses << qgraphicsitem_cast<BlockBusItem*>(i); if (i->data(bvidType).toInt() == bvitBlock) blockl << qgraphicsitem_cast<BlockItem *>(i);
if (i->data(bvidType).toInt() == bvitBlock)
blockl << qgraphicsitem_cast<BlockItem*>(i);
} }
} }
foreach (BlockBusItem * b, buses) { foreach(BlockBusItem * b, buses) {
b->clearBusState(); b->clearBusState();
b->selPoint = b->selSegment = -1; b->selPoint = b->selSegment = -1;
} }
if (!bv) return; if (!bv) return;
BlockBusItem * b(0); BlockBusItem * b(0);
if (m_pin_mc) { if (m_pin_mc) {
foreach (BlockItem * b_, blockl) foreach(BlockItem * b_, blockl)
foreach (BlockItemPin * p_, b_->pins()) foreach(BlockItemPin * p_, b_->pins())
if (p_->scenePos() == point) { if (p_->scenePos() == point) {
return; return;
} }
} }
//qDebug() << "1" << buses.size() << tmp_bus.pol; // qDebug() << "1" << buses.size() << tmp_bus.pol;
for (int i = 0; i < buses.size(); ++i) { for (int i = 0; i < buses.size(); ++i) {
b = buses[i]; b = buses[i];
b->testPoint(point, &sp, &ss, true); b->testPoint(point, &sp, &ss, true);
//qDebug() << i << sp << ss; // qDebug() << i << sp << ss;
if (sp >= 0 || ss >= 0) break; if (sp >= 0 || ss >= 0) break;
} }
if ((sp < 0 && ss < 0) || b == 0) return; if ((sp < 0 && ss < 0) || b == 0) return;
//qDebug("2"); // qDebug("2");
match_bus = b; match_bus = b;
if ((b->busType() != tmp_bus.busType()) || b->connections_.value(sp, 0) != 0) { if ((b->busType() != tmp_bus.busType()) || b->connections_.value(sp, 0) != 0) {
b->setBusState(false); b->setBusState(false);
@@ -1405,7 +1387,7 @@ void BlockView::matchBus() {
} }
iconnect = true; iconnect = true;
b->setBusState(true); b->setBusState(true);
b->selPoint = sp; b->selPoint = sp;
b->selSegment = ss; b->selSegment = ss;
} }
} }
@@ -1416,8 +1398,7 @@ bool BlockView::connectTmpToBus(BlockBusItem * bus) {
if (!bus->busState()) return false; if (!bus->busState()) return false;
if (tmp_bus.pol.size() < 2) return false; if (tmp_bus.pol.size() < 2) return false;
int np = bus->selPoint; int np = bus->selPoint;
if (np < 0) if (np < 0) np = bus->addPoint(tmp_bus.pol.back());
np = bus->addPoint(tmp_bus.pol.back());
if (np < 0) return false; if (np < 0) return false;
tmp_bus.pol.pop_back(); tmp_bus.pol.pop_back();
int lp = bus->pol.size(); int lp = bus->pol.size();
@@ -1433,18 +1414,16 @@ bool BlockView::connectTmpToBus(BlockBusItem * bus) {
void BlockView::markPins(int bus_type) { void BlockView::markPins(int bus_type) {
unhoverPins(); unhoverPins();
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidType).toInt() == bvitPin) { if (i->data(bvidType).toInt() == bvitPin) {
BlockItemPin * p = qgraphicsitem_cast<BlockItemPin*>(i); BlockItemPin * p = qgraphicsitem_cast<BlockItemPin *>(i);
p->saveState(); p->saveState();
if (m_pin_mc) { if (m_pin_mc) {
if (p->busType() == bus_type) if (p->busType() == bus_type) p->setState(BlockItemPin::Accept);
p->setState(BlockItemPin::Accept);
} else { } else {
if (p->busType() == bus_type) { if (p->busType() == bus_type) {
if (p->state() == BlockItemPin::Disconnected) if (p->state() == BlockItemPin::Disconnected) p->setState(BlockItemPin::Accept);
p->setState(BlockItemPin::Accept);
} }
} }
} }
@@ -1454,12 +1433,13 @@ void BlockView::markPins(int bus_type) {
void BlockView::unmarkPins(bool to_normal) { void BlockView::unmarkPins(bool to_normal) {
unhoverPins(); unhoverPins();
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidType).toInt() == bvitPin) { if (i->data(bvidType).toInt() == bvitPin) {
qgraphicsitem_cast<BlockItemPin*>(i)->restoreState(); qgraphicsitem_cast<BlockItemPin *>(i)->restoreState();
if (to_normal) if (to_normal)
while (qgraphicsitem_cast<BlockItemPin*>(i)->restoreState()); while (qgraphicsitem_cast<BlockItemPin *>(i)->restoreState())
;
} }
} }
} }
@@ -1471,60 +1451,71 @@ void BlockView::hoverAcceptedPin(BlockItemPin * pin, bool hover) {
} }
void BlockView::unhoverPins(BlockItemPin* excl_pin) { void BlockView::unhoverPins(BlockItemPin * excl_pin) {
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (excl_pin == ((BlockItemPin*)i)) continue; if (excl_pin == ((BlockItemPin *)i)) continue;
if (i->data(bvidType).toInt() == bvitPin) { if (i->data(bvidType).toInt() == bvitPin) {
((BlockItemPin*)i)->enlargePin(false); ((BlockItemPin *)i)->enlargePin(false);
} }
} }
} }
void BlockView::simplifyBuses() { void BlockView::simplifyBuses() {
QList<BlockBusItem*> bl = buses(); QList<BlockBusItem *> bl = buses();
foreach (BlockBusItem * b, bl) foreach(BlockBusItem * b, bl)
b->simplify(); b->simplify();
} }
void BlockView::moveBuses(const QList<QGraphicsItem * > & items, QPointF dp) { void BlockView::moveBuses(const QList<QGraphicsItem *> & items, QPointF dp) {
if (dp.isNull()) return; if (dp.isNull()) return;
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
QVector<BlockItemPin * > pins; QVector<BlockItemPin *> pins;
QList<BlockBusItem * > buses; QList<BlockBusItem *> buses;
//qDebug() << "move" << dp; // qDebug() << "move" << dp;
foreach (QGraphicsItem * i, items) foreach(QGraphicsItem * i, items)
if ((i->data(bvidType).toInt() == bvitBlock) && i->flags().testFlag(QGraphicsItem::ItemIsMovable)) if ((i->data(bvidType).toInt() == bvitBlock) && i->flags().testFlag(QGraphicsItem::ItemIsMovable))
pins << qgraphicsitem_cast<BlockItem*>(i)->pins(); pins << qgraphicsitem_cast<BlockItem *>(i)->pins();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->data(bvidType).toInt() == bvitBus) if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
buses << qgraphicsitem_cast<BlockBusItem*>(i); foreach(BlockBusItem * b, buses) {
foreach (BlockBusItem * b, buses) { QList<BlockItemPin *> bpins = b->connections_.values();
QList<BlockItemPin * > bpins = b->connections_.values();
if (!bpins.isEmpty()) { if (!bpins.isEmpty()) {
foreach (BlockItemPin * p, pins) foreach(BlockItemPin * p, pins)
bpins.removeAll(p); bpins.removeAll(p);
if (bpins.isEmpty()) { if (bpins.isEmpty()) {
b->movePolyline(dp); b->movePolyline(dp);
continue; continue;
} }
} }
foreach (BlockItemPin * p, pins) { foreach(BlockItemPin * p, pins) {
QList<int> ends = b->connections_.keys(p); QList<int> ends = b->connections_.keys(p);
for (int i = 0; i < ends.size(); ++i) { for (int i = 0; i < ends.size(); ++i) {
QPointF pdp = dp; QPointF pdp = dp;
double ang = 0.; double ang = 0.;
switch (p->alignment()) { switch (p->alignment()) {
case Qt::AlignRight : pdp.setX(0.); ang = 0.; break; case Qt::AlignRight:
case Qt::AlignTop : pdp.setY(0.); ang = 90.; break; pdp.setX(0.);
case Qt::AlignLeft : pdp.setX(0.); ang = 180.; break; ang = 0.;
case Qt::AlignBottom: pdp.setY(0.); ang = 270.; break; break;
case Qt::AlignTop:
pdp.setY(0.);
ang = 90.;
break;
case Qt::AlignLeft:
pdp.setX(0.);
ang = 180.;
break;
case Qt::AlignBottom:
pdp.setY(0.);
ang = 270.;
break;
default: break; default: break;
} }
QVector<int> epl = b->endpointLine(ends[i], ang); QVector<int> epl = b->endpointLine(ends[i], ang);
foreach (int e, epl) foreach(int e, epl)
b->movePoint(e, pdp); b->movePoint(e, pdp);
b->movePoint(ends[i], dp); b->movePoint(ends[i], dp);
} }
@@ -1533,27 +1524,26 @@ void BlockView::moveBuses(const QList<QGraphicsItem * > & items, QPointF dp) {
} }
QList<BlockBusItem * > BlockView::internalBuses(const QList<BlockItem * > & items) { QList<BlockBusItem *> BlockView::internalBuses(const QList<BlockItem *> & items) {
QList<BlockBusItem * > ret; QList<BlockBusItem *> ret;
if (items.isEmpty()) return ret; if (items.isEmpty()) return ret;
QList<BlockBusItem * > sbl = buses(); QList<BlockBusItem *> sbl = buses();
QSet<BlockItem * > sis = QList2QSet(items); QSet<BlockItem *> sis = QList2QSet(items);
foreach (BlockBusItem * bi, sbl) { foreach(BlockBusItem * bi, sbl) {
if (bi->connectedBlocks().isEmpty()) continue; if (bi->connectedBlocks().isEmpty()) continue;
QSet<BlockItem * > bis = QList2QSet(bi->connectedBlocks()); QSet<BlockItem *> bis = QList2QSet(bi->connectedBlocks());
if ((bis - sis).isEmpty()) if ((bis - sis).isEmpty()) ret << bi;
ret << bi;
} }
return ret; return ret;
} }
QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) { QList<BlockItemPin *> BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
QList<BlockItemPin * > ret; QList<BlockItemPin *> ret;
bool up = km.testFlag(Qt::ShiftModifier); bool up = km.testFlag(Qt::ShiftModifier);
bool down = km.testFlag(Qt::ControlModifier); bool down = km.testFlag(Qt::ControlModifier);
bool ab = km.testFlag(Qt::AltModifier); bool ab = km.testFlag(Qt::AltModifier);
//qDebug() << "nearPins" << km; // qDebug() << "nearPins" << km;
if (!pin || (!up && !down)) return ret; if (!pin || (!up && !down)) return ret;
const BlockItem * src = pin->parent(); const BlockItem * src = pin->parent();
if (!src) return ret; if (!src) return ret;
@@ -1562,17 +1552,16 @@ QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModif
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
if (!dirs[i]) continue; if (!dirs[i]) continue;
const BlockItem * cb = src; const BlockItem * cb = src;
BlockItemPin * cpin = pin; BlockItemPin * cpin = pin;
//qDebug() << "dir" << dirs[i]; // qDebug() << "dir" << dirs[i];
while (cpin) { while (cpin) {
//qDebug() << "cur" << cpin; // qDebug() << "cur" << cpin;
QList<QGraphicsItem * > il = scene_->items(cpin->scenePos() + QPointF(0., dy[i] * cb->pinsMargin())); QList<QGraphicsItem *> il = scene_->items(cpin->scenePos() + QPointF(0., dy[i] * cb->pinsMargin()));
BlockItemPin * np = getPin(il); BlockItemPin * np = getPin(il);
if (np == cpin) break; if (np == cpin) break;
cpin = np; cpin = np;
if (cpin) { if (cpin) {
if (((cb != cpin->parent()) && !ab) || if (((cb != cpin->parent()) && !ab) || (cpin->state() != BlockItemPin::Disconnected)) {
(cpin->state() != BlockItemPin::Disconnected)) {
break; break;
} }
cb = cpin->parent(); cb = cpin->parent();
@@ -1585,20 +1574,19 @@ QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModif
BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const { BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const {
foreach (QGraphicsItem * i, list) { foreach(QGraphicsItem * i, list) {
if (i->data(bvidType).toInt() == bvitPin) if (i->data(bvidType).toInt() == bvitPin) return qgraphicsitem_cast<BlockItemPin *>(i);
return qgraphicsitem_cast<BlockItemPin*>(i);
} }
return 0; return 0;
} }
void BlockView::highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) { void BlockView::highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
//qDebug() << "restore for" << last_multiconnect_pl.size(); // qDebug() << "restore for" << last_multiconnect_pl.size();
foreach (BlockItemPin * p, last_multiconnect_pl) foreach(BlockItemPin * p, last_multiconnect_pl)
p->restoreState(); p->restoreState();
QList<BlockItemPin * > pl = nearPins(pin, km); QList<BlockItemPin *> pl = nearPins(pin, km);
foreach (BlockItemPin * p, pl) { foreach(BlockItemPin * p, pl) {
p->saveState(); p->saveState();
p->setState(BlockItemPin::Hover); p->setState(BlockItemPin::Hover);
} }
@@ -1616,21 +1604,19 @@ void BlockView::hideTmpBuses(bool clear) {
} }
QList<BlockItem * > BlockView::selectedBlocks() const { QList<BlockItem *> BlockView::selectedBlocks() const {
QList<BlockItem * > ret; QList<BlockItem *> ret;
QList<QGraphicsItem * > sil = scene()->selectedItems(); QList<QGraphicsItem *> sil = scene()->selectedItems();
foreach (QGraphicsItem * b, sil) foreach(QGraphicsItem * b, sil)
if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) ret << qgraphicsitem_cast<BlockItem *>(b);
ret << qgraphicsitem_cast<BlockItem*>(b);
return ret; return ret;
} }
QList<QGraphicsItem * > BlockView::selectedDecors() const { QList<QGraphicsItem *> BlockView::selectedDecors() const {
QList<QGraphicsItem * > ret, sil = decors(); QList<QGraphicsItem *> ret, sil = decors();
foreach (QGraphicsItem * b, sil) foreach(QGraphicsItem * b, sil)
if (b->isSelected()) if (b->isSelected()) ret << b;
ret << b;
return ret; return ret;
} }
@@ -1643,7 +1629,7 @@ void BlockView::animateNav(QRectF d, double scl) {
return; return;
} }
if (nav_anim.state() != QAbstractAnimation::Running) { if (nav_anim.state() != QAbstractAnimation::Running) {
nav_prev_aa = renderHints().testFlag(QPainter::Antialiasing); nav_prev_aa = renderHints().testFlag(QPainter::Antialiasing);
nav_prev_imaa = renderHints().testFlag(QPainter::SmoothPixmapTransform); nav_prev_imaa = renderHints().testFlag(QPainter::SmoothPixmapTransform);
nav_prev_grid = isGridVisible(); nav_prev_grid = isGridVisible();
setRenderHint(QPainter::Antialiasing, false); setRenderHint(QPainter::Antialiasing, false);
@@ -1667,14 +1653,11 @@ void BlockView::adjustThumb() {
scl = thumb_size.width() / sr.width(); scl = thumb_size.width() / sr.width();
else else
scl = thumb_size.height() / sr.height(); scl = thumb_size.height() / sr.height();
tr = sr * scl; tr = sr * scl;
int sx = 0, sy = 0; int sx = 0, sy = 0;
if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) sx = verticalScrollBar()->width();
sx = verticalScrollBar()->width(); if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) sy = horizontalScrollBar()->height();
if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) widget_thumb.setGeometry(QRect(QPoint(width() - tr.width() - 10 - sx, height() - tr.height() - 10 - sy), tr.toSize()));
sy = horizontalScrollBar()->height();
widget_thumb.setGeometry(QRect(QPoint(width() - tr.width() - 10 - sx,
height() - tr.height() - 10 - sy), tr.toSize()));
} }
@@ -1695,38 +1678,41 @@ void BlockView::newBranch(BlockBusItem * item) {
void BlockView::startBusPointMove(int bus_type) { void BlockView::startBusPointMove(int bus_type) {
move_bus_point = true; move_bus_point = true;
prev_tcb = m_trace_with_buses; prev_tcb = m_trace_with_buses;
newBusStarted(bus_type); newBusStarted(bus_type);
markPins(bus_type); markPins(bus_type);
} }
void BlockView::pinHoverInOut(BlockItemPin * pin) { void BlockView::pinHoverInOut(BlockItemPin * pin) {
//qDebug() << "pinHoverInOut" << pin << pin->state(); // qDebug() << "pinHoverInOut" << pin << pin->state();
highlightNearPins(pin, QApplication::keyboardModifiers()); highlightNearPins(pin, QApplication::keyboardModifiers());
} }
void BlockView::checkPaste(bool queued) { void BlockView::checkPaste(bool queued) {
const QMimeData * mime = QApplication::clipboard()->mimeData(); const QMimeData * mime = QApplication::clipboard()->mimeData();
bool ret = false; bool ret = false;
if (mime) if (mime) ret = mime->hasFormat(_BlockView_Mime_);
ret = mime->hasFormat(_BlockView_Mime_); if (queued)
if (queued) QMetaObject::invokeMethod(this, [this, ret](){pasteEnabledChanged(ret);}, Qt::QueuedConnection); QMetaObject::invokeMethod(
else emit pasteEnabledChanged(ret); this,
[this, ret]() { pasteEnabledChanged(ret); },
Qt::QueuedConnection);
else
emit pasteEnabledChanged(ret);
} }
void BlockView::setBusSquareNodes(bool yes) { void BlockView::setBusSquareNodes(bool yes) {
square_node = yes; square_node = yes;
QList<BlockBusItem * > sbl = buses(); QList<BlockBusItem *> sbl = buses();
foreach (BlockBusItem * b, sbl) { foreach(BlockBusItem * b, sbl) {
b->setSquareNodes(square_node); b->setSquareNodes(square_node);
} }
} }
void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) { void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) {
trace(item->press_pos, to, &tmp_bus); trace(item->press_pos, to, &tmp_bus);
tmp_bus.show(); tmp_bus.show();
@@ -1740,17 +1726,18 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
tmp_bus.hide(); tmp_bus.hide();
if (tmp_bus.pol.size() < 2) return; if (tmp_bus.pol.size() < 2) return;
tmp_bus.pol.pop_front(); tmp_bus.pol.pop_front();
if ((tmp_bus.pol.size() == 1) && (tmp_bus.pol[0] == item->press_pos)) if ((tmp_bus.pol.size() == 1) && (tmp_bus.pol[0] == item->press_pos)) return;
return;
int np = item->addPoint(item->press_pos); int np = item->addPoint(item->press_pos);
if (np < 0) return; if (np < 0) return;
if (match_bus) { if (match_bus) {
if (iconnect) tmp_bus.pol.pop_back(); if (iconnect)
else return; tmp_bus.pol.pop_back();
else
return;
} }
if (item == match_bus) return; if (item == match_bus) return;
int snp = np; int snp = np;
int lp = item->pol.size(); int lp = item->pol.size();
if (!tmp_bus.pol.isEmpty()) { if (!tmp_bus.pol.isEmpty()) {
item->pol << tmp_bus.pol; item->pol << tmp_bus.pol;
item->segments << QPair<int, int>(np, lp); item->segments << QPair<int, int>(np, lp);
@@ -1760,8 +1747,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
if (match_bus != 0) { if (match_bus != 0) {
if (!iconnect) return; if (!iconnect) return;
np = match_bus->selPoint; np = match_bus->selPoint;
if (np < 0) if (np < 0) np = match_bus->addPoint(trace_to);
np = match_bus->addPoint(trace_to);
if (np < 0) return; if (np < 0) return;
lp = item->pol.size(); lp = item->pol.size();
item->pol << match_bus->pol; item->pol << match_bus->pol;
@@ -1777,7 +1763,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
} }
item->updateGeometry(); item->updateGeometry();
newBusCreated(item); newBusCreated(item);
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << item); emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << item);
emit connectionsChanged(); emit connectionsChanged();
tmp_bus.clear(); tmp_bus.clear();
} }
@@ -1785,7 +1771,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
void BlockView::newBranchCancel() { void BlockView::newBranchCancel() {
unmarkPins(); unmarkPins();
//qDebug() << "cancel"; // qDebug() << "cancel";
new_branch = false; new_branch = false;
hideTmpBuses(); hideTmpBuses();
} }
@@ -1794,25 +1780,25 @@ void BlockView::newBranchCancel() {
void BlockView::removedBus(QObject * o) { void BlockView::removedBus(QObject * o) {
mm_ci = 0; mm_ci = 0;
reconnectAll(); reconnectAll();
BlockBusItem * bus = (BlockBusItem*)o; BlockBusItem * bus = (BlockBusItem *)o;
if (bus->property("_nodelete_").toBool()) return; if (bus->property("_nodelete_").toBool()) return;
emitActionEvent(BlockItemBase::BusRemove, QList<QGraphicsItem*>() << bus); emitActionEvent(BlockItemBase::BusRemove, QList<QGraphicsItem *>() << bus);
emit connectionsChanged(); emit connectionsChanged();
} }
void BlockView::removedBlock(QObject * o) { void BlockView::removedBlock(QObject * o) {
if (o == ghost_) return; if (o == ghost_) return;
emit blockRemoved((BlockItem*)o); emit blockRemoved((BlockItem *)o);
emitActionEvent(BlockItemBase::BlockRemove, QList<QGraphicsItem*>() << qgraphicsitem_cast<QGraphicsItem*>((BlockItem*)o)); emitActionEvent(BlockItemBase::BlockRemove, QList<QGraphicsItem *>() << qgraphicsitem_cast<QGraphicsItem *>((BlockItem *)o));
} }
void BlockView::removeJunk() { void BlockView::removeJunk() {
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidType).toInt() != bvitBus) continue; if (i->data(bvidType).toInt() != bvitBus) continue;
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem*>(i); BlockBusItem * b = qgraphicsitem_cast<BlockBusItem *>(i);
if (b->pol.size() <= 1) { if (b->pol.size() <= 1) {
b->deleteLater(); b->deleteLater();
} }
@@ -1823,17 +1809,21 @@ void BlockView::removeJunk() {
void BlockView::sceneSelectionChanged() { void BlockView::sceneSelectionChanged() {
bool ie = scene()->selectedItems().isEmpty(); bool ie = scene()->selectedItems().isEmpty();
emit copyEnabledChanged(!ie); emit copyEnabledChanged(!ie);
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
void BlockView::_setThumb(double v) { void BlockView::_setThumb(double v) {
_talpha = v; _talpha = v;
QWidget * w = &widget_thumb; QWidget * w = &widget_thumb;
QMetaObject::invokeMethod(this, [w](){w->update();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
if (_talpha <= 0.01) widget_thumb.hide(); this,
else widget_thumb.show(); [w]() { w->update(); },
Qt::QueuedConnection);
if (_talpha <= 0.01)
widget_thumb.hide();
else
widget_thumb.show();
} }
@@ -1841,7 +1831,7 @@ void BlockView::_setNav(QRectF v) {
double vw = viewport()->width(), vh = viewport()->height(); double vw = viewport()->width(), vh = viewport()->height();
if (vw < 1. || vh < 1. || v.isEmpty()) return; if (vw < 1. || vh < 1. || v.isEmpty()) return;
QTransform matrix; QTransform matrix;
double scl = qMin(vw / v.width(), vh / v.height()); double scl = qMin(vw / v.width(), vh / v.height());
double ascl = appScale(this); double ascl = appScale(this);
if (scl > 0.02 * ascl && scl < 50.0 * ascl) { if (scl > 0.02 * ascl && scl < 50.0 * ascl) {
matrix.scale(scl, scl); matrix.scale(scl, scl);
@@ -1865,23 +1855,21 @@ void BlockView::_navFinished() {
void BlockView::reconnectAll() { void BlockView::reconnectAll() {
//qDebug() << "reconnect"; // qDebug() << "reconnect";
removeJunk(); removeJunk();
QList<QGraphicsItem * > gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
QList<BlockItemPin * > pins; QList<BlockItemPin *> pins;
QList<BlockBusItem * > buses; QList<BlockBusItem *> buses;
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidType).toInt() == bvitPin) if (i->data(bvidType).toInt() == bvitPin) pins << qgraphicsitem_cast<BlockItemPin *>(i);
pins << qgraphicsitem_cast<BlockItemPin*>(i); if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
if (i->data(bvidType).toInt() == bvitBus)
buses << qgraphicsitem_cast<BlockBusItem*>(i);
} }
foreach (BlockItemPin * p, pins) { foreach(BlockItemPin * p, pins) {
p->clearStateStack(); p->clearStateStack();
p->setState(BlockItemPin::Disconnected); p->setState(BlockItemPin::Disconnected);
p->buses_.clear(); p->buses_.clear();
} }
foreach (BlockBusItem * b, buses) { foreach(BlockBusItem * b, buses) {
b->connections_.clear(); b->connections_.clear();
QVector<int> conns(b->endpoints()); QVector<int> conns(b->endpoints());
for (int c = 0; c < conns.size(); ++c) { for (int c = 0; c < conns.size(); ++c) {
@@ -1890,11 +1878,10 @@ void BlockView::reconnectAll() {
if (!pins[j]->isVisible()) continue; if (!pins[j]->isVisible()) continue;
QPointF pp = pins[j]->scenePos(); QPointF pp = pins[j]->scenePos();
if ((cp - pp).manhattanLength() <= (grid_step / 2.)) { if ((cp - pp).manhattanLength() <= (grid_step / 2.)) {
//qDebug() << "found"; // qDebug() << "found";
if (b->busType() == pins[j]->busType()) { if (b->busType() == pins[j]->busType()) {
b->connections_[conns[c]] = pins[j]; b->connections_[conns[c]] = pins[j];
if (!pins[j]->buses_.contains(b)) if (!pins[j]->buses_.contains(b)) pins[j]->buses_ << b;
pins[j]->buses_ << b;
pins[j]->setState(BlockItemPin::Connected); pins[j]->setState(BlockItemPin::Connected);
} else } else
pins[j]->setState(BlockItemPin::Reject); pins[j]->setState(BlockItemPin::Reject);
@@ -1903,17 +1890,18 @@ void BlockView::reconnectAll() {
} }
} }
} }
//qDebug() << pins.size() << buses.size(); // qDebug() << pins.size() << buses.size();
} }
void BlockView::zoom(double factor) { void BlockView::zoom(double factor) {
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) nav_target = _nav();
nav_target = _nav();
QRectF r = nav_target; QRectF r = nav_target;
QPoint mp; QPoint mp;
if (underMouse()) mp = mapFromGlobal(QCursor::pos()); if (underMouse())
else mp = QPoint(viewport()->width() / 2, viewport()->height() / 2); mp = mapFromGlobal(QCursor::pos());
else
mp = QPoint(viewport()->width() / 2, viewport()->height() / 2);
double cx = double(mp.x()) / viewport()->width(), cy = double(mp.y()) / viewport()->height(); double cx = double(mp.x()) / viewport()->width(), cy = double(mp.y()) / viewport()->height();
double pw = r.width(), ph = r.height(); double pw = r.width(), ph = r.height();
r.setWidth(r.width() / factor); r.setWidth(r.width() / factor);
@@ -1930,11 +1918,11 @@ void BlockView::zoomReset() {
void BlockView::copyToClipboard() { void BlockView::copyToClipboard() {
QList<BlockItem*> bll = selectedBlocks(); QList<BlockItem *> bll = selectedBlocks();
QList<QGraphicsItem*> del = selectedDecors(); QList<QGraphicsItem *> del = selectedDecors();
//qDebug() << "copy" << bll.size() << del.size(); // qDebug() << "copy" << bll.size() << del.size();
if (bll.isEmpty() && del.isEmpty()) return; if (bll.isEmpty() && del.isEmpty()) return;
QList<BlockBusItem*> bul = internalBuses(bll); QList<BlockBusItem *> bul = internalBuses(bll);
QByteArray ba; QByteArray ba;
QDataStream s(&ba, QIODevice::ReadWrite); QDataStream s(&ba, QIODevice::ReadWrite);
s << uint(0x89abcdef) << bll << bul << del; s << uint(0x89abcdef) << bll << bul << del;
@@ -1949,11 +1937,11 @@ void BlockView::pasteFromClipboard() {
if (!mime) return; if (!mime) return;
if (!mime->hasFormat(_BlockView_Mime_)) return; if (!mime->hasFormat(_BlockView_Mime_)) return;
QByteArray ba = mime->data(_BlockView_Mime_); QByteArray ba = mime->data(_BlockView_Mime_);
//qDebug() << "paste" << ba.size(); // qDebug() << "paste" << ba.size();
if (ba.size() < 4) return; if (ba.size() < 4) return;
QList<BlockItem*> bll; QList<BlockItem *> bll;
QList<BlockBusItem*> bul; QList<BlockBusItem *> bul;
QList<QGraphicsItem*> del, gl; QList<QGraphicsItem *> del, gl;
uint hdr = 0; uint hdr = 0;
QDataStream s(ba); QDataStream s(ba);
s >> hdr; s >> hdr;
@@ -1962,24 +1950,26 @@ void BlockView::pasteFromClipboard() {
int all = bll.size() + bul.size() + del.size(); int all = bll.size() + bul.size() + del.size();
if (all == 0) return; if (all == 0) return;
QRectF br; QRectF br;
foreach (BlockItem * b, bll) { foreach(BlockItem * b, bll) {
br |= b->boundingRect().translated(b->pos()); br |= b->boundingRect().translated(b->pos());
gl << b; gl << b;
} }
foreach (BlockBusItem * b, bul) foreach(BlockBusItem * b, bul)
gl << b; gl << b;
foreach (QGraphicsItem * b, del) foreach(QGraphicsItem * b, del)
br |= b->boundingRect().translated(b->pos()); br |= b->boundingRect().translated(b->pos());
gl << del; gl << del;
QPointF copy_dp; QPointF copy_dp;
if (underMouse()) copy_dp = mapToScene(mapFromGlobal(QCursor::pos())); if (underMouse())
else copy_dp = mapToScene(rect().center()); copy_dp = mapToScene(mapFromGlobal(QCursor::pos()));
else
copy_dp = mapToScene(rect().center());
copy_dp -= br.center(); copy_dp -= br.center();
copy_dp = quantize(copy_dp, grid_step); copy_dp = quantize(copy_dp, grid_step);
ae_enabled = false; ae_enabled = false;
if (!bll.isEmpty()) copyBlocks(bll, copy_dp); if (!bll.isEmpty()) copyBlocks(bll, copy_dp);
if (!bul.isEmpty()) copyBuses(bul, copy_dp); if (!bul.isEmpty()) copyBuses(bul, copy_dp);
foreach (QGraphicsItem * i, del) foreach(QGraphicsItem * i, del)
i->setPos(i->pos() + copy_dp); i->setPos(i->pos() + copy_dp);
addItems(del); addItems(del);
ae_enabled = true; ae_enabled = true;
@@ -1988,80 +1978,75 @@ void BlockView::pasteFromClipboard() {
void BlockView::selectNone() { void BlockView::selectNone() {
bool pb = block_emit_selection; bool pb = block_emit_selection;
block_emit_selection = true; block_emit_selection = true;
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
i->setSelected(false); i->setSelected(false);
block_emit_selection = pb; block_emit_selection = pb;
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
void BlockView::selectAll() { void BlockView::selectAll() {
bool pb = block_emit_selection; bool pb = block_emit_selection;
block_emit_selection = true; block_emit_selection = true;
QList<QGraphicsItem*> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach (QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(true);
i->setSelected(true);
block_emit_selection = pb; block_emit_selection = pb;
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
void BlockView::removeSelected() { void BlockView::removeSelected() {
QList<QGraphicsItem*> gi = scene_->selectedItems(), ai; QList<QGraphicsItem *> gi = scene_->selectedItems(), ai;
blockSignals(true); blockSignals(true);
QList<BlockBusItem * > sbuses = buses(), dbuses, wbuses = wrongConnectedBuses(); QList<BlockBusItem *> sbuses = buses(), dbuses, wbuses = wrongConnectedBuses();
foreach (BlockBusItem * i, sbuses) foreach(BlockBusItem * i, sbuses)
if (i->connectedBlocks().isEmpty()) if (i->connectedBlocks().isEmpty()) dbuses << i;
dbuses << i; foreach(QGraphicsItem * i, gi) {
foreach (QGraphicsItem * i, gi) {
if (i->data(bvidTmpItem).toBool()) continue; if (i->data(bvidTmpItem).toBool()) continue;
if (i->data(bvidType).toInt() == bvitBlock) if (i->data(bvidType).toInt() == bvitBlock) ai << qgraphicsitem_cast<QGraphicsItem *>(i);
ai << qgraphicsitem_cast<QGraphicsItem*>(i); if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) ||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) || (i->data(bvidType).toInt() == bvitDecor)) { (i->data(bvidType).toInt() == bvitDecor)) {
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close)); scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
delete i; delete i;
} }
} }
reconnectAll(); reconnectAll();
foreach (BlockBusItem * i, sbuses) foreach(BlockBusItem * i, sbuses)
if (i->connectedBlocks().isEmpty()) if (i->connectedBlocks().isEmpty())
if (!dbuses.contains(i)) if (!dbuses.contains(i)) delete i;
delete i;
blockSignals(false); blockSignals(false);
foreach (QGraphicsItem * i, ai) foreach(QGraphicsItem * i, ai)
emit blockRemoved((BlockItem*)i); emit blockRemoved((BlockItem *)i);
emitActionEvent(BlockItemBase::BlockRemove, ai); emitActionEvent(BlockItemBase::BlockRemove, ai);
} }
void BlockView::removeAll() { void BlockView::removeAll() {
last_multiconnect_pl.clear(); last_multiconnect_pl.clear();
QList<QGraphicsItem*> gi = scene_->items(), ai; QList<QGraphicsItem *> gi = scene_->items(), ai;
blockSignals(true); blockSignals(true);
match_bus = bus_from = cur_bus = nullptr; match_bus = bus_from = cur_bus = nullptr;
mm_ci = nullptr; mm_ci = nullptr;
hpin = nullptr; hpin = nullptr;
ghost_ = nullptr; ghost_ = nullptr;
foreach (QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidTmpItem).toBool()) continue; if (i->data(bvidTmpItem).toBool()) continue;
if (i->data(bvidType).toInt() == bvitBlock) if (i->data(bvidType).toInt() == bvitBlock) ai << qgraphicsitem_cast<QGraphicsItem *>(i);
ai << qgraphicsitem_cast<QGraphicsItem*>(i); if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) ||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) || (i->data(bvidType).toInt() == bvitDecor)) { (i->data(bvidType).toInt() == bvitDecor)) {
if ((i != &sel_rect) && (i != &tmp_bus) && (i->parentItem() == 0) && !(i->data(bvidItemSelection).toBool())) { if ((i != &sel_rect) && (i != &tmp_bus) && (i->parentItem() == 0) && !(i->data(bvidItemSelection).toBool())) {
//qDebug() << "delete" << i->data(1005).toInt(); // qDebug() << "delete" << i->data(1005).toInt();
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close)); scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
delete i; delete i;
} }
} }
} }
blockSignals(false); blockSignals(false);
foreach (QGraphicsItem * i, ai) foreach(QGraphicsItem * i, ai)
emit blockRemoved((BlockItem*)i); emit blockRemoved((BlockItem *)i);
} }
+107 -91
View File
@@ -1,45 +1,45 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKVIEW_H #ifndef BLOCKVIEW_H
#define BLOCKVIEW_H #define BLOCKVIEW_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPainter>
#include <QPixmap>
#include <QMouseEvent>
#include <QDebug>
#include <QTime>
#include <QPropertyAnimation>
#include "blockviewwavetrace.h"
#include "blockbusitem.h" #include "blockbusitem.h"
#include "blockviewwavetrace.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QDebug>
Q_DECLARE_METATYPE(BlockItem*) #include <QGraphicsScene>
Q_DECLARE_METATYPE(BlockItemPin*) #include <QGraphicsView>
Q_DECLARE_METATYPE(BlockBusItem*) #include <QMouseEvent>
#include <QPainter>
#include <QPixmap>
#include <QPropertyAnimation>
#include <QTime>
class QAD_BLOCKVIEW_EXPORT BlockView: public QGraphicsView Q_DECLARE_METATYPE(BlockItem *)
{ Q_DECLARE_METATYPE(BlockItemPin *)
Q_DECLARE_METATYPE(BlockBusItem *)
class QAD_BLOCKVIEW_EXPORT BlockView: public QGraphicsView {
Q_OBJECT Q_OBJECT
Q_ENUMS(SelectionMode) Q_ENUMS(SelectionMode)
@@ -77,34 +77,37 @@ public:
MultiSelection MultiSelection
}; };
QPen gridPen() const {return grid_pen;} QPen gridPen() const { return grid_pen; }
bool isGridVisible() const {return grid_visible;} bool isGridVisible() const { return grid_visible; }
bool isSnapToGrid() const {return grid_snap;} bool isSnapToGrid() const { return grid_snap; }
bool isPostMoveConnectEnabled() const {return pm_connect;} bool isPostMoveConnectEnabled() const { return pm_connect; }
bool isNavigationEnabled() const {return navigation;} bool isNavigationEnabled() const { return navigation; }
bool isNavigateAnimationEnabled() const {return is_nav_anim;} bool isNavigateAnimationEnabled() const { return is_nav_anim; }
bool isBlockAnimationEnabled() const {return is_block_anim;} bool isBlockAnimationEnabled() const { return is_block_anim; }
bool isConnectByMouseEnabled() const {return m_connect;} bool isConnectByMouseEnabled() const { return m_connect; }
bool isTraceConsiderBuses() const {return m_trace_with_buses;} bool isTraceConsiderBuses() const { return m_trace_with_buses; }
bool isPinMulticonnectEnabled() const {return m_pin_mc;} bool isPinMulticonnectEnabled() const { return m_pin_mc; }
bool isMiniMapEnabled() const {return minimap;} bool isMiniMapEnabled() const { return minimap; }
bool isZoomWheelOnly() const {return wheel_zoom;} bool isZoomWheelOnly() const { return wheel_zoom; }
bool isBusSquareNodes() const {return square_node;} bool isBusSquareNodes() const { return square_node; }
double gridStep() const {return grid_step;} double gridStep() const { return grid_step; }
double gridPointsWidth() const {return grid_points;} double gridPointsWidth() const { return grid_points; }
SelectionMode selectionMode() const {return smode;} SelectionMode selectionMode() const { return smode; }
void setSelectionMode(SelectionMode mode) {smode = mode;} void setSelectionMode(SelectionMode mode) { smode = mode; }
void addItems(QList<QGraphicsItem * > items) {foreach (QGraphicsItem * i, items) addItem(i);} void addItems(QList<QGraphicsItem *> items) {
QList<BlockBusItem * > buses() const; foreach(QGraphicsItem * i, items)
QList<BlockBusItem * > wrongConnectedBuses() const; addItem(i);
QList<BlockItem * > blocks() const; }
QList<QGraphicsItem * > decors() const; QList<BlockBusItem *> buses() const;
QList<BlockBusItem *> wrongConnectedBuses() const;
QList<BlockItem *> blocks() const;
QList<QGraphicsItem *> decors() const;
BlockBusItem * connectionBus(BlockItem * b0, BlockItem * b1) const; BlockBusItem * connectionBus(BlockItem * b0, BlockItem * b1) const;
QList<BlockBusItem * > connectionBuses(BlockItem * b0, BlockItem * b1) const; QList<BlockBusItem *> connectionBuses(BlockItem * b0, BlockItem * b1) const;
bool connectPins(BlockItemPin * p0, BlockItemPin * p1); bool connectPins(BlockItemPin * p0, BlockItemPin * p1);
QList<BlockItem * > selectedBlocks() const; QList<BlockItem *> selectedBlocks() const;
QList<QGraphicsItem * > selectedDecors() const; QList<QGraphicsItem *> selectedDecors() const;
void setTransform(const QTransform & matrix, bool combine = false); void setTransform(const QTransform & matrix, bool combine = false);
void centerOn(const QPointF & pos); void centerOn(const QPointF & pos);
@@ -149,42 +152,42 @@ protected:
void trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary = true); void trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary = true);
void clearBusStates(); void clearBusStates();
void matchBus(); void matchBus();
bool connectTmpToBus(BlockBusItem* bus); bool connectTmpToBus(BlockBusItem * bus);
void markPins(int bus_type); void markPins(int bus_type);
void unmarkPins(bool to_normal = false); void unmarkPins(bool to_normal = false);
void hoverAcceptedPin(BlockItemPin * pin, bool hover); void hoverAcceptedPin(BlockItemPin * pin, bool hover);
void unhoverPins(BlockItemPin * excl_pin = 0); void unhoverPins(BlockItemPin * excl_pin = 0);
void simplifyBuses(); void simplifyBuses();
void moveBuses(const QList<QGraphicsItem * > & items, QPointF dp); void moveBuses(const QList<QGraphicsItem *> & items, QPointF dp);
QList<BlockBusItem * > internalBuses(const QList<BlockItem * > & items); QList<BlockBusItem *> internalBuses(const QList<BlockItem *> & items);
QList<BlockItemPin * > nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km); QList<BlockItemPin *> nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
BlockItemPin * getPin(const QList<QGraphicsItem * > & list) const; BlockItemPin * getPin(const QList<QGraphicsItem *> & list) const;
void highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km); void highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
void hideTmpBuses(bool clear = true); void hideTmpBuses(bool clear = true);
double _thumb() const {return _talpha;} double _thumb() const { return _talpha; }
QRectF _nav() const; QRectF _nav() const;
void animateNav(QRectF d, double scl = 0.); void animateNav(QRectF d, double scl = 0.);
void scrollFromThumb(); void scrollFromThumb();
void deleteCopyTemp(); void deleteCopyTemp();
void emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem * > items); void emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem *> items);
void setGhost(BlockItem * item); void setGhost(BlockItem * item);
void clearGhost(); void clearGhost();
BlockItem * ghost() const {return ghost_;} BlockItem * ghost() const { return ghost_; }
virtual void loadBus(BlockBusItem * bus) {} virtual void loadBus(BlockBusItem * bus) {}
virtual void copyBlocks(QList<BlockItem * > items, QPointF offset) {} virtual void copyBlocks(QList<BlockItem *> items, QPointF offset) {}
virtual void copyBuses(QList<BlockBusItem * > items, QPointF offset) {} virtual void copyBuses(QList<BlockBusItem *> items, QPointF offset) {}
virtual void newBusStarted(int bus_type) {} virtual void newBusStarted(int bus_type) {}
virtual void newBusCreated(BlockBusItem * bus) {} virtual void newBusCreated(BlockBusItem * bus) {}
QGraphicsScene * scene_; QGraphicsScene * scene_;
QGraphicsRectItem sel_rect; QGraphicsRectItem sel_rect;
QGraphicsItem * mm_ci; QGraphicsItem * mm_ci;
QList<QGraphicsItem * > sel_items; QList<QGraphicsItem *> sel_items;
QList<BlockItem * > copy_items; QList<BlockItem *> copy_items;
QList<BlockItemPin * > last_multiconnect_pl; QList<BlockItemPin *> last_multiconnect_pl;
QList<BlockBusItem * > copy_buses, tmp_buses; QList<BlockBusItem *> copy_buses, tmp_buses;
BlockBusItem tmp_bus, * match_bus, * bus_from, * cur_bus; BlockBusItem tmp_bus, *match_bus, *bus_from, *cur_bus;
BlockItemPin * hpin; BlockItemPin * hpin;
BlockItem * ghost_; BlockItem * ghost_;
BlockViewWavetrace wavetrace; BlockViewWavetrace wavetrace;
@@ -200,7 +203,8 @@ protected:
Qt::KeyboardModifiers mm_mods; Qt::KeyboardModifiers mm_mods;
QPropertyAnimation thumb_anim, nav_anim; QPropertyAnimation thumb_anim, nav_anim;
int timer_thumb, thumb_hide_delay, thick; int timer_thumb, thumb_hide_delay, thick;
bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim, is_block_anim, move_bus_point; bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim, is_block_anim,
move_bus_point;
bool grid_visible, grid_snap, pm_connect, navigation, m_connect, m_trace_with_buses, m_pin_mc, minimap, prev_tcb, wheel_zoom; bool grid_visible, grid_snap, pm_connect, navigation, m_connect, m_trace_with_buses, m_pin_mc, minimap, prev_tcb, wheel_zoom;
bool nav_prev_aa, nav_prev_imaa, nav_prev_grid, square_node, block_emit_selection; bool nav_prev_aa, nav_prev_imaa, nav_prev_grid, square_node, block_emit_selection;
double grid_step, grid_points, cur_scl, _talpha, thumb_scl; double grid_step, grid_points, cur_scl, _talpha, thumb_scl;
@@ -225,28 +229,41 @@ protected slots:
void startBusPointMove(int bus_type); void startBusPointMove(int bus_type);
void pinHoverInOut(BlockItemPin * pin); void pinHoverInOut(BlockItemPin * pin);
void checkPaste(bool queued); void checkPaste(bool queued);
void checkPaste() {checkPaste(false);} void checkPaste() { checkPaste(false); }
public slots: public slots:
void setGridPen(const QPen & pen) {grid_pen = pen; _updateBack();} void setGridPen(const QPen & pen) {
void setGridVisible(bool yes) {grid_visible = yes; _updateBack();} grid_pen = pen;
void setSnapToGrid(bool yes) {grid_snap = yes;} _updateBack();
void setGridStep(double step) {grid_step = step; applyGridStep(); _updateBack();} }
void setGridPointsWidth(double width_) {grid_points = width_; _updateBack();} void setGridVisible(bool yes) {
void setPostMoveConnectEnabled(bool on) {pm_connect = on;} grid_visible = yes;
void setNavigationEnabled(bool on) {navigation = on;} _updateBack();
void setNavigateAnimationEnabled(bool on) {is_nav_anim = on;} }
void setBlockAnimationEnabled(bool on) {is_block_anim = on;} void setSnapToGrid(bool yes) { grid_snap = yes; }
void setConnectByMouseEnabled(bool on) {m_connect = on;} void setGridStep(double step) {
void setTraceConsiderBuses(bool on) {m_trace_with_buses = on;} grid_step = step;
void setPinMulticonnectEnabled(bool on) {m_pin_mc = on;} applyGridStep();
void setMiniMapEnabled(bool on) {minimap = on;} _updateBack();
void setZoomWheelOnly(bool on) {wheel_zoom = on;} }
void setGridPointsWidth(double width_) {
grid_points = width_;
_updateBack();
}
void setPostMoveConnectEnabled(bool on) { pm_connect = on; }
void setNavigationEnabled(bool on) { navigation = on; }
void setNavigateAnimationEnabled(bool on) { is_nav_anim = on; }
void setBlockAnimationEnabled(bool on) { is_block_anim = on; }
void setConnectByMouseEnabled(bool on) { m_connect = on; }
void setTraceConsiderBuses(bool on) { m_trace_with_buses = on; }
void setPinMulticonnectEnabled(bool on) { m_pin_mc = on; }
void setMiniMapEnabled(bool on) { minimap = on; }
void setZoomWheelOnly(bool on) { wheel_zoom = on; }
void setBusSquareNodes(bool yes); void setBusSquareNodes(bool yes);
void zoom(double factor); void zoom(double factor);
void zoomIn() {zoom(1.2);} void zoomIn() { zoom(1.2); }
void zoomOut() {zoom(1. / 1.2);} void zoomOut() { zoom(1. / 1.2); }
void zoomReset(); void zoomReset();
void copyToClipboard(); void copyToClipboard();
@@ -261,17 +278,16 @@ public slots:
void addItem(QGraphicsItem * item, bool emit_action = true); void addItem(QGraphicsItem * item, bool emit_action = true);
signals: signals:
void blockDoubleClicked(BlockItem * ); void blockDoubleClicked(BlockItem *);
void blockHoverEnter(BlockItem * ); void blockHoverEnter(BlockItem *);
void blockHoverLeave(BlockItem * ); void blockHoverLeave(BlockItem *);
void busDoubleClicked(BlockBusItem * ); void busDoubleClicked(BlockBusItem *);
void schemeAction(BlockItemBase::Action action, QList<QGraphicsItem * > items); void schemeAction(BlockItemBase::Action action, QList<QGraphicsItem *> items);
void blockRemoved(BlockItem * item); void blockRemoved(BlockItem * item);
void connectionsChanged(); void connectionsChanged();
void copyEnabledChanged(bool); void copyEnabledChanged(bool);
void pasteEnabledChanged(bool); void pasteEnabledChanged(bool);
void selectionChanged(); void selectionChanged();
}; };
#endif // BLOCKVIEW_H #endif // BLOCKVIEW_H
+18 -27
View File
@@ -11,8 +11,7 @@ BlockViewWavetrace::BlockViewWavetrace(int width, int height) {
void BlockViewWavetrace::resize(int width, int height) { void BlockViewWavetrace::resize(int width, int height) {
wid = width; wid = width;
hei = height; hei = height;
if (field.size() != wid) if (field.size() != wid) field.resize(wid);
field.resize(wid);
for (int i = 0; i < wid; ++i) { for (int i = 0; i < wid; ++i) {
if (field[i].size() != hei) { if (field[i].size() != hei) {
field[i].resize(hei); field[i].resize(hei);
@@ -41,8 +40,7 @@ void BlockViewWavetrace::fill(const QRect & rect, short val) {
void BlockViewWavetrace::fill(int px, int py, short val) { void BlockViewWavetrace::fill(int px, int py, short val) {
short p = field[px][py].value; short p = field[px][py].value;
if ((val == HorizontalBus && p == VerticalBus ) || if ((val == HorizontalBus && p == VerticalBus) || (val == VerticalBus && p == HorizontalBus))
(val == VerticalBus && p == HorizontalBus))
field[px][py].value = Blocked; field[px][py].value = Blocked;
else else
field[px][py].value = val; field[px][py].value = val;
@@ -54,14 +52,13 @@ bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
st = start; st = start;
fn = finish; fn = finish;
if (dir_ == NoTrace) return true; if (dir_ == NoTrace) return true;
//qDebug() << "trace" << start << finish; // qDebug() << "trace" << start << finish;
short cl = 0; short cl = 0;
QRect frect(0, 0, wid - 1, hei - 1); QRect frect(0, 0, wid - 1, hei - 1);
QVector<QPoint> cpnts, npnts; QVector<QPoint> cpnts, npnts;
fill(st, cl); fill(st, cl);
cpnts.push_back(st); cpnts.push_back(st);
if (field[fn.x()][fn.y()].value == (short)Blocked) if (field[fn.x()][fn.y()].value == (short)Blocked) return false;
return false;
auto checkAndFill = [this, &npnts, &frect](int x, int y, short acc_dir, short c) { auto checkAndFill = [this, &npnts, &frect](int x, int y, short acc_dir, short c) {
if (!frect.contains(x, y)) return; if (!frect.contains(x, y)) return;
short p = field[x][y].value; short p = field[x][y].value;
@@ -73,18 +70,16 @@ bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
while (cpnts.size() > 0) { while (cpnts.size() > 0) {
npnts.clear(); npnts.clear();
cl++; cl++;
if (cl >= max_steps) if (cl >= max_steps) return false;
return false;
for (int i = 0; i < cpnts.size(); ++i) { for (int i = 0; i < cpnts.size(); ++i) {
if (cpnts[i] == fn) if (cpnts[i] == fn) return true;
return true; checkAndFill(cpnts[i].x() - 1, cpnts[i].y(), (short)VerticalBus, cl);
checkAndFill(cpnts[i].x() - 1, cpnts[i].y() , (short)VerticalBus , cl); checkAndFill(cpnts[i].x() + 1, cpnts[i].y(), (short)VerticalBus, cl);
checkAndFill(cpnts[i].x() + 1, cpnts[i].y() , (short)VerticalBus , cl); checkAndFill(cpnts[i].x(), cpnts[i].y() - 1, (short)HorizontalBus, cl);
checkAndFill(cpnts[i].x() , cpnts[i].y() - 1, (short)HorizontalBus, cl); checkAndFill(cpnts[i].x(), cpnts[i].y() + 1, (short)HorizontalBus, cl);
checkAndFill(cpnts[i].x() , cpnts[i].y() + 1, (short)HorizontalBus, cl);
} }
cpnts = npnts; cpnts = npnts;
//qDebug() << cl << ": " << cpnts.size(); // qDebug() << cl << ": " << cpnts.size();
} }
return false; return false;
} }
@@ -99,25 +94,22 @@ void BlockViewWavetrace::gatherPath() {
} }
int pa = -1, ca = -1; int pa = -1, ca = -1;
bool first = true; bool first = true;
short cl = field[fn.x()][fn.y()].value; short cl = field[fn.x()][fn.y()].value;
QRect frect(0, 0, wid, hei); QRect frect(0, 0, wid, hei);
QPoint cpnt = fn; QPoint cpnt = fn;
auto checkAndStep = [this, &cpnt, &first, &frect] (int dir, short c, int & ca_, int pa_)->bool { auto checkAndStep = [this, &cpnt, &first, &frect](int dir, short c, int & ca_, int pa_) -> bool {
int cx = cpnt.x() + dps[dir].x(); int cx = cpnt.x() + dps[dir].x();
int cy = cpnt.y() + dps[dir].y(); int cy = cpnt.y() + dps[dir].y();
if (frect.contains(cx, cy)) { if (frect.contains(cx, cy)) {
const Cell & cell(field[cx][cy]); const Cell & cell(field[cx][cy]);
if (cell.value == c) { if (cell.value == c) {
if (cell.direction == HorizontalBus || cell.direction == VerticalBus) { if (cell.direction == HorizontalBus || cell.direction == VerticalBus) {
if (dps[dir].x() == 0 && cell.direction == VerticalBus) if (dps[dir].x() == 0 && cell.direction == VerticalBus) return false;
return false; if (dps[dir].y() == 0 && cell.direction == HorizontalBus) return false;
if (dps[dir].y() == 0 && cell.direction == HorizontalBus)
return false;
} }
ca_ = QLineF(QPointF(cx, cy), cpnt).angle(); ca_ = QLineF(QPointF(cx, cy), cpnt).angle();
if (ca_ != pa_ && !first) if (ca_ != pa_ && !first) path_.push_front(cpnt);
path_.push_front(cpnt); cpnt = QPoint(cx, cy);
cpnt = QPoint(cx, cy);
first = false; first = false;
return true; return true;
} }
@@ -132,7 +124,6 @@ void BlockViewWavetrace::gatherPath() {
if (checkAndStep(1, cl, ca, pa)) continue; if (checkAndStep(1, cl, ca, pa)) continue;
if (checkAndStep(2, cl, ca, pa)) continue; if (checkAndStep(2, cl, ca, pa)) continue;
if (checkAndStep(3, cl, ca, pa)) continue; if (checkAndStep(3, cl, ca, pa)) continue;
} }
path_.push_front(st); path_.push_front(st);
} }
+36 -28
View File
@@ -1,20 +1,20 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BLOCKVIEWWAVETRACE_H #ifndef BLOCKVIEWWAVETRACE_H
@@ -28,27 +28,36 @@ class QAD_BLOCKVIEW_EXPORT BlockViewWavetrace {
public: public:
BlockViewWavetrace(int width = 1, int height = 1); BlockViewWavetrace(int width = 1, int height = 1);
enum CellState {Empty = -1, Blocked = -2, HorizontalBus = -3, VerticalBus = -4}; enum CellState {
enum Direction {NoTrace, Horizontal, Vertical}; Empty = -1,
Blocked = -2,
HorizontalBus = -3,
VerticalBus = -4
};
enum Direction {
NoTrace,
Horizontal,
Vertical
};
int width() const {return wid;} int width() const { return wid; }
int height() const {return hei;} int height() const { return hei; }
void resize(int width, int height); void resize(int width, int height);
void resize(const QSize & sz) {resize(sz.width(), sz.height());} void resize(const QSize & sz) { resize(sz.width(), sz.height()); }
void fill(short val = -1); void fill(short val = -1);
void fill(const QRect & rect, short val = -1); void fill(const QRect & rect, short val = -1);
void fill(const QPoint & point, short val = -1) {fill(point.x(), point.y(), val);} void fill(const QPoint & point, short val = -1) { fill(point.x(), point.y(), val); }
void fill(int px, int py, short val); void fill(int px, int py, short val);
void fill(BlockViewWavetrace::CellState val = Empty) {fill((short)val);} void fill(BlockViewWavetrace::CellState val = Empty) { fill((short)val); }
void fill(const QRect & rect, BlockViewWavetrace::CellState val = Empty) {fill(rect, (short)val);} void fill(const QRect & rect, BlockViewWavetrace::CellState val = Empty) { fill(rect, (short)val); }
void fill(const QPoint & point, BlockViewWavetrace::CellState val = Empty) {fill(point, (short)val);} void fill(const QPoint & point, BlockViewWavetrace::CellState val = Empty) { fill(point, (short)val); }
void fill(int px, int py, BlockViewWavetrace::CellState val = Empty) {fill(px, py, (short)val);} void fill(int px, int py, BlockViewWavetrace::CellState val = Empty) { fill(px, py, (short)val); }
void clear() {fill(-1);} void clear() { fill(-1); }
bool trace(const QPoint & start, const QPoint & finish); bool trace(const QPoint & start, const QPoint & finish);
Direction preferredDirection() const {return dir_;} Direction preferredDirection() const { return dir_; }
void setPreferredDirection(Direction dir); void setPreferredDirection(Direction dir);
void setMaximumSteps(int steps) {max_steps = steps;} void setMaximumSteps(int steps) { max_steps = steps; }
int maximumSteps() const {return max_steps;} int maximumSteps() const { return max_steps; }
void gatherPath(); void gatherPath();
const QVector<QPoint> & path() const; const QVector<QPoint> & path() const;
@@ -61,11 +70,10 @@ private:
int wid, hei, max_steps; int wid, hei, max_steps;
Direction dir_; Direction dir_;
QVector<QVector<Cell> > field; QVector<QVector<Cell>> field;
QVector<QPoint> path_; QVector<QPoint> path_;
QVector<QPoint> jumps; QVector<QPoint> jumps;
QPoint dps[4], st, fn; QPoint dps[4], st, fn;
}; };
#endif // BLOCKVIEWWAVETRACE_H #endif // BLOCKVIEWWAVETRACE_H
+185 -144
View File
@@ -1,23 +1,25 @@
#include "drawtools.h" #include "drawtools.h"
#include "ui_drawtools.h"
#include "alignedtextitem.h" #include "alignedtextitem.h"
#include <QGraphicsLineItem> #include "ui_drawtools.h"
#include <QLineEdit>
#include <QLabel>
#include <QMouseEvent>
#include <QFileDialog>
#include <QImageReader>
#include <QDialogButtonBox>
#include <QClipboard> #include <QClipboard>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QGraphicsLineItem>
#include <QImageReader>
#include <QLabel>
#include <QLineEdit>
#include <QMouseEvent>
_DTSizeItem::_DTSizeItem(): QGraphicsObject() { _DTSizeItem::_DTSizeItem(): QGraphicsObject() {
cur_item = nullptr; cur_item = nullptr;
grid = 10.; grid = 10.;
in_process = can_drag = false; in_process = can_drag = false;
setData(bvidItemSelection, true); setData(bvidItemSelection, true);
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
//qDebug() << &(rects[i]); // qDebug() << &(rects[i]);
rects[i].setData(bvidItemSelection, true); rects[i].setData(bvidItemSelection, true);
rects[i].setData(bvidDTHandle, true); rects[i].setData(bvidDTHandle, true);
rects[i].setFlag(QGraphicsItem::ItemIgnoresTransformations); rects[i].setFlag(QGraphicsItem::ItemIgnoresTransformations);
@@ -32,7 +34,7 @@ _DTSizeItem::_DTSizeItem(): QGraphicsObject() {
_DTSizeItem::~_DTSizeItem() { _DTSizeItem::~_DTSizeItem() {
assignObject(nullptr); assignObject(nullptr);
//qDebug() << "!!!"; // qDebug() << "!!!";
} }
@@ -52,15 +54,15 @@ void _DTSizeItem::assignObject(QGraphicsItem * item) {
} }
if (cur_item->scene()) { if (cur_item->scene()) {
if (!cur_item->scene()->views().isEmpty()) { if (!cur_item->scene()->views().isEmpty()) {
grid = qobject_cast<BlockView*>(cur_item->scene()->views()[0])->gridStep(); grid = qobject_cast<BlockView *>(cur_item->scene()->views()[0])->gridStep();
} }
} }
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item); QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
if (irect || iell || iline) { if (irect || iell || iline) {
resizeHandles(); resizeHandles();
is_line = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item); is_line = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
for (int i = 0; i < (is_line ? 2 : 8); ++i) { for (int i = 0; i < (is_line ? 2 : 8); ++i) {
rects[i].setParentItem(cur_item); rects[i].setParentItem(cur_item);
rects[i].installSceneEventFilter(this); rects[i].installSceneEventFilter(this);
@@ -78,26 +80,36 @@ void _DTSizeItem::moveRects() {
QRectF rect = itemRect(cur_item); QRectF rect = itemRect(cur_item);
QPointF tl = rect.topLeft(), tr = rect.topRight(), bl = rect.bottomLeft(), br = rect.bottomRight(); QPointF tl = rect.topLeft(), tr = rect.topRight(), bl = rect.bottomLeft(), br = rect.bottomRight();
if (is_line) { if (is_line) {
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeAllCursor)); rects[0].setPos(tl);
rects[1].setPos(br); rects[1].setData(2001, int(Qt::SizeAllCursor)); rects[0].setData(2001, int(Qt::SizeAllCursor));
rects[1].setPos(br);
rects[1].setData(2001, int(Qt::SizeAllCursor));
} else { } else {
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeFDiagCursor)); rects[0].setPos(tl);
rects[1].setPos((tl + tr) / 2.); rects[1].setData(2001, int(Qt::SizeVerCursor)); rects[0].setData(2001, int(Qt::SizeFDiagCursor));
rects[2].setPos(tr); rects[2].setData(2001, int(Qt::SizeBDiagCursor)); rects[1].setPos((tl + tr) / 2.);
rects[3].setPos((tr + br) / 2.); rects[3].setData(2001, int(Qt::SizeHorCursor)); rects[1].setData(2001, int(Qt::SizeVerCursor));
rects[4].setPos(br); rects[4].setData(2001, int(Qt::SizeFDiagCursor)); rects[2].setPos(tr);
rects[5].setPos((br + bl) / 2.); rects[5].setData(2001, int(Qt::SizeVerCursor)); rects[2].setData(2001, int(Qt::SizeBDiagCursor));
rects[6].setPos(bl); rects[6].setData(2001, int(Qt::SizeBDiagCursor)); rects[3].setPos((tr + br) / 2.);
rects[7].setPos((bl + tl) / 2.); rects[7].setData(2001, int(Qt::SizeHorCursor)); rects[3].setData(2001, int(Qt::SizeHorCursor));
rects[4].setPos(br);
rects[4].setData(2001, int(Qt::SizeFDiagCursor));
rects[5].setPos((br + bl) / 2.);
rects[5].setData(2001, int(Qt::SizeVerCursor));
rects[6].setPos(bl);
rects[6].setData(2001, int(Qt::SizeBDiagCursor));
rects[7].setPos((bl + tl) / 2.);
rects[7].setData(2001, int(Qt::SizeHorCursor));
} }
} }
void _DTSizeItem::applyRect() { void _DTSizeItem::applyRect() {
if (!cur_item) return; if (!cur_item) return;
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item); QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
if (irect) irect->setRect(nrect); if (irect) irect->setRect(nrect);
if (iell) iell->setRect(nrect); if (iell) iell->setRect(nrect);
if (iline) iline->setLine(QLineF(nrect.topLeft(), nrect.bottomRight())); if (iline) iline->setLine(QLineF(nrect.topLeft(), nrect.bottomRight()));
@@ -105,21 +117,27 @@ void _DTSizeItem::applyRect() {
void _DTSizeItem::doubleClick() { void _DTSizeItem::doubleClick() {
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem*>(cur_item); QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem*>(cur_item); AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem*>(cur_item); QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
if (itext || iatext) { if (itext || iatext) {
QMetaObject::invokeMethod(this, [this](){textEditRequest();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this]() { textEditRequest(); },
Qt::QueuedConnection);
} }
if (ipixmap) { if (ipixmap) {
QMetaObject::invokeMethod(this, [this](){pixmapEditRequest();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this]() { pixmapEditRequest(); },
Qt::QueuedConnection);
} }
} }
void _DTSizeItem::resizeHandles() { void _DTSizeItem::resizeHandles() {
double sz = fontHeight() / 3.; double sz = fontHeight() / 3.;
QRectF r(-sz, -sz, sz*2, sz*2); QRectF r(-sz, -sz, sz * 2, sz * 2);
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
rects[i].setRect(r); rects[i].setRect(r);
} }
@@ -128,9 +146,9 @@ void _DTSizeItem::resizeHandles() {
QRectF _DTSizeItem::itemRect(const QGraphicsItem *) const { QRectF _DTSizeItem::itemRect(const QGraphicsItem *) const {
if (!cur_item) return QRectF(); if (!cur_item) return QRectF();
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item); QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
if (irect) return irect->rect(); if (irect) return irect->rect();
if (iell) return iell->rect(); if (iell) return iell->rect();
if (iline) return QRectF(iline->line().p1(), iline->line().p2()); if (iline) return QRectF(iline->line().p1(), iline->line().p2());
@@ -148,7 +166,7 @@ QRectF _DTSizeItem::boundingRect() const {
bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) { bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent * )event; QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent *)event;
if (watched == cur_item) { if (watched == cur_item) {
if (event->type() == QEvent::Close) { if (event->type() == QEvent::Close) {
assignObject(nullptr); assignObject(nullptr);
@@ -166,11 +184,13 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
view_ = nullptr; view_ = nullptr;
switch (event->type()) { switch (event->type()) {
case QEvent::GraphicsSceneHoverEnter: case QEvent::GraphicsSceneHoverEnter:
if (watched->scene()) if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0]; if (watched->scene())
if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0];
if (view_) view_->setCursor(Qt::CursorShape(watched->data(2001).toInt())); if (view_) view_->setCursor(Qt::CursorShape(watched->data(2001).toInt()));
break; break;
case QEvent::GraphicsSceneHoverLeave: case QEvent::GraphicsSceneHoverLeave:
if (watched->scene()) if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0]; if (watched->scene())
if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0];
if (view_) view_->unsetCursor(); if (view_) view_->unsetCursor();
break; break;
case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMousePress:
@@ -181,7 +201,7 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
moveRects(); moveRects();
} }
in_process = false; in_process = false;
pp = quantize(me->scenePos(), grid); pp = quantize(me->scenePos(), grid);
cur_item->setData(2000, itemRect(cur_item)); cur_item->setData(2000, itemRect(cur_item));
return true; return true;
case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseMove:
@@ -189,7 +209,7 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
sp = quantize(me->scenePos(), grid); sp = quantize(me->scenePos(), grid);
if (pp != sp && can_drag) { if (pp != sp && can_drag) {
in_process = true; in_process = true;
nrect = itemRect(cur_item); nrect = itemRect(cur_item);
if (is_line) { if (is_line) {
if (watched == &(rects[0])) nrect.setTopLeft(rects[0].pos() + (sp - pp)); if (watched == &(rects[0])) nrect.setTopLeft(rects[0].pos() + (sp - pp));
if (watched == &(rects[1])) nrect.setBottomRight(rects[1].pos() + (sp - pp)); if (watched == &(rects[1])) nrect.setBottomRight(rects[1].pos() + (sp - pp));
@@ -213,7 +233,7 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseRelease:
if (in_process) emit sizeChanged(); if (in_process) emit sizeChanged();
in_process = false; in_process = false;
can_drag = false; can_drag = false;
return true; return true;
default: break; default: break;
} }
@@ -221,19 +241,21 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
} }
DrawTools::DrawTools(BlockView * parent)
: QWidget(parent)
DrawTools::DrawTools(BlockView * parent): QWidget(parent), , actions_Z_up(this)
actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(this) { , actions_Z_top(this)
, actions_Z_down(this)
, actions_Z_bottom(this) {
widget_props = new QWidget(); widget_props = new QWidget();
ui = new Ui::DrawTools(); ui = new Ui::DrawTools();
ui->setupUi(widget_props); ui->setupUi(widget_props);
ui->labelPen->setMinimumSize(preferredIconSize(1.5, widget_props)); ui->labelPen->setMinimumSize(preferredIconSize(1.5, widget_props));
ui->labelPen->setMaximumSize(ui->labelPen->minimumSize()); ui->labelPen->setMaximumSize(ui->labelPen->minimumSize());
ui->labelBrush->setMinimumSize(ui->labelPen->minimumSize()); ui->labelBrush->setMinimumSize(ui->labelPen->minimumSize());
ui->labelBrush->setMaximumSize(ui->labelBrush->minimumSize()); ui->labelBrush->setMaximumSize(ui->labelBrush->minimumSize());
widget_props->setEnabled(false); widget_props->setEnabled(false);
int fh = qMax<int>(fontHeight(this), 22); int fh = qMax<int>(fontHeight(this), 22);
int thick = lineThickness(this); int thick = lineThickness(this);
QSize sz(fh * 2.5, fh); QSize sz(fh * 2.5, fh);
ui->comboLineStyle->setIconSize(sz); ui->comboLineStyle->setIconSize(sz);
@@ -251,36 +273,37 @@ actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(
#else #else
setAlignCompact(false); setAlignCompact(false);
#endif #endif
menu_hor.addActions(QList<QAction*>() << ui->actionLeft << ui->actionHCenter << ui->actionRight); menu_hor.addActions(QList<QAction *>() << ui->actionLeft << ui->actionHCenter << ui->actionRight);
menu_ver.addActions(QList<QAction*>() << ui->actionTop << ui->actionVCenter << ui->actionBottom); menu_ver.addActions(QList<QAction *>() << ui->actionTop << ui->actionVCenter << ui->actionBottom);
ui->buttonAlignHor->setMenu(&menu_hor); ui->buttonAlignHor->setMenu(&menu_hor);
ui->buttonAlignVer->setMenu(&menu_ver); ui->buttonAlignVer->setMenu(&menu_ver);
new_type = -1; new_type = -1;
new_item = cur_item = nullptr; new_item = cur_item = nullptr;
view_ = nullptr; view_ = nullptr;
resize_enabled = true; resize_enabled = true;
text_dlg.setLayout(new QBoxLayout(QBoxLayout::TopToBottom)); text_dlg.setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
QDialogButtonBox * bbox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel); QDialogButtonBox * bbox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
connect(bbox, SIGNAL(accepted()), &text_dlg, SLOT(accept())); connect(bbox, SIGNAL(accepted()), &text_dlg, SLOT(accept()));
connect(bbox, SIGNAL(rejected()), &text_dlg, SLOT(reject())); connect(bbox, SIGNAL(rejected()), &text_dlg, SLOT(reject()));
text_dlg.layout()->addWidget(&text_edit); text_dlg.layout()->addWidget(&text_edit);
text_dlg.layout()->addWidget(bbox); text_dlg.layout()->addWidget(bbox);
actions_Z_up.setIcon(QIcon(":/icons/z-up.png")); actions_Z_up.setEnabled(false); actions_Z_up.setIcon(QIcon(":/icons/z-up.png"));
actions_Z_top.setIcon(QIcon(":/icons/z-top.png")); actions_Z_top.setEnabled(false); actions_Z_up.setEnabled(false);
actions_Z_down.setIcon(QIcon(":/icons/z-down.png")); actions_Z_down.setEnabled(false); actions_Z_top.setIcon(QIcon(":/icons/z-top.png"));
actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png")); actions_Z_bottom.setEnabled(false); actions_Z_top.setEnabled(false);
actions_add << newAction(QIcon(":/icons/draw-rectangle.png"), 1) actions_Z_down.setIcon(QIcon(":/icons/z-down.png"));
<< newAction(QIcon(":/icons/draw-ellipse.png"), 2) actions_Z_down.setEnabled(false);
<< newAction(QIcon(":/icons/draw-line.png"), 4) actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png"));
<< newAction(QIcon(":/icons/draw-text.png"), 0) actions_Z_bottom.setEnabled(false);
actions_add << newAction(QIcon(":/icons/draw-rectangle.png"), 1) << newAction(QIcon(":/icons/draw-ellipse.png"), 2)
<< newAction(QIcon(":/icons/draw-line.png"), 4) << newAction(QIcon(":/icons/draw-text.png"), 0)
<< newAction(QIcon(":/icons/view-preview.png"), 3); << newAction(QIcon(":/icons/view-preview.png"), 3);
buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR << ui->buttonAlignCL << ui->buttonAlignCC
<< ui->buttonAlignCL << ui->buttonAlignCC << ui->buttonAlignCR << ui->buttonAlignCR << ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR;
<< ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR; foreach(QAction * a, actions_add) {
foreach (QAction * a, actions_add) {
connect(a, SIGNAL(toggled(bool)), this, SLOT(toggleNewItem(bool))); connect(a, SIGNAL(toggled(bool)), this, SLOT(toggleNewItem(bool)));
} }
foreach (QToolButton * b, buttons_align) { foreach(QToolButton * b, buttons_align) {
connect(b, SIGNAL(clicked(bool)), this, SLOT(alignClicked())); connect(b, SIGNAL(clicked(bool)), this, SLOT(alignClicked()));
} }
connect(ui->buttonImage, SIGNAL(clicked(bool)), this, SLOT(buttonImage_clicked())); connect(ui->buttonImage, SIGNAL(clicked(bool)), this, SLOT(buttonImage_clicked()));
@@ -328,8 +351,7 @@ DrawTools::~DrawTools() {
void DrawTools::retranslate() { void DrawTools::retranslate() {
QStringList styles; QStringList styles;
styles << tr("NoPen") << tr("Solid") << tr("Dash") styles << tr("NoPen") << tr("Solid") << tr("Dash") << tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
for (int i = 0; i < styles.size(); i++) { for (int i = 0; i < styles.size(); i++) {
ui->comboLineStyle->setItemText(i, styles[i]); ui->comboLineStyle->setItemText(i, styles[i]);
} }
@@ -380,7 +402,7 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
delete new_item; delete new_item;
new_item = nullptr; new_item = nullptr;
if (!me->modifiers().testFlag(Qt::ControlModifier)) { if (!me->modifiers().testFlag(Qt::ControlModifier)) {
foreach (QAction * a, actions_add) { foreach(QAction * a, actions_add) {
a->setChecked(false); a->setChecked(false);
} }
new_type = -1; new_type = -1;
@@ -388,26 +410,21 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
} }
} }
new_item = nullptr; new_item = nullptr;
pp = sp; pp = sp;
switch (new_type) { switch (new_type) {
case 0: case 0:
new_item = new AlignedTextItem(); new_item = new AlignedTextItem();
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setText("Text"); qgraphicsitem_cast<AlignedTextItem *>(new_item)->setText("Text");
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp);
break; break;
case 1: case 1: new_item = new QGraphicsRectItem(); break;
new_item = new QGraphicsRectItem(); case 2: new_item = new QGraphicsEllipseItem(); break;
break;
case 2:
new_item = new QGraphicsEllipseItem();
break;
case 3: case 3:
new_item = new QGraphicsPixmapItem(QPixmap(":/icons/view-preview.png")); new_item = new QGraphicsPixmapItem(QPixmap(":/icons/view-preview.png"));
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2)); qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(
break; sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
case 4:
new_item = new QGraphicsLineItem(QLineF(sp, sp));
break; break;
case 4: new_item = new QGraphicsLineItem(QLineF(sp, sp)); break;
}; };
if (new_item) { if (new_item) {
if (new_type == 1 || new_type == 2) { if (new_type == 1 || new_type == 2) {
@@ -424,21 +441,14 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
if (new_item) { if (new_item) {
mr = new_item->mapRectFromScene(QRectF(pp, sp).normalized()); mr = new_item->mapRectFromScene(QRectF(pp, sp).normalized());
switch (new_type) { switch (new_type) {
case 0: case 0: qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); break;
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); case 1: qgraphicsitem_cast<QGraphicsRectItem *>(new_item)->setRect(mr); break;
break; case 2: qgraphicsitem_cast<QGraphicsEllipseItem *>(new_item)->setRect(mr); break;
case 1:
qgraphicsitem_cast<QGraphicsRectItem *>(new_item)->setRect(mr);
break;
case 2:
qgraphicsitem_cast<QGraphicsEllipseItem *>(new_item)->setRect(mr);
break;
case 3: case 3:
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2)); qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(
break; sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
case 4:
qgraphicsitem_cast<QGraphicsLineItem *>(new_item)->setLine(QLineF(pp, sp));
break; break;
case 4: qgraphicsitem_cast<QGraphicsLineItem *>(new_item)->setLine(QLineF(pp, sp)); break;
}; };
return true; return true;
} }
@@ -457,7 +467,7 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
} }
new_item = nullptr; new_item = nullptr;
if (!me->modifiers().testFlag(Qt::ControlModifier)) { if (!me->modifiers().testFlag(Qt::ControlModifier)) {
foreach (QAction * a, actions_add) { foreach(QAction * a, actions_add) {
a->setChecked(false); a->setChecked(false);
} }
new_type = -1; new_type = -1;
@@ -497,8 +507,8 @@ QAction * DrawTools::newAction(const QIcon & icon, int type) {
void DrawTools::toggleNewItem(bool on) { void DrawTools::toggleNewItem(bool on) {
QAction * sa = (QAction * )sender(); QAction * sa = (QAction *)sender();
foreach (QAction * a, actions_add) { foreach(QAction * a, actions_add) {
if (a != sa) a->setChecked(false); if (a != sa) a->setChecked(false);
} }
if (!on) { if (!on) {
@@ -512,12 +522,12 @@ void DrawTools::toggleNewItem(bool on) {
void DrawTools::alignClicked() { void DrawTools::alignClicked() {
QToolButton * sb = (QToolButton * )sender(); QToolButton * sb = (QToolButton *)sender();
foreach (QToolButton * b, buttons_align) { foreach(QToolButton * b, buttons_align) {
if (b != sb) b->setChecked(false); if (b != sb) b->setChecked(false);
} }
sb->setChecked(true); sb->setChecked(true);
align = Qt::Alignment(); align = Qt::Alignment();
QString als = sb->objectName().right(2).toLower(); QString als = sb->objectName().right(2).toLower();
if (als[0] == 't') align |= Qt::AlignTop; if (als[0] == 't') align |= Qt::AlignTop;
if (als[0] == 'c') align |= Qt::AlignVCenter; if (als[0] == 'c') align |= Qt::AlignVCenter;
@@ -563,7 +573,7 @@ void DrawTools::blockPropSignals(bool block_) {
ui->actionHCenter->blockSignals(block_); ui->actionHCenter->blockSignals(block_);
ui->actionLeft->blockSignals(block_); ui->actionLeft->blockSignals(block_);
ui->actionRight->blockSignals(block_); ui->actionRight->blockSignals(block_);
foreach (QToolButton * b, buttons_align) { foreach(QToolButton * b, buttons_align) {
b->blockSignals(block_); b->blockSignals(block_);
} }
} }
@@ -571,8 +581,12 @@ void DrawTools::blockPropSignals(bool block_) {
void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) { void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
blockPropSignals(true); blockPropSignals(true);
if (vert) foreach (QAction * a, menu_ver.actions()) a->setChecked(false); if (vert)
else foreach (QAction * a, menu_hor.actions()) a->setChecked(false); foreach(QAction * a, menu_ver.actions())
a->setChecked(false);
else
foreach(QAction * a, menu_hor.actions())
a->setChecked(false);
align = align & (vert ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask); align = align & (vert ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask);
align |= value; align |= value;
qobject_cast<QAction *>(sender())->setChecked(true); qobject_cast<QAction *>(sender())->setChecked(true);
@@ -583,7 +597,9 @@ void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
void DrawTools::emitZAvailabe(QGraphicsItem * item) { void DrawTools::emitZAvailabe(QGraphicsItem * item) {
BlockView * view = nullptr; BlockView * view = nullptr;
if (item) if (item->scene()) if (!item->scene()->views().isEmpty()) view = qobject_cast<BlockView *>(item->scene()->views()[0]); if (item)
if (item->scene())
if (!item->scene()->views().isEmpty()) view = qobject_cast<BlockView *>(item->scene()->views()[0]);
if (!view) { if (!view) {
moveZUpAvailable(false); moveZUpAvailable(false);
moveZDownAvailable(false); moveZDownAvailable(false);
@@ -633,11 +649,11 @@ void DrawTools::selectionChanged() {
return; return;
} }
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item); QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item); AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item); QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item); QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
blockPropSignals(true); blockPropSignals(true);
if (itext) { if (itext) {
ui->stackedProperties->setCurrentIndex(0); ui->stackedProperties->setCurrentIndex(0);
@@ -658,20 +674,40 @@ void DrawTools::selectionChanged() {
font_dlg.setCurrentFont(iatext->font()); font_dlg.setCurrentFont(iatext->font());
font_dlg.blockSignals(false); font_dlg.blockSignals(false);
setToolButtonsEnabled(true, false, false); setToolButtonsEnabled(true, false, false);
foreach (QAction * a, menu_hor.actions()) a->setChecked(false); foreach(QAction * a, menu_hor.actions())
foreach (QAction * a, menu_ver.actions()) a->setChecked(false); a->setChecked(false);
foreach(QAction * a, menu_ver.actions())
a->setChecked(false);
align = iatext->alignment(); align = iatext->alignment();
QString als; QString als;
if (align.testFlag(Qt::AlignTop)) {als += "T"; ui->actionTop->setChecked(true);} if (align.testFlag(Qt::AlignTop)) {
if (align.testFlag(Qt::AlignVCenter)) {als += "C"; ui->actionVCenter->setChecked(true);} als += "T";
if (align.testFlag(Qt::AlignBottom)) {als += "B"; ui->actionBottom->setChecked(true);} ui->actionTop->setChecked(true);
if (align.testFlag(Qt::AlignLeft)) {als += "L"; ui->actionLeft->setChecked(true);} }
if (align.testFlag(Qt::AlignHCenter)) {als += "C"; ui->actionHCenter->setChecked(true);} if (align.testFlag(Qt::AlignVCenter)) {
if (align.testFlag(Qt::AlignRight)) {als += "R"; ui->actionRight->setChecked(true);} als += "C";
foreach (QToolButton * b, buttons_align) { ui->actionVCenter->setChecked(true);
}
if (align.testFlag(Qt::AlignBottom)) {
als += "B";
ui->actionBottom->setChecked(true);
}
if (align.testFlag(Qt::AlignLeft)) {
als += "L";
ui->actionLeft->setChecked(true);
}
if (align.testFlag(Qt::AlignHCenter)) {
als += "C";
ui->actionHCenter->setChecked(true);
}
if (align.testFlag(Qt::AlignRight)) {
als += "R";
ui->actionRight->setChecked(true);
}
foreach(QToolButton * b, buttons_align) {
b->setChecked(false); b->setChecked(false);
} }
foreach (QToolButton * b, buttons_align) { foreach(QToolButton * b, buttons_align) {
if (b->objectName().endsWith(als)) { if (b->objectName().endsWith(als)) {
b->setChecked(true); b->setChecked(true);
break; break;
@@ -724,7 +760,7 @@ void DrawTools::selectionChanged() {
void DrawTools::sizeChanged() { void DrawTools::sizeChanged() {
blockPropSignals(true); blockPropSignals(true);
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
if (irect || iell) { if (irect || iell) {
if (irect) { if (irect) {
@@ -744,17 +780,17 @@ void DrawTools::sizeChanged() {
void DrawTools::propertyChanged() { void DrawTools::propertyChanged() {
if (!cur_item) return; if (!cur_item) return;
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item); QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item); AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item); QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item); QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
if (itext) { if (itext) {
QRectF obr = itext->boundingRect(); QRectF obr = itext->boundingRect();
itext->setFont(font_dlg.currentFont()); itext->setFont(font_dlg.currentFont());
itext->setText(ui->comboText->currentText()); itext->setText(ui->comboText->currentText());
QRectF nbr = itext->boundingRect(); QRectF nbr = itext->boundingRect();
QSizeF ds = (obr.size() - nbr.size()) / 2.; QSizeF ds = (obr.size() - nbr.size()) / 2.;
itext->setPos(itext->pos() + QPointF(ds.width(), ds.height())); itext->setPos(itext->pos() + QPointF(ds.width(), ds.height()));
itext->setBrush(ui->colorButtonPen->color()); itext->setBrush(ui->colorButtonPen->color());
} else if (iatext) { } else if (iatext) {
@@ -764,8 +800,8 @@ void DrawTools::propertyChanged() {
iatext->setAlignment(align); iatext->setAlignment(align);
} else if (ipixmap) { } else if (ipixmap) {
QTransform t = ipixmap->transform(); QTransform t = ipixmap->transform();
double det = sqrt(t.determinant()); double det = sqrt(t.determinant());
QSizeF os = ipixmap->boundingRect().size() * det; QSizeF os = ipixmap->boundingRect().size() * det;
if (det != 0.) t.scale(1. / det, 1. / det); if (det != 0.) t.scale(1. / det, 1. / det);
det = ui->spinScale->value(); det = ui->spinScale->value();
t.scale(det, det); t.scale(det, det);
@@ -797,9 +833,9 @@ void DrawTools::propertyChanged() {
void DrawTools::comboLineStyleChanged() { void DrawTools::comboLineStyleChanged() {
if (!cur_item) return; if (!cur_item) return;
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item); QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item); QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item); QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
if (irect || iell) { if (irect || iell) {
QAbstractGraphicsShapeItem * ishape = nullptr; QAbstractGraphicsShapeItem * ishape = nullptr;
if (irect) ishape = irect; if (irect) ishape = irect;
@@ -824,7 +860,7 @@ void DrawTools::buttonImage_clicked() {
if (!pi) return; if (!pi) return;
QList<QByteArray> sif(QImageReader::supportedImageFormats()); QList<QByteArray> sif(QImageReader::supportedImageFormats());
QString f; QString f;
foreach (const QByteArray & i, sif) { foreach(const QByteArray & i, sif) {
if (!f.isEmpty()) f += " "; if (!f.isEmpty()) f += " ";
f += "*."; f += "*.";
f += i; f += i;
@@ -833,11 +869,11 @@ void DrawTools::buttonImage_clicked() {
if (ret.isEmpty()) return; if (ret.isEmpty()) return;
QImage im(ret); QImage im(ret);
if (im.isNull()) return; if (im.isNull()) return;
prev_dir = ret; prev_dir = ret;
QRectF obr = pi->boundingRect(); QRectF obr = pi->boundingRect();
pi->setPixmap(QPixmap::fromImage(im)); pi->setPixmap(QPixmap::fromImage(im));
QRectF nbr = pi->boundingRect(); QRectF nbr = pi->boundingRect();
QSizeF ds = (obr.size() - nbr.size()) / 2.; QSizeF ds = (obr.size() - nbr.size()) / 2.;
pi->setPos(pi->pos() + QPointF(ds.width(), ds.height())); pi->setPos(pi->pos() + QPointF(ds.width(), ds.height()));
changeFinished(); changeFinished();
} }
@@ -851,7 +887,7 @@ void DrawTools::buttonImagePaste_clicked() {
QRectF obr = pi->boundingRect(); QRectF obr = pi->boundingRect();
pi->setPixmap(pm); pi->setPixmap(pm);
QRectF nbr = pi->boundingRect(); QRectF nbr = pi->boundingRect();
QSizeF ds = (obr.size() - nbr.size()) / 2.; QSizeF ds = (obr.size() - nbr.size()) / 2.;
pi->setPos(pi->pos() + QPointF(ds.width(), ds.height())); pi->setPos(pi->pos() + QPointF(ds.width(), ds.height()));
changeFinished(); changeFinished();
} }
@@ -860,7 +896,7 @@ void DrawTools::buttonImagePaste_clicked() {
void DrawTools::buttonFont_clicked() { void DrawTools::buttonFont_clicked() {
if (!cur_item) return; if (!cur_item) return;
QGraphicsSimpleTextItem * ti = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item); QGraphicsSimpleTextItem * ti = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
AlignedTextItem * ati = qgraphicsitem_cast<AlignedTextItem *>(cur_item); AlignedTextItem * ati = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
if (!ti && !ati) return; if (!ti && !ati) return;
QFont font_prev; QFont font_prev;
if (ti) font_prev = ti->font(); if (ti) font_prev = ti->font();
@@ -892,28 +928,32 @@ void DrawTools::actionZ_triggered() {
if (!cur_item) return; if (!cur_item) return;
if (cur_item->data(bvidType).toInt() == bvitDecor) { if (cur_item->data(bvidType).toInt() == bvitDecor) {
BlockView * view = nullptr; BlockView * view = nullptr;
if (cur_item->scene()) if (!cur_item->scene()->views().isEmpty()) { if (cur_item->scene())
view = qobject_cast<BlockView *>(cur_item->scene()->views()[0]); if (!cur_item->scene()->views().isEmpty()) {
} view = qobject_cast<BlockView *>(cur_item->scene()->views()[0]);
}
if (!view) return; if (!view) return;
QGraphicsScene * scene = view->scene(); QGraphicsScene * scene = view->scene();
QList<QGraphicsItem *> dl = view->decors(); QList<QGraphicsItem *> dl = view->decors();
scene->blockSignals(true); scene->blockSignals(true);
foreach (QGraphicsItem * d, dl) scene->removeItem(d); foreach(QGraphicsItem * d, dl)
scene->removeItem(d);
int ind = dl.indexOf(cur_item); int ind = dl.indexOf(cur_item);
dl.removeAt(ind); dl.removeAt(ind);
if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item); if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item);
if (sender() == &actions_Z_top) dl.append(cur_item); if (sender() == &actions_Z_top) dl.append(cur_item);
if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item); if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item);
if (sender() == &actions_Z_bottom) dl.prepend(cur_item); if (sender() == &actions_Z_bottom) dl.prepend(cur_item);
foreach (QGraphicsItem * d, dl) scene->addItem(d); foreach(QGraphicsItem * d, dl)
scene->addItem(d);
scene->blockSignals(false); scene->blockSignals(false);
} }
if (cur_item->data(bvidBlockDecor).toBool()) { if (cur_item->data(bvidBlockDecor).toBool()) {
BlockItem * bi = qgraphicsitem_cast<BlockItem *>(cur_item->parentItem()); BlockItem * bi = qgraphicsitem_cast<BlockItem *>(cur_item->parentItem());
if (!bi) return; if (!bi) return;
QList<QGraphicsItem *> dl = bi->decors_; QList<QGraphicsItem *> dl = bi->decors_;
foreach (QGraphicsItem * d, dl) d->setParentItem(nullptr); foreach(QGraphicsItem * d, dl)
d->setParentItem(nullptr);
int ind = dl.indexOf(cur_item); int ind = dl.indexOf(cur_item);
dl.removeAt(ind); dl.removeAt(ind);
if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item); if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item);
@@ -921,7 +961,8 @@ void DrawTools::actionZ_triggered() {
if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item); if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item);
if (sender() == &actions_Z_bottom) dl.prepend(cur_item); if (sender() == &actions_Z_bottom) dl.prepend(cur_item);
bi->decors_ = dl; bi->decors_ = dl;
foreach (QGraphicsItem * d, dl) d->setParentItem(bi); foreach(QGraphicsItem * d, dl)
d->setParentItem(bi);
} }
size_item.assignObject(cur_item); size_item.assignObject(cur_item);
emitZAvailabe(cur_item); emitZAvailabe(cur_item);
+51 -41
View File
@@ -1,41 +1,42 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef DRAWTOOLS_H #ifndef DRAWTOOLS_H
#define DRAWTOOLS_H #define DRAWTOOLS_H
#include <QObject>
#include <QAction>
#include <QFontDialog>
#include <QToolButton>
#include <QPlainTextEdit>
#include <QMenu>
#include "blockview.h" #include "blockview.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QAction>
#include <QFontDialog>
#include <QMenu>
#include <QObject>
#include <QPlainTextEdit>
#include <QToolButton>
class QComboBox; class QComboBox;
class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject {
{
Q_OBJECT Q_OBJECT
public: public:
_DTSizeItem(); _DTSizeItem();
~_DTSizeItem(); ~_DTSizeItem();
@@ -64,32 +65,33 @@ signals:
void sizeChanged(); void sizeChanged();
void textEditRequest(); void textEditRequest();
void pixmapEditRequest(); void pixmapEditRequest();
}; };
namespace Ui { namespace Ui {
class DrawTools; class DrawTools;
} }
class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool resizeHandlesEnabled READ isResizeHandlesEnabled WRITE setResizeHandlesEnabled) Q_PROPERTY(bool resizeHandlesEnabled READ isResizeHandlesEnabled WRITE setResizeHandlesEnabled)
public: public:
explicit DrawTools(BlockView * parent = 0); explicit DrawTools(BlockView * parent = 0);
~DrawTools(); ~DrawTools();
void setBlockView(BlockView * v); void setBlockView(BlockView * v);
void resetSizeTool() {size_item.assignObject(0);} void resetSizeTool() { size_item.assignObject(0); }
bool isResizeHandlesEnabled() const {return resize_enabled;} bool isResizeHandlesEnabled() const { return resize_enabled; }
void setAlignCompact(bool yes); void setAlignCompact(bool yes);
QComboBox * textEditCombo() const; QComboBox * textEditCombo() const;
QList<QAction * > actionsForAdd() const {return actions_add;} QList<QAction *> actionsForAdd() const { return actions_add; }
QList<QAction * > actionsForZ() const {return QList<QAction * >() << &actions_Z_bottom << &actions_Z_down << &actions_Z_up << &actions_Z_top;} QList<QAction *> actionsForZ() const {
QWidget * propertyWidget() const {return widget_props;} return QList<QAction *>() << &actions_Z_bottom << &actions_Z_down << &actions_Z_up << &actions_Z_top;
}
QWidget * propertyWidget() const { return widget_props; }
protected: protected:
bool eventFilter(QObject * o, QEvent * e); bool eventFilter(QObject * o, QEvent * e);
@@ -104,10 +106,10 @@ protected:
QWidget * widget_props; QWidget * widget_props;
Ui::DrawTools * ui; Ui::DrawTools * ui;
BlockView * view_; BlockView * view_;
QList<QAction * > actions_add; QList<QAction *> actions_add;
mutable QAction actions_Z_up, actions_Z_top, actions_Z_down, actions_Z_bottom; mutable QAction actions_Z_up, actions_Z_top, actions_Z_down, actions_Z_bottom;
QList<QToolButton * > buttons_align; QList<QToolButton *> buttons_align;
QGraphicsItem * new_item, * cur_item; QGraphicsItem *new_item, *cur_item;
QFontDialog font_dlg; QFontDialog font_dlg;
QPointF pp; QPointF pp;
QDialog text_dlg; QDialog text_dlg;
@@ -126,21 +128,29 @@ private slots:
void sizeChanged(); void sizeChanged();
void propertyChanged(); void propertyChanged();
void comboLineStyleChanged(); void comboLineStyleChanged();
void changeFinished() {if (cur_item) emit itemEdited(cur_item);} void changeFinished() {
void moveZUpAvailable(bool yes) {actions_Z_up.setEnabled(yes); actions_Z_top.setEnabled(yes);} if (cur_item) emit itemEdited(cur_item);
void moveZDownAvailable(bool yes) {actions_Z_down.setEnabled(yes); actions_Z_bottom.setEnabled(yes);} }
void moveZUpAvailable(bool yes) {
actions_Z_up.setEnabled(yes);
actions_Z_top.setEnabled(yes);
}
void moveZDownAvailable(bool yes) {
actions_Z_down.setEnabled(yes);
actions_Z_bottom.setEnabled(yes);
}
void buttonImage_clicked(); void buttonImage_clicked();
void buttonImagePaste_clicked(); void buttonImagePaste_clicked();
void buttonFont_clicked(); void buttonFont_clicked();
void buttonTextEdit_clicked(); void buttonTextEdit_clicked();
void actionTop_triggered(bool on) {actionAlignTrigger(true, Qt::AlignTop);} void actionTop_triggered(bool on) { actionAlignTrigger(true, Qt::AlignTop); }
void actionVCenter_triggered(bool on) {actionAlignTrigger(true, Qt::AlignVCenter);} void actionVCenter_triggered(bool on) { actionAlignTrigger(true, Qt::AlignVCenter); }
void actionBottom_triggered(bool on) {actionAlignTrigger(true, Qt::AlignBottom);} void actionBottom_triggered(bool on) { actionAlignTrigger(true, Qt::AlignBottom); }
void actionLeft_triggered(bool on) {actionAlignTrigger(false, Qt::AlignLeft);} void actionLeft_triggered(bool on) { actionAlignTrigger(false, Qt::AlignLeft); }
void actionHCenter_triggered(bool on) {actionAlignTrigger(false, Qt::AlignHCenter);} void actionHCenter_triggered(bool on) { actionAlignTrigger(false, Qt::AlignHCenter); }
void actionRight_triggered(bool on) {actionAlignTrigger(false, Qt::AlignRight);} void actionRight_triggered(bool on) { actionAlignTrigger(false, Qt::AlignRight); }
void actionZ_triggered(); void actionZ_triggered();
public slots: public slots:
+4 -4
View File
@@ -1,5 +1,7 @@
#include "blockview.h"
#include "blockviewplugin.h" #include "blockviewplugin.h"
#include "blockview.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ BlockViewPlugin::BlockViewPlugin(QObject * parent): QObject(parent) {
void BlockViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void BlockViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString BlockViewPlugin::domXml() const {
QString BlockViewPlugin::includeFile() const { QString BlockViewPlugin::includeFile() const {
return QLatin1String("blockview.h"); return QLatin1String("blockview.h");
} }
+3 -3
View File
@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class BlockViewPlugin: public QObject, public QDesignerCustomWidgetInterface class BlockViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif // BLOCKVIEWPLUGIN_H #endif // BLOCKVIEWPLUGIN_H
+3 -3
View File
@@ -1,13 +1,13 @@
#include "qad_blockview.h" #include "qad_blockview.h"
#include "blockviewplugin.h" #include "blockviewplugin.h"
QADBlockView::QADBlockView(QObject * parent): QObject(parent) QADBlockView::QADBlockView(QObject * parent): QObject(parent) {
{
m_widgets.append(new BlockViewPlugin(this)); m_widgets.append(new BlockViewPlugin(this));
} }
QList<QDesignerCustomWidgetInterface * > QADBlockView::customWidgets() const { QList<QDesignerCustomWidgetInterface *> QADBlockView::customWidgets() const {
return m_widgets; return m_widgets;
} }
+7 -6
View File
@@ -1,23 +1,24 @@
#ifndef QAD_BLOCKVIEW_H #ifndef QAD_BLOCKVIEW_H
#define QAD_BLOCKVIEW_H #define QAD_BLOCKVIEW_H
#include <QtDesigner/QtDesigner>
#include <QtCore/qplugin.h> #include <QtCore/qplugin.h>
#include <QtDesigner/QtDesigner>
class QADBlockView: public QObject, public QDesignerCustomWidgetCollectionInterface class QADBlockView
{ : public QObject
, public QDesignerCustomWidgetCollectionInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "qad.blockview") Q_PLUGIN_METADATA(IID "qad.blockview")
#endif #endif
public: public:
explicit QADBlockView(QObject * parent = 0); explicit QADBlockView(QObject * parent = 0);
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const; virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
private: private:
QList<QDesignerCustomWidgetInterface * > m_widgets; QList<QDesignerCustomWidgetInterface *> m_widgets;
}; };
#endif // QAD_BLOCKVIEW_H #endif // QAD_BLOCKVIEW_H
+42 -42
View File
@@ -1,36 +1,36 @@
#include "markdown.h" #include "markdown.h"
#include <QIODevice>
#include <QDebug> #include <QDebug>
#include <QIODevice>
#ifndef NO_MARKDOWN #ifndef NO_MARKDOWN
extern "C" { extern "C" {
#include MARKDOWN_HEADER # include MARKDOWN_HEADER
} }
#ifndef mkd_flags_are # ifndef mkd_flags_are
# ifndef MKD_DLEXTRA # ifndef MKD_DLEXTRA
# define MKD_DLEXTRA 0x01000000 # define MKD_DLEXTRA 0x01000000
# endif
# ifndef MKD_FENCEDCODE
# define MKD_FENCEDCODE 0x02000000
# endif
# ifndef MKD_EXTRA_FOOTNOTE
# define MKD_EXTRA_FOOTNOTE 0x00200000
# endif
# ifndef MKD_TOC
# define MKD_TOC 0x00001000
# endif
# ifndef MKD_AUTOLINK
# define MKD_AUTOLINK 0x00004000
# endif
# ifndef MKD_GITHUBTAGS
# define MKD_GITHUBTAGS 0x08000000
# endif
# endif # endif
# ifndef MKD_FENCEDCODE
# define MKD_FENCEDCODE 0x02000000
# endif
# ifndef MKD_EXTRA_FOOTNOTE
# define MKD_EXTRA_FOOTNOTE 0x00200000
# endif
# ifndef MKD_TOC
# define MKD_TOC 0x00001000
# endif
# ifndef MKD_AUTOLINK
# define MKD_AUTOLINK 0x00004000
# endif
# ifndef MKD_GITHUBTAGS
# define MKD_GITHUBTAGS 0x08000000
# endif
#endif
static QString markdown_css = "table { margin: 5px; background-color: #cccccc; }" static QString markdown_css = "table { margin: 5px; background-color: #cccccc; }"
"table tr { background-color: white; }" "table tr { background-color: white; }"
"table td { vertical-align: middle; padding: 5px;}" "table td { vertical-align: middle; padding: 5px;}"
"table th { padding: 5px; };" "table th { padding: 5px; };";
;
QString md2html(const QByteArray & src) { QString md2html(const QByteArray & src) {
static bool _is_mkd_init = false; static bool _is_mkd_init = false;
@@ -39,34 +39,34 @@ QString md2html(const QByteArray & src) {
_is_mkd_init = true; _is_mkd_init = true;
mkd_initialize(); mkd_initialize();
} }
#ifdef _MARKDOWN_D # ifdef _MARKDOWN_D
DWORD flagm = (MKD_DLEXTRA | MKD_FENCEDCODE); DWORD flagm = (MKD_DLEXTRA | MKD_FENCEDCODE);
Document Document
#endif # endif
#ifdef _MKDIO_D # ifdef _MKDIO_D
#ifdef mkd_flags_are # ifdef mkd_flags_are
mkd_flag_t * flagm = mkd_flags(); mkd_flag_t * flagm = mkd_flags();
mkd_set_flag_num(flagm, MKD_DLEXTRA); mkd_set_flag_num(flagm, MKD_DLEXTRA);
mkd_set_flag_num(flagm, MKD_FENCEDCODE); mkd_set_flag_num(flagm, MKD_FENCEDCODE);
#else # else
mkd_flag_t flagm = (MKD_DLEXTRA | MKD_FENCEDCODE | MKD_GITHUBTAGS | MKD_AUTOLINK); mkd_flag_t flagm = (MKD_DLEXTRA | MKD_FENCEDCODE | MKD_GITHUBTAGS | MKD_AUTOLINK);
#endif # endif
MMIOT MMIOT
#endif # endif
* doc = mkd_string(src.constData(), src.size(), 0); *doc = mkd_string(src.constData(), src.size(), 0);
if (!doc) return QString(); if (!doc) return QString();
mkd_compile(doc, flagm); mkd_compile(doc, flagm);
char * html = 0; char * html = 0;
int len = mkd_document(doc, &html); int len = mkd_document(doc, &html);
if (!html) { if (!html) {
mkd_cleanup(doc); mkd_cleanup(doc);
return QString(); return QString();
} }
QString ret = QString::fromUtf8(html, len); QString ret = QString::fromUtf8(html, len);
mkd_cleanup(doc); mkd_cleanup(doc);
QString title = QTextStream(&ret, QIODevice::ReadOnly).readLine(); QString title = QTextStream(&ret, QIODevice::ReadOnly).readLine();
title = title.mid(title.indexOf(">")+1); title = title.mid(title.indexOf(">") + 1);
title = title.left(title.indexOf("<")); title = title.left(title.indexOf("<"));
QString header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" QString header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html>\n<head>\n" "<html>\n<head>\n"
"<meta name=\"qrichtext\" content=\"1\" />\n" "<meta name=\"qrichtext\" content=\"1\" />\n"
+14 -13
View File
@@ -1,28 +1,29 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef QAD_MARKDOWN_H #ifndef QAD_MARKDOWN_H
#define QAD_MARKDOWN_H #define QAD_MARKDOWN_H
#include <QString>
#include "qad_doc_export.h" #include "qad_doc_export.h"
#include <QString>
QAD_DOC_EXPORT QString md2html(const QByteArray & src); QAD_DOC_EXPORT QString md2html(const QByteArray & src);
+572 -593
View File
@@ -29,10 +29,10 @@
#ifndef gif_h #ifndef gif_h
#define gif_h #define gif_h
#include <stdbool.h> // for bool macros
#include <stdint.h> // for integer typedefs
#include <stdio.h> // for FILE* #include <stdio.h> // for FILE*
#include <string.h> // for memcpy and bzero #include <string.h> // for memcpy and bzero
#include <stdint.h> // for integer typedefs
#include <stdbool.h> // for bool macros
// Define these macros to hook into a custom memory allocator. // Define these macros to hook into a custom memory allocator.
// TEMP_MALLOC and TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs // TEMP_MALLOC and TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs
@@ -41,796 +41,775 @@
// is used to find changed pixels for delta-encoding.) // is used to find changed pixels for delta-encoding.)
#ifndef GIF_TEMP_MALLOC #ifndef GIF_TEMP_MALLOC
#include <stdlib.h> # include <stdlib.h>
#define GIF_TEMP_MALLOC malloc # define GIF_TEMP_MALLOC malloc
#endif #endif
#ifndef GIF_TEMP_FREE #ifndef GIF_TEMP_FREE
#include <stdlib.h> # include <stdlib.h>
#define GIF_TEMP_FREE free # define GIF_TEMP_FREE free
#endif #endif
#ifndef GIF_MALLOC #ifndef GIF_MALLOC
#include <stdlib.h> # include <stdlib.h>
#define GIF_MALLOC malloc # define GIF_MALLOC malloc
#endif #endif
#ifndef GIF_FREE #ifndef GIF_FREE
#include <stdlib.h> # include <stdlib.h>
#define GIF_FREE free # define GIF_FREE free
#endif #endif
const int kGifTransIndex = 0; const int kGifTransIndex = 0;
typedef struct typedef struct {
{ int bitDepth;
int bitDepth;
uint8_t r[256]; uint8_t r[256];
uint8_t g[256]; uint8_t g[256];
uint8_t b[256]; uint8_t b[256];
// k-d tree over RGB space, organized in heap fashion // k-d tree over RGB space, organized in heap fashion
// i.e. left child of node i is node i*2, right child is node i*2+1 // i.e. left child of node i is node i*2, right child is node i*2+1
// nodes 256-511 are implicitly the leaves, containing a color // nodes 256-511 are implicitly the leaves, containing a color
uint8_t treeSplitElt[256]; uint8_t treeSplitElt[256];
uint8_t treeSplit[256]; uint8_t treeSplit[256];
} GifPalette; } GifPalette;
// max, min, and abs functions // max, min, and abs functions
int GifIMax(int l, int r) { return l>r?l:r; } int GifIMax(int l, int r) {
int GifIMin(int l, int r) { return l<r?l:r; } return l > r ? l : r;
int GifIAbs(int i) { return i<0?-i:i; } }
int GifIMin(int l, int r) {
return l < r ? l : r;
}
int GifIAbs(int i) {
return i < 0 ? -i : i;
}
// walks the k-d tree to pick the palette entry for a desired color. // walks the k-d tree to pick the palette entry for a desired color.
// Takes as in/out parameters the current best color and its error - // Takes as in/out parameters the current best color and its error -
// only changes them if it finds a better color in its subtree. // only changes them if it finds a better color in its subtree.
// this is the major hotspot in the code at the moment. // this is the major hotspot in the code at the moment.
void GifGetClosestPaletteColor( GifPalette* pPal, int r, int g, int b, int* bestInd, int* bestDiff, int treeRoot ) void GifGetClosestPaletteColor(GifPalette * pPal, int r, int g, int b, int * bestInd, int * bestDiff, int treeRoot) {
{ // base case, reached the bottom of the tree
// base case, reached the bottom of the tree if (treeRoot > (1 << pPal->bitDepth) - 1) {
if(treeRoot > (1<<pPal->bitDepth)-1) int ind = treeRoot - (1 << pPal->bitDepth);
{ if (ind == kGifTransIndex) return;
int ind = treeRoot-(1<<pPal->bitDepth);
if(ind == kGifTransIndex) return;
// check whether this color is better than the current winner // check whether this color is better than the current winner
int r_err = r - ((int32_t)pPal->r[ind]); int r_err = r - ((int32_t)pPal->r[ind]);
int g_err = g - ((int32_t)pPal->g[ind]); int g_err = g - ((int32_t)pPal->g[ind]);
int b_err = b - ((int32_t)pPal->b[ind]); int b_err = b - ((int32_t)pPal->b[ind]);
int diff = GifIAbs(r_err)+GifIAbs(g_err)+GifIAbs(b_err); int diff = GifIAbs(r_err) + GifIAbs(g_err) + GifIAbs(b_err);
if(diff < *bestDiff) if (diff < *bestDiff) {
{ *bestInd = ind;
*bestInd = ind; *bestDiff = diff;
*bestDiff = diff; }
}
return; return;
} }
// take the appropriate color (r, g, or b) for this node of the k-d tree // take the appropriate color (r, g, or b) for this node of the k-d tree
int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b; int comps[3];
int splitComp = comps[pPal->treeSplitElt[treeRoot]]; comps[0] = r;
comps[1] = g;
comps[2] = b;
int splitComp = comps[pPal->treeSplitElt[treeRoot]];
int splitPos = pPal->treeSplit[treeRoot]; int splitPos = pPal->treeSplit[treeRoot];
if(splitPos > splitComp) if (splitPos > splitComp) {
{ // check the left subtree
// check the left subtree GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2); if (*bestDiff > splitPos - splitComp) {
if( *bestDiff > splitPos - splitComp ) // cannot prove there's not a better value in the right subtree, check that too
{ GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1);
// cannot prove there's not a better value in the right subtree, check that too }
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2+1); } else {
} GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1);
} if (*bestDiff > splitComp - splitPos) {
else GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
{ }
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2+1); }
if( *bestDiff > splitComp - splitPos )
{
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2);
}
}
} }
void GifSwapPixels(uint8_t* image, int pixA, int pixB) void GifSwapPixels(uint8_t * image, int pixA, int pixB) {
{ uint8_t rA = image[pixA * 4];
uint8_t rA = image[pixA*4]; uint8_t gA = image[pixA * 4 + 1];
uint8_t gA = image[pixA*4+1]; uint8_t bA = image[pixA * 4 + 2];
uint8_t bA = image[pixA*4+2]; uint8_t aA = image[pixA * 4 + 3];
uint8_t aA = image[pixA*4+3];
uint8_t rB = image[pixB*4]; uint8_t rB = image[pixB * 4];
uint8_t gB = image[pixB*4+1]; uint8_t gB = image[pixB * 4 + 1];
uint8_t bB = image[pixB*4+2]; uint8_t bB = image[pixB * 4 + 2];
uint8_t aB = image[pixA*4+3]; uint8_t aB = image[pixA * 4 + 3];
image[pixA*4] = rB; image[pixA * 4] = rB;
image[pixA*4+1] = gB; image[pixA * 4 + 1] = gB;
image[pixA*4+2] = bB; image[pixA * 4 + 2] = bB;
image[pixA*4+3] = aB; image[pixA * 4 + 3] = aB;
image[pixB*4] = rA; image[pixB * 4] = rA;
image[pixB*4+1] = gA; image[pixB * 4 + 1] = gA;
image[pixB*4+2] = bA; image[pixB * 4 + 2] = bA;
image[pixB*4+3] = aA; image[pixB * 4 + 3] = aA;
} }
// just the partition operation from quicksort // just the partition operation from quicksort
int GifPartition(uint8_t* image, const int left, const int right, const int elt, int pivotIndex) int GifPartition(uint8_t * image, const int left, const int right, const int elt, int pivotIndex) {
{ const int pivotValue = image[(pivotIndex)*4 + elt];
const int pivotValue = image[(pivotIndex)*4+elt]; GifSwapPixels(image, pivotIndex, right - 1);
GifSwapPixels(image, pivotIndex, right-1); int storeIndex = left;
int storeIndex = left; bool split = 0;
bool split = 0; for (int ii = left; ii < right - 1; ++ii) {
for(int ii=left; ii<right-1; ++ii) int arrayVal = image[ii * 4 + elt];
{ if (arrayVal < pivotValue) {
int arrayVal = image[ii*4+elt]; GifSwapPixels(image, ii, storeIndex);
if( arrayVal < pivotValue ) ++storeIndex;
{ } else if (arrayVal == pivotValue) {
GifSwapPixels(image, ii, storeIndex); if (split) {
++storeIndex; GifSwapPixels(image, ii, storeIndex);
} ++storeIndex;
else if( arrayVal == pivotValue ) }
{ split = !split;
if(split) }
{ }
GifSwapPixels(image, ii, storeIndex); GifSwapPixels(image, storeIndex, right - 1);
++storeIndex; return storeIndex;
}
split = !split;
}
}
GifSwapPixels(image, storeIndex, right-1);
return storeIndex;
} }
// Perform an incomplete sort, finding all elements above and below the desired median // Perform an incomplete sort, finding all elements above and below the desired median
void GifPartitionByMedian(uint8_t* image, int left, int right, int com, int neededCenter) void GifPartitionByMedian(uint8_t * image, int left, int right, int com, int neededCenter) {
{ if (left < right - 1) {
if(left < right-1) int pivotIndex = left + (right - left) / 2;
{
int pivotIndex = left + (right-left)/2;
pivotIndex = GifPartition(image, left, right, com, pivotIndex); pivotIndex = GifPartition(image, left, right, com, pivotIndex);
// Only "sort" the section of the array that contains the median // Only "sort" the section of the array that contains the median
if(pivotIndex > neededCenter) if (pivotIndex > neededCenter) GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
if(pivotIndex < neededCenter) if (pivotIndex < neededCenter) GifPartitionByMedian(image, pivotIndex + 1, right, com, neededCenter);
GifPartitionByMedian(image, pivotIndex+1, right, com, neededCenter); }
}
} }
// Builds a palette by creating a balanced k-d tree of all pixels in the image // Builds a palette by creating a balanced k-d tree of all pixels in the image
void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette* pal) void GifSplitPalette(uint8_t * image,
{ int numPixels,
if(lastElt <= firstElt || numPixels == 0) int firstElt,
return; int lastElt,
int splitElt,
int splitDist,
int treeNode,
bool buildForDither,
GifPalette * pal) {
if (lastElt <= firstElt || numPixels == 0) return;
// base case, bottom of the tree // base case, bottom of the tree
if(lastElt == firstElt+1) if (lastElt == firstElt + 1) {
{ if (buildForDither) {
if(buildForDither) // Dithering needs at least one color as dark as anything
{ // in the image and at least one brightest color -
// Dithering needs at least one color as dark as anything // otherwise it builds up error and produces strange artifacts
// in the image and at least one brightest color - if (firstElt == 1) {
// otherwise it builds up error and produces strange artifacts // special case: the darkest color in the image
if( firstElt == 1 ) uint32_t r = 255, g = 255, b = 255;
{ for (int ii = 0; ii < numPixels; ++ii) {
// special case: the darkest color in the image r = (uint32_t)GifIMin((int32_t)r, image[ii * 4 + 0]);
uint32_t r=255, g=255, b=255; g = (uint32_t)GifIMin((int32_t)g, image[ii * 4 + 1]);
for(int ii=0; ii<numPixels; ++ii) b = (uint32_t)GifIMin((int32_t)b, image[ii * 4 + 2]);
{ }
r = (uint32_t)GifIMin((int32_t)r, image[ii * 4 + 0]);
g = (uint32_t)GifIMin((int32_t)g, image[ii * 4 + 1]);
b = (uint32_t)GifIMin((int32_t)b, image[ii * 4 + 2]);
}
pal->r[firstElt] = (uint8_t)r; pal->r[firstElt] = (uint8_t)r;
pal->g[firstElt] = (uint8_t)g; pal->g[firstElt] = (uint8_t)g;
pal->b[firstElt] = (uint8_t)b; pal->b[firstElt] = (uint8_t)b;
return; return;
} }
if( firstElt == (1 << pal->bitDepth)-1 ) if (firstElt == (1 << pal->bitDepth) - 1) {
{ // special case: the lightest color in the image
// special case: the lightest color in the image uint32_t r = 0, g = 0, b = 0;
uint32_t r=0, g=0, b=0; for (int ii = 0; ii < numPixels; ++ii) {
for(int ii=0; ii<numPixels; ++ii) r = (uint32_t)GifIMax((int32_t)r, image[ii * 4 + 0]);
{ g = (uint32_t)GifIMax((int32_t)g, image[ii * 4 + 1]);
r = (uint32_t)GifIMax((int32_t)r, image[ii * 4 + 0]); b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]);
g = (uint32_t)GifIMax((int32_t)g, image[ii * 4 + 1]); }
b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]);
}
pal->r[firstElt] = (uint8_t)r; pal->r[firstElt] = (uint8_t)r;
pal->g[firstElt] = (uint8_t)g; pal->g[firstElt] = (uint8_t)g;
pal->b[firstElt] = (uint8_t)b; pal->b[firstElt] = (uint8_t)b;
return; return;
} }
} }
// otherwise, take the average of all colors in this subcube // otherwise, take the average of all colors in this subcube
uint64_t r=0, g=0, b=0; uint64_t r = 0, g = 0, b = 0;
for(int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{ r += image[ii * 4 + 0];
r += image[ii*4+0]; g += image[ii * 4 + 1];
g += image[ii*4+1]; b += image[ii * 4 + 2];
b += image[ii*4+2]; }
}
r += (uint64_t)numPixels / 2; // round to nearest r += (uint64_t)numPixels / 2; // round to nearest
g += (uint64_t)numPixels / 2; g += (uint64_t)numPixels / 2;
b += (uint64_t)numPixels / 2; b += (uint64_t)numPixels / 2;
r /= (uint64_t)numPixels; r /= (uint64_t)numPixels;
g /= (uint64_t)numPixels; g /= (uint64_t)numPixels;
b /= (uint64_t)numPixels; b /= (uint64_t)numPixels;
pal->r[firstElt] = (uint8_t)r; pal->r[firstElt] = (uint8_t)r;
pal->g[firstElt] = (uint8_t)g; pal->g[firstElt] = (uint8_t)g;
pal->b[firstElt] = (uint8_t)b; pal->b[firstElt] = (uint8_t)b;
return; return;
} }
// Find the axis with the largest range // Find the axis with the largest range
int minR = 255, maxR = 0; int minR = 255, maxR = 0;
int minG = 255, maxG = 0; int minG = 255, maxG = 0;
int minB = 255, maxB = 0; int minB = 255, maxB = 0;
for(int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{ int r = image[ii * 4 + 0];
int r = image[ii*4+0]; int g = image[ii * 4 + 1];
int g = image[ii*4+1]; int b = image[ii * 4 + 2];
int b = image[ii*4+2];
if(r > maxR) maxR = r; if (r > maxR) maxR = r;
if(r < minR) minR = r; if (r < minR) minR = r;
if(g > maxG) maxG = g; if (g > maxG) maxG = g;
if(g < minG) minG = g; if (g < minG) minG = g;
if(b > maxB) maxB = b; if (b > maxB) maxB = b;
if(b < minB) minB = b; if (b < minB) minB = b;
} }
int rRange = maxR - minR; int rRange = maxR - minR;
int gRange = maxG - minG; int gRange = maxG - minG;
int bRange = maxB - minB; int bRange = maxB - minB;
// and split along that axis. (incidentally, this means this isn't a "proper" k-d tree but I don't know what else to call it) // and split along that axis. (incidentally, this means this isn't a "proper" k-d tree but I don't know what else to call it)
int splitCom = 1; int splitCom = 1;
if(bRange > gRange) splitCom = 2; if (bRange > gRange) splitCom = 2;
if(rRange > bRange && rRange > gRange) splitCom = 0; if (rRange > bRange && rRange > gRange) splitCom = 0;
int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt); int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt);
int subPixelsB = numPixels-subPixelsA; int subPixelsB = numPixels - subPixelsA;
GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA); GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA);
pal->treeSplitElt[treeNode] = (uint8_t)splitCom; pal->treeSplitElt[treeNode] = (uint8_t)splitCom;
pal->treeSplit[treeNode] = image[subPixelsA*4+splitCom]; pal->treeSplit[treeNode] = image[subPixelsA * 4 + splitCom];
GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt-splitDist, splitDist/2, treeNode*2, buildForDither, pal); GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt - splitDist, splitDist / 2, treeNode * 2, buildForDither, pal);
GifSplitPalette(image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2+1, buildForDither, pal); GifSplitPalette(image + subPixelsA * 4,
subPixelsB,
splitElt,
lastElt,
splitElt + splitDist,
splitDist / 2,
treeNode * 2 + 1,
buildForDither,
pal);
} }
// Finds all pixels that have changed from the previous image and // Finds all pixels that have changed from the previous image and
// moves them to the fromt of th buffer. // moves them to the fromt of th buffer.
// This allows us to build a palette optimized for the colors of the // This allows us to build a palette optimized for the colors of the
// changed pixels only. // changed pixels only.
int GifPickChangedPixels( const uint8_t* lastFrame, uint8_t* frame, int numPixels ) int GifPickChangedPixels(const uint8_t * lastFrame, uint8_t * frame, int numPixels) {
{ int numChanged = 0;
int numChanged = 0; uint8_t * writeIter = frame;
uint8_t* writeIter = frame;
for (int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{ if (lastFrame[0] != frame[0] || lastFrame[1] != frame[1] || lastFrame[2] != frame[2]) {
if(lastFrame[0] != frame[0] || writeIter[0] = frame[0];
lastFrame[1] != frame[1] || writeIter[1] = frame[1];
lastFrame[2] != frame[2]) writeIter[2] = frame[2];
{ ++numChanged;
writeIter[0] = frame[0]; writeIter += 4;
writeIter[1] = frame[1]; }
writeIter[2] = frame[2]; lastFrame += 4;
++numChanged; frame += 4;
writeIter += 4; }
}
lastFrame += 4;
frame += 4;
}
return numChanged; return numChanged;
} }
// Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom. // Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom.
// This is known as the "modified median split" technique // This is known as the "modified median split" technique
void GifMakePalette( const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette* pPal ) void GifMakePalette(const uint8_t * lastFrame,
{ const uint8_t * nextFrame,
pPal->bitDepth = bitDepth; uint32_t width,
uint32_t height,
int bitDepth,
bool buildForDither,
GifPalette * pPal) {
pPal->bitDepth = bitDepth;
// SplitPalette is destructive (it sorts the pixels by color) so // SplitPalette is destructive (it sorts the pixels by color) so
// we must create a copy of the image for it to destroy // we must create a copy of the image for it to destroy
size_t imageSize = (size_t)(width * height * 4 * sizeof(uint8_t)); size_t imageSize = (size_t)(width * height * 4 * sizeof(uint8_t));
uint8_t* destroyableImage = (uint8_t*)GIF_TEMP_MALLOC(imageSize); uint8_t * destroyableImage = (uint8_t *)GIF_TEMP_MALLOC(imageSize);
memcpy(destroyableImage, nextFrame, imageSize); memcpy(destroyableImage, nextFrame, imageSize);
int numPixels = (int)(width * height); int numPixels = (int)(width * height);
if(lastFrame) if (lastFrame) numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
const int lastElt = 1 << bitDepth; const int lastElt = 1 << bitDepth;
const int splitElt = lastElt/2; const int splitElt = lastElt / 2;
const int splitDist = splitElt/2; const int splitDist = splitElt / 2;
GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal); GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal);
GIF_TEMP_FREE(destroyableImage); GIF_TEMP_FREE(destroyableImage);
// add the bottom node for the transparency index // add the bottom node for the transparency index
pPal->treeSplit[1 << (bitDepth-1)] = 0; pPal->treeSplit[1 << (bitDepth - 1)] = 0;
pPal->treeSplitElt[1 << (bitDepth-1)] = 0; pPal->treeSplitElt[1 << (bitDepth - 1)] = 0;
pPal->r[0] = pPal->g[0] = pPal->b[0] = 0; pPal->r[0] = pPal->g[0] = pPal->b[0] = 0;
} }
// Implements Floyd-Steinberg dithering, writes palette value to alpha // Implements Floyd-Steinberg dithering, writes palette value to alpha
void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal ) void GifDitherImage(const uint8_t * lastFrame,
{ const uint8_t * nextFrame,
int numPixels = (int)(width * height); uint8_t * outFrame,
uint32_t width,
uint32_t height,
GifPalette * pPal) {
int numPixels = (int)(width * height);
// quantPixels initially holds color*256 for all pixels // quantPixels initially holds color*256 for all pixels
// The extra 8 bits of precision allow for sub-single-color error values // The extra 8 bits of precision allow for sub-single-color error values
// to be propagated // to be propagated
int32_t *quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4); int32_t * quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4);
for( int ii=0; ii<numPixels*4; ++ii ) for (int ii = 0; ii < numPixels * 4; ++ii) {
{ uint8_t pix = nextFrame[ii];
uint8_t pix = nextFrame[ii]; int32_t pix16 = (int32_t)(pix)*256;
int32_t pix16 = (int32_t)(pix) * 256; quantPixels[ii] = pix16;
quantPixels[ii] = pix16; }
}
for( uint32_t yy=0; yy<height; ++yy ) for (uint32_t yy = 0; yy < height; ++yy) {
{ for (uint32_t xx = 0; xx < width; ++xx) {
for( uint32_t xx=0; xx<width; ++xx ) int32_t * nextPix = quantPixels + 4 * (yy * width + xx);
{ const uint8_t * lastPix = lastFrame ? lastFrame + 4 * (yy * width + xx) : NULL;
int32_t* nextPix = quantPixels + 4*(yy*width+xx);
const uint8_t* lastPix = lastFrame? lastFrame + 4*(yy*width+xx) : NULL;
// Compute the colors we want (rounding to nearest) // Compute the colors we want (rounding to nearest)
int32_t rr = (nextPix[0] + 127) / 256; int32_t rr = (nextPix[0] + 127) / 256;
int32_t gg = (nextPix[1] + 127) / 256; int32_t gg = (nextPix[1] + 127) / 256;
int32_t bb = (nextPix[2] + 127) / 256; int32_t bb = (nextPix[2] + 127) / 256;
// if it happens that we want the color from last frame, then just write out // if it happens that we want the color from last frame, then just write out
// a transparent pixel // a transparent pixel
if( lastFrame && if (lastFrame && lastPix[0] == rr && lastPix[1] == gg && lastPix[2] == bb) {
lastPix[0] == rr && nextPix[0] = rr;
lastPix[1] == gg && nextPix[1] = gg;
lastPix[2] == bb ) nextPix[2] = bb;
{ nextPix[3] = kGifTransIndex;
nextPix[0] = rr; continue;
nextPix[1] = gg; }
nextPix[2] = bb;
nextPix[3] = kGifTransIndex;
continue;
}
int32_t bestDiff = 1000000; int32_t bestDiff = 1000000;
int32_t bestInd = kGifTransIndex; int32_t bestInd = kGifTransIndex;
// Search the palete // Search the palete
GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1); GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1);
// Write the result to the temp buffer // Write the result to the temp buffer
int32_t r_err = nextPix[0] - (int32_t)(pPal->r[bestInd]) * 256; int32_t r_err = nextPix[0] - (int32_t)(pPal->r[bestInd]) * 256;
int32_t g_err = nextPix[1] - (int32_t)(pPal->g[bestInd]) * 256; int32_t g_err = nextPix[1] - (int32_t)(pPal->g[bestInd]) * 256;
int32_t b_err = nextPix[2] - (int32_t)(pPal->b[bestInd]) * 256; int32_t b_err = nextPix[2] - (int32_t)(pPal->b[bestInd]) * 256;
nextPix[0] = pPal->r[bestInd]; nextPix[0] = pPal->r[bestInd];
nextPix[1] = pPal->g[bestInd]; nextPix[1] = pPal->g[bestInd];
nextPix[2] = pPal->b[bestInd]; nextPix[2] = pPal->b[bestInd];
nextPix[3] = bestInd; nextPix[3] = bestInd;
// Propagate the error to the four adjacent locations // Propagate the error to the four adjacent locations
// that we haven't touched yet // that we haven't touched yet
int quantloc_7 = (int)(yy * width + xx + 1); int quantloc_7 = (int)(yy * width + xx + 1);
int quantloc_3 = (int)(yy * width + width + xx - 1); int quantloc_3 = (int)(yy * width + width + xx - 1);
int quantloc_5 = (int)(yy * width + width + xx); int quantloc_5 = (int)(yy * width + width + xx);
int quantloc_1 = (int)(yy * width + width + xx + 1); int quantloc_1 = (int)(yy * width + width + xx + 1);
if(quantloc_7 < numPixels) if (quantloc_7 < numPixels) {
{ int32_t * pix7 = quantPixels + 4 * quantloc_7;
int32_t* pix7 = quantPixels+4*quantloc_7; pix7[0] += GifIMax(-pix7[0], r_err * 7 / 16);
pix7[0] += GifIMax( -pix7[0], r_err * 7 / 16 ); pix7[1] += GifIMax(-pix7[1], g_err * 7 / 16);
pix7[1] += GifIMax( -pix7[1], g_err * 7 / 16 ); pix7[2] += GifIMax(-pix7[2], b_err * 7 / 16);
pix7[2] += GifIMax( -pix7[2], b_err * 7 / 16 ); }
}
if(quantloc_3 < numPixels) if (quantloc_3 < numPixels) {
{ int32_t * pix3 = quantPixels + 4 * quantloc_3;
int32_t* pix3 = quantPixels+4*quantloc_3; pix3[0] += GifIMax(-pix3[0], r_err * 3 / 16);
pix3[0] += GifIMax( -pix3[0], r_err * 3 / 16 ); pix3[1] += GifIMax(-pix3[1], g_err * 3 / 16);
pix3[1] += GifIMax( -pix3[1], g_err * 3 / 16 ); pix3[2] += GifIMax(-pix3[2], b_err * 3 / 16);
pix3[2] += GifIMax( -pix3[2], b_err * 3 / 16 ); }
}
if(quantloc_5 < numPixels) if (quantloc_5 < numPixels) {
{ int32_t * pix5 = quantPixels + 4 * quantloc_5;
int32_t* pix5 = quantPixels+4*quantloc_5; pix5[0] += GifIMax(-pix5[0], r_err * 5 / 16);
pix5[0] += GifIMax( -pix5[0], r_err * 5 / 16 ); pix5[1] += GifIMax(-pix5[1], g_err * 5 / 16);
pix5[1] += GifIMax( -pix5[1], g_err * 5 / 16 ); pix5[2] += GifIMax(-pix5[2], b_err * 5 / 16);
pix5[2] += GifIMax( -pix5[2], b_err * 5 / 16 ); }
}
if(quantloc_1 < numPixels) if (quantloc_1 < numPixels) {
{ int32_t * pix1 = quantPixels + 4 * quantloc_1;
int32_t* pix1 = quantPixels+4*quantloc_1; pix1[0] += GifIMax(-pix1[0], r_err / 16);
pix1[0] += GifIMax( -pix1[0], r_err / 16 ); pix1[1] += GifIMax(-pix1[1], g_err / 16);
pix1[1] += GifIMax( -pix1[1], g_err / 16 ); pix1[2] += GifIMax(-pix1[2], b_err / 16);
pix1[2] += GifIMax( -pix1[2], b_err / 16 ); }
} }
} }
}
// Copy the palettized result to the output buffer // Copy the palettized result to the output buffer
for( int ii=0; ii<numPixels*4; ++ii ) for (int ii = 0; ii < numPixels * 4; ++ii) {
{ outFrame[ii] = (uint8_t)quantPixels[ii];
outFrame[ii] = (uint8_t)quantPixels[ii]; }
}
GIF_TEMP_FREE(quantPixels); GIF_TEMP_FREE(quantPixels);
} }
// Picks palette colors for the image using simple thresholding, no dithering // Picks palette colors for the image using simple thresholding, no dithering
void GifThresholdImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal ) void GifThresholdImage(const uint8_t * lastFrame,
{ const uint8_t * nextFrame,
uint32_t numPixels = width*height; uint8_t * outFrame,
for( uint32_t ii=0; ii<numPixels; ++ii ) uint32_t width,
{ uint32_t height,
// if a previous color is available, and it matches the current color, GifPalette * pPal) {
// set the pixel to transparent uint32_t numPixels = width * height;
if(lastFrame && for (uint32_t ii = 0; ii < numPixels; ++ii) {
lastFrame[0] == nextFrame[0] && // if a previous color is available, and it matches the current color,
lastFrame[1] == nextFrame[1] && // set the pixel to transparent
lastFrame[2] == nextFrame[2]) if (lastFrame && lastFrame[0] == nextFrame[0] && lastFrame[1] == nextFrame[1] && lastFrame[2] == nextFrame[2]) {
{ outFrame[0] = lastFrame[0];
outFrame[0] = lastFrame[0]; outFrame[1] = lastFrame[1];
outFrame[1] = lastFrame[1]; outFrame[2] = lastFrame[2];
outFrame[2] = lastFrame[2]; outFrame[3] = kGifTransIndex;
outFrame[3] = kGifTransIndex; } else {
} // palettize the pixel
else int32_t bestDiff = 1000000;
{ int32_t bestInd = 1;
// palettize the pixel GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], &bestInd, &bestDiff, 1);
int32_t bestDiff = 1000000;
int32_t bestInd = 1;
GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], &bestInd, &bestDiff, 1);
// Write the resulting color to the output buffer // Write the resulting color to the output buffer
outFrame[0] = pPal->r[bestInd]; outFrame[0] = pPal->r[bestInd];
outFrame[1] = pPal->g[bestInd]; outFrame[1] = pPal->g[bestInd];
outFrame[2] = pPal->b[bestInd]; outFrame[2] = pPal->b[bestInd];
outFrame[3] = (uint8_t)bestInd; outFrame[3] = (uint8_t)bestInd;
} }
if(lastFrame) lastFrame += 4; if (lastFrame) lastFrame += 4;
outFrame += 4; outFrame += 4;
nextFrame += 4; nextFrame += 4;
} }
} }
// Simple structure to write out the LZW-compressed portion of the image // Simple structure to write out the LZW-compressed portion of the image
// one bit at a time // one bit at a time
typedef struct typedef struct {
{ uint8_t bitIndex; // how many bits in the partial byte written so far
uint8_t bitIndex; // how many bits in the partial byte written so far uint8_t byte; // current partial byte
uint8_t byte; // current partial byte
uint32_t chunkIndex; uint32_t chunkIndex;
uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file
} GifBitStatus; } GifBitStatus;
// insert a single bit // insert a single bit
void GifWriteBit( GifBitStatus* stat, uint32_t bit ) void GifWriteBit(GifBitStatus * stat, uint32_t bit) {
{ bit = bit & 1;
bit = bit & 1; bit = bit << stat->bitIndex;
bit = bit << stat->bitIndex; stat->byte |= bit;
stat->byte |= bit;
++stat->bitIndex; ++stat->bitIndex;
if( stat->bitIndex > 7 ) if (stat->bitIndex > 7) {
{ // move the newly-finished byte to the chunk buffer
// move the newly-finished byte to the chunk buffer stat->chunk[stat->chunkIndex++] = stat->byte;
stat->chunk[stat->chunkIndex++] = stat->byte; // and start a new byte
// and start a new byte stat->bitIndex = 0;
stat->bitIndex = 0; stat->byte = 0;
stat->byte = 0; }
}
} }
// write all bytes so far to the file // write all bytes so far to the file
void GifWriteChunk( FILE* f, GifBitStatus* stat ) void GifWriteChunk(FILE * f, GifBitStatus * stat) {
{ fputc((int)stat->chunkIndex, f);
fputc((int)stat->chunkIndex, f); fwrite(stat->chunk, 1, stat->chunkIndex, f);
fwrite(stat->chunk, 1, stat->chunkIndex, f);
stat->bitIndex = 0; stat->bitIndex = 0;
stat->byte = 0; stat->byte = 0;
stat->chunkIndex = 0; stat->chunkIndex = 0;
} }
void GifWriteCode( FILE* f, GifBitStatus* stat, uint32_t code, uint32_t length ) void GifWriteCode(FILE * f, GifBitStatus * stat, uint32_t code, uint32_t length) {
{ for (uint32_t ii = 0; ii < length; ++ii) {
for( uint32_t ii=0; ii<length; ++ii ) GifWriteBit(stat, code);
{ code = code >> 1;
GifWriteBit(stat, code);
code = code >> 1;
if( stat->chunkIndex == 255 ) if (stat->chunkIndex == 255) {
{ GifWriteChunk(f, stat);
GifWriteChunk(f, stat); }
} }
}
} }
// The LZW dictionary is a 256-ary tree constructed as the file is encoded, // The LZW dictionary is a 256-ary tree constructed as the file is encoded,
// this is one node // this is one node
typedef struct typedef struct {
{ uint16_t m_next[256];
uint16_t m_next[256];
} GifLzwNode; } GifLzwNode;
// write a 256-color (8-bit) image palette to the file // write a 256-color (8-bit) image palette to the file
void GifWritePalette( const GifPalette* pPal, FILE* f ) void GifWritePalette(const GifPalette * pPal, FILE * f) {
{ fputc(0, f); // first color: transparency
fputc(0, f); // first color: transparency fputc(0, f);
fputc(0, f); fputc(0, f);
fputc(0, f);
for(int ii=1; ii<(1 << pPal->bitDepth); ++ii) for (int ii = 1; ii < (1 << pPal->bitDepth); ++ii) {
{ uint32_t r = pPal->r[ii];
uint32_t r = pPal->r[ii]; uint32_t g = pPal->g[ii];
uint32_t g = pPal->g[ii]; uint32_t b = pPal->b[ii];
uint32_t b = pPal->b[ii];
fputc((int)r, f); fputc((int)r, f);
fputc((int)g, f); fputc((int)g, f);
fputc((int)b, f); fputc((int)b, f);
} }
} }
// write the image header, LZW-compress and write out the image // write the image header, LZW-compress and write out the image
void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette* pPal) void GifWriteLzwImage(FILE * f,
{ uint8_t * image,
// graphics control extension uint32_t left,
fputc(0x21, f); uint32_t top,
fputc(0xf9, f); uint32_t width,
fputc(0x04, f); uint32_t height,
fputc(0x05, f); // leave prev frame in place, this frame has transparency uint32_t delay,
fputc(delay & 0xff, f); GifPalette * pPal) {
fputc((delay >> 8) & 0xff, f); // graphics control extension
fputc(kGifTransIndex, f); // transparent color index fputc(0x21, f);
fputc(0, f); fputc(0xf9, f);
fputc(0x04, f);
fputc(0x05, f); // leave prev frame in place, this frame has transparency
fputc(delay & 0xff, f);
fputc((delay >> 8) & 0xff, f);
fputc(kGifTransIndex, f); // transparent color index
fputc(0, f);
fputc(0x2c, f); // image descriptor block fputc(0x2c, f); // image descriptor block
fputc(left & 0xff, f); // corner of image in canvas space fputc(left & 0xff, f); // corner of image in canvas space
fputc((left >> 8) & 0xff, f); fputc((left >> 8) & 0xff, f);
fputc(top & 0xff, f); fputc(top & 0xff, f);
fputc((top >> 8) & 0xff, f); fputc((top >> 8) & 0xff, f);
fputc(width & 0xff, f); // width and height of image fputc(width & 0xff, f); // width and height of image
fputc((width >> 8) & 0xff, f); fputc((width >> 8) & 0xff, f);
fputc(height & 0xff, f); fputc(height & 0xff, f);
fputc((height >> 8) & 0xff, f); fputc((height >> 8) & 0xff, f);
//fputc(0, f); // no local color table, no transparency // fputc(0, f); // no local color table, no transparency
//fputc(0x80, f); // no local color table, but transparency // fputc(0x80, f); // no local color table, but transparency
fputc(0x80 + pPal->bitDepth-1, f); // local color table present, 2 ^ bitDepth entries fputc(0x80 + pPal->bitDepth - 1, f); // local color table present, 2 ^ bitDepth entries
GifWritePalette(pPal, f); GifWritePalette(pPal, f);
const int minCodeSize = pPal->bitDepth; const int minCodeSize = pPal->bitDepth;
const uint32_t clearCode = 1 << pPal->bitDepth; const uint32_t clearCode = 1 << pPal->bitDepth;
fputc(minCodeSize, f); // min code size 8 bits fputc(minCodeSize, f); // min code size 8 bits
GifLzwNode* codetree = (GifLzwNode*)GIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096); GifLzwNode * codetree = (GifLzwNode *)GIF_TEMP_MALLOC(sizeof(GifLzwNode) * 4096);
memset(codetree, 0, sizeof(GifLzwNode)*4096); memset(codetree, 0, sizeof(GifLzwNode) * 4096);
int32_t curCode = -1; int32_t curCode = -1;
uint32_t codeSize = (uint32_t)minCodeSize + 1; uint32_t codeSize = (uint32_t)minCodeSize + 1;
uint32_t maxCode = clearCode+1; uint32_t maxCode = clearCode + 1;
GifBitStatus stat; GifBitStatus stat;
stat.byte = 0; stat.byte = 0;
stat.bitIndex = 0; stat.bitIndex = 0;
stat.chunkIndex = 0; stat.chunkIndex = 0;
GifWriteCode(f, &stat, clearCode, codeSize); // start with a fresh LZW dictionary GifWriteCode(f, &stat, clearCode, codeSize); // start with a fresh LZW dictionary
for(uint32_t yy=0; yy<height; ++yy) for (uint32_t yy = 0; yy < height; ++yy) {
{ for (uint32_t xx = 0; xx < width; ++xx) {
for(uint32_t xx=0; xx<width; ++xx) #ifdef GIF_FLIP_VERT
{ // bottom-left origin image (such as an OpenGL capture)
#ifdef GIF_FLIP_VERT uint8_t nextValue = image[((height - 1 - yy) * width + xx) * 4 + 3];
// bottom-left origin image (such as an OpenGL capture) #else
uint8_t nextValue = image[((height-1-yy)*width+xx)*4+3]; // top-left origin
#else uint8_t nextValue = image[(yy * width + xx) * 4 + 3];
// top-left origin #endif
uint8_t nextValue = image[(yy*width+xx)*4+3];
#endif
// "loser mode" - no compression, every single code is followed immediately by a clear // "loser mode" - no compression, every single code is followed immediately by a clear
//WriteCode( f, stat, nextValue, codeSize ); // WriteCode( f, stat, nextValue, codeSize );
//WriteCode( f, stat, 256, codeSize ); // WriteCode( f, stat, 256, codeSize );
if( curCode < 0 ) if (curCode < 0) {
{ // first value in a new run
// first value in a new run curCode = nextValue;
curCode = nextValue; } else if (codetree[curCode].m_next[nextValue]) {
} // current run already in the dictionary
else if( codetree[curCode].m_next[nextValue] ) curCode = codetree[curCode].m_next[nextValue];
{ } else {
// current run already in the dictionary // finish the current run, write a code
curCode = codetree[curCode].m_next[nextValue]; GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
}
else
{
// finish the current run, write a code
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
// insert the new run into the dictionary // insert the new run into the dictionary
codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode; codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode;
if( maxCode >= (1ul << codeSize) ) if (maxCode >= (1ul << codeSize)) {
{ // dictionary entry count has broken a size barrier,
// dictionary entry count has broken a size barrier, // we need more bits for codes
// we need more bits for codes codeSize++;
codeSize++; }
} if (maxCode == 4095) {
if( maxCode == 4095 ) // the dictionary is full, clear it out and begin anew
{ GifWriteCode(f, &stat, clearCode, codeSize); // clear tree
// the dictionary is full, clear it out and begin anew
GifWriteCode(f, &stat, clearCode, codeSize); // clear tree
memset(codetree, 0, sizeof(GifLzwNode)*4096); memset(codetree, 0, sizeof(GifLzwNode) * 4096);
codeSize = (uint32_t)(minCodeSize + 1); codeSize = (uint32_t)(minCodeSize + 1);
maxCode = clearCode+1; maxCode = clearCode + 1;
} }
curCode = nextValue; curCode = nextValue;
} }
} }
} }
// compression footer // compression footer
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize); GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
GifWriteCode(f, &stat, clearCode, codeSize); GifWriteCode(f, &stat, clearCode, codeSize);
GifWriteCode(f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1); GifWriteCode(f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1);
// write out the last partial chunk // write out the last partial chunk
while( stat.bitIndex ) GifWriteBit(&stat, 0); while (stat.bitIndex)
if( stat.chunkIndex ) GifWriteChunk(f, &stat); GifWriteBit(&stat, 0);
if (stat.chunkIndex) GifWriteChunk(f, &stat);
fputc(0, f); // image block terminator fputc(0, f); // image block terminator
GIF_TEMP_FREE(codetree); GIF_TEMP_FREE(codetree);
} }
typedef struct typedef struct {
{ FILE * f;
FILE* f; uint8_t * oldImage;
uint8_t* oldImage; bool firstFrame;
bool firstFrame;
} GifWriter; } GifWriter;
// Creates a gif file. // Creates a gif file.
// The input GIFWriter is assumed to be uninitialized. // The input GIFWriter is assumed to be uninitialized.
// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value. // The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value.
bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth = 8, bool dither = false ) bool GifBegin(GifWriter * writer,
{ const char * filename,
(void)bitDepth; (void)dither; // Mute "Unused argument" warnings uint32_t width,
uint32_t height,
uint32_t delay,
int32_t bitDepth = 8,
bool dither = false) {
(void)bitDepth;
(void)dither; // Mute "Unused argument" warnings
#if defined(_MSC_VER) && (_MSC_VER >= 1400) #if defined(_MSC_VER) && (_MSC_VER >= 1400)
writer->f = 0; writer->f = 0;
fopen_s(&writer->f, filename, "wb"); fopen_s(&writer->f, filename, "wb");
#else #else
writer->f = fopen(filename, "wb"); writer->f = fopen(filename, "wb");
#endif #endif
if(!writer->f) return false; if (!writer->f) return false;
writer->firstFrame = true; writer->firstFrame = true;
// allocate // allocate
writer->oldImage = (uint8_t*)GIF_MALLOC(width*height*4); writer->oldImage = (uint8_t *)GIF_MALLOC(width * height * 4);
fputs("GIF89a", writer->f); fputs("GIF89a", writer->f);
// screen descriptor // screen descriptor
fputc(width & 0xff, writer->f); fputc(width & 0xff, writer->f);
fputc((width >> 8) & 0xff, writer->f); fputc((width >> 8) & 0xff, writer->f);
fputc(height & 0xff, writer->f); fputc(height & 0xff, writer->f);
fputc((height >> 8) & 0xff, writer->f); fputc((height >> 8) & 0xff, writer->f);
fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries
fputc(0, writer->f); // background color fputc(0, writer->f); // background color
fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989) fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989)
// now the "global" palette (really just a dummy palette) // now the "global" palette (really just a dummy palette)
// color 0: black // color 0: black
fputc(0, writer->f); fputc(0, writer->f);
fputc(0, writer->f); fputc(0, writer->f);
fputc(0, writer->f); fputc(0, writer->f);
// color 1: also black // color 1: also black
fputc(0, writer->f); fputc(0, writer->f);
fputc(0, writer->f); fputc(0, writer->f);
fputc(0, writer->f); fputc(0, writer->f);
if( delay != 0 ) if (delay != 0) {
{ // animation header
// animation header fputc(0x21, writer->f); // extension
fputc(0x21, writer->f); // extension fputc(0xff, writer->f); // application specific
fputc(0xff, writer->f); // application specific fputc(11, writer->f); // length 11
fputc(11, writer->f); // length 11 fputs("NETSCAPE2.0", writer->f); // yes, really
fputs("NETSCAPE2.0", writer->f); // yes, really fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data
fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data
fputc(1, writer->f); // JUST BECAUSE fputc(1, writer->f); // JUST BECAUSE
fputc(0, writer->f); // loop infinitely (byte 0) fputc(0, writer->f); // loop infinitely (byte 0)
fputc(0, writer->f); // loop infinitely (byte 1) fputc(0, writer->f); // loop infinitely (byte 1)
fputc(0, writer->f); // block terminator fputc(0, writer->f); // block terminator
} }
return true; return true;
} }
// Writes out a new frame to a GIF in progress. // Writes out a new frame to a GIF in progress.
// The GIFWriter should have been created by GIFBegin. // The GIFWriter should have been created by GIFBegin.
// AFAIK, it is legal to use different bit depths for different frames of an image - // AFAIK, it is legal to use different bit depths for different frames of an image -
// this may be handy to save bits in animations that don't change much. // this may be handy to save bits in animations that don't change much.
bool GifWriteFrame( GifWriter* writer, const uint8_t* image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth = 8, bool dither = false ) bool GifWriteFrame(GifWriter * writer,
{ const uint8_t * image,
if(!writer->f) return false; uint32_t width,
uint32_t height,
uint32_t delay,
int bitDepth = 8,
bool dither = false) {
if (!writer->f) return false;
const uint8_t* oldImage = writer->firstFrame? NULL : writer->oldImage; const uint8_t * oldImage = writer->firstFrame ? NULL : writer->oldImage;
writer->firstFrame = false; writer->firstFrame = false;
GifPalette pal; GifPalette pal;
GifMakePalette((dither? NULL : oldImage), image, width, height, bitDepth, dither, &pal); GifMakePalette((dither ? NULL : oldImage), image, width, height, bitDepth, dither, &pal);
if(dither) if (dither)
GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal); GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal);
else else
GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal); GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal);
GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal); GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal);
return true; return true;
} }
// Writes the EOF code, closes the file handle, and frees temp memory used by a GIF. // Writes the EOF code, closes the file handle, and frees temp memory used by a GIF.
// Many if not most viewers will still display a GIF properly if the EOF code is missing, // Many if not most viewers will still display a GIF properly if the EOF code is missing,
// but it's still a good idea to write it out. // but it's still a good idea to write it out.
bool GifEnd( GifWriter* writer ) bool GifEnd(GifWriter * writer) {
{ if (!writer->f) return false;
if(!writer->f) return false;
fputc(0x3b, writer->f); // end of file fputc(0x3b, writer->f); // end of file
fclose(writer->f); fclose(writer->f);
GIF_FREE(writer->oldImage); GIF_FREE(writer->oldImage);
writer->f = NULL; writer->f = NULL;
writer->oldImage = NULL; writer->oldImage = NULL;
return true; return true;
} }
#endif #endif
+532 -457
View File
@@ -1,19 +1,21 @@
#include "graphic.h" #include "graphic.h"
#include "gif.h"
#include "qad_types.h" #include "qad_types.h"
#include "uglwidget.h" #include "uglwidget.h"
#include "ui_graphic.h" #include "ui_graphic.h"
#include "ui_graphic_conf.h" #include "ui_graphic_conf.h"
#include <float.h>
#include <QMetaObject> #include <QActionGroup>
#include <QInputDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QTapAndHoldGesture> #include <QMetaObject>
#include <QPanGesture> #include <QPanGesture>
#include <QPinchGesture> #include <QPinchGesture>
#include <QActionGroup>
#include <QScrollArea> #include <QScrollArea>
#include <QTapAndHoldGesture>
#include <QTimer> #include <QTimer>
#include <QInputDialog> #include <float.h>
#include "gif.h"
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
# include <QRandomGenerator> # include <QRandomGenerator>
#endif #endif
@@ -21,12 +23,12 @@
# define NO_BUTTONS # define NO_BUTTONS
#else #else
# ifndef FORCE_NO_GL # ifndef FORCE_NO_GL
# define HAS_GL # define HAS_GL
# endif # endif
#endif #endif
#ifdef HAS_GL #ifdef HAS_GL
# ifndef GL_MULTISAMPLE # ifndef GL_MULTISAMPLE
# define GL_MULTISAMPLE 0x809D # define GL_MULTISAMPLE 0x809D
# endif # endif
#endif #endif
@@ -42,7 +44,7 @@ enum DateComponent {
}; };
const char _button_prop_name_[] = "_button_"; const char _button_prop_name_[] = "_button_";
const double rad2deg_qpie = 45. / atan(1.); const double rad2deg_qpie = 45. / atan(1.);
__GraphicRegistrator__ __graphic_registrator__; __GraphicRegistrator__ __graphic_registrator__;
@@ -61,6 +63,7 @@ public:
w->setAutoFillBackground(false); w->setAutoFillBackground(false);
} }
int minimum_hei; int minimum_hei;
protected: protected:
virtual QSize sizeHint() const { virtual QSize sizeHint() const {
QSize ret; QSize ret;
@@ -68,26 +71,24 @@ protected:
ret = widget()->sizeHint(); ret = widget()->sizeHint();
return ret; return ret;
} }
virtual QSize minimumSizeHint() const { virtual QSize minimumSizeHint() const { return QSize(1, minimum_hei); }
return QSize(1, minimum_hei);
}
}; };
Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), line_x_max(this), line_y_min(this), line_y_max(this) { 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; canvas_gl = 0;
timer_pause = timer_record = 0; timer_pause = timer_record = 0;
gesture_angle = 45.; gesture_angle = 45.;
leg_update = true; leg_update = true;
visible_update = fullscr = need_mouse_pan = m_fakeGL = false; visible_update = fullscr = need_mouse_pan = m_fakeGL = false;
gestures = gestures =
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
true; true;
#else #else
false; false;
#endif #endif
func_gridMarkX = func_gridMarkY = nullptr; func_gridMarkX = func_gridMarkY = nullptr;
ui = new Ui::Graphic(); ui = new Ui::Graphic();
ui->setupUi(this); ui->setupUi(this);
ui->scrollLegend->layout()->addWidget(new LegendScrollArea(ui->widgetLegend)); ui->scrollLegend->layout()->addWidget(new LegendScrollArea(ui->widgetLegend));
ui->scrollLegend->hide(); ui->scrollLegend->hide();
@@ -95,21 +96,20 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
#ifdef NO_BUTTONS #ifdef NO_BUTTONS
ui->widgetLeft->hide(); ui->widgetLeft->hide();
ui->widgetRight->hide(); ui->widgetRight->hide();
QList<QToolButton*> btnlist = { QList<QToolButton *> btnlist = {ui->graphic_buttonAutofit,
ui->graphic_buttonAutofit, ui->graphic_checkGrid,
ui->graphic_checkGrid, ui->graphic_checkGuides,
ui->graphic_checkGuides, ui->graphic_buttonFullscreen,
ui->graphic_buttonFullscreen, ui->graphic_checkBorderInputs,
ui->graphic_checkBorderInputs, ui->graphic_checkLegend,
ui->graphic_checkLegend, ui->graphic_checkPause,
ui->graphic_checkPause, ui->graphic_buttonConfigure,
ui->graphic_buttonConfigure, ui->graphic_buttonSave,
ui->graphic_buttonSave, ui->graphic_buttonExport,
ui->graphic_buttonExport, ui->graphic_buttonRecord,
ui->graphic_buttonRecord, ui->graphic_buttonClear,
ui->graphic_buttonClear, ui->graphic_buttonClose};
ui->graphic_buttonClose}; buttons_menu = new QMenu(this);
buttons_menu = new QMenu(this);
for (auto * b: btnlist) { for (auto * b: btnlist) {
auto * a = new QAction(this); auto * a = new QAction(this);
connect(a, SIGNAL(triggered()), b, SLOT(click())); connect(a, SIGNAL(triggered()), b, SLOT(click()));
@@ -120,31 +120,31 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
} }
#endif #endif
QActionGroup * agroup = new QActionGroup(this); QActionGroup * agroup = new QActionGroup(this);
agroup->addAction(ui->graphic_actionGuidesFree ); agroup->addAction(ui->graphic_actionGuidesFree);
agroup->addAction(ui->graphic_actionGuidesTrace ); agroup->addAction(ui->graphic_actionGuidesTrace);
agroup->addAction(ui->graphic_actionGuidesTraceX); agroup->addAction(ui->graphic_actionGuidesTraceX);
agroup->addAction(ui->graphic_actionGuidesTraceY); agroup->addAction(ui->graphic_actionGuidesTraceY);
ui->graphic_actionGuidesFree ->setProperty("_value", (int)Free ); ui->graphic_actionGuidesFree->setProperty("_value", (int)Free);
ui->graphic_actionGuidesTrace ->setProperty("_value", (int)TraceXY); ui->graphic_actionGuidesTrace->setProperty("_value", (int)TraceXY);
ui->graphic_actionGuidesTraceX->setProperty("_value", (int)TraceX ); ui->graphic_actionGuidesTraceX->setProperty("_value", (int)TraceX);
ui->graphic_actionGuidesTraceY->setProperty("_value", (int)TraceY ); ui->graphic_actionGuidesTraceY->setProperty("_value", (int)TraceY);
ui->graphic_actionGuidesFree->setChecked(true); ui->graphic_actionGuidesFree->setChecked(true);
connect(agroup, SIGNAL(triggered(QAction*)), this, SLOT(actionGuidesTriggered(QAction*))); connect(agroup, SIGNAL(triggered(QAction *)), this, SLOT(actionGuidesTriggered(QAction *)));
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesFree ); ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesFree);
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesTrace ); ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesTrace);
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesTraceX); ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesTraceX);
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesTraceY); ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesTraceY);
ui->graphic_buttonAutofit->addAction(ui->graphic_actionExpandX); ui->graphic_buttonAutofit->addAction(ui->graphic_actionExpandX);
ui->graphic_buttonAutofit->addAction(ui->graphic_actionExpandY); ui->graphic_buttonAutofit->addAction(ui->graphic_actionExpandY);
line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
line_x_max.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())->insertWidget(0, &line_y_min);
((QBoxLayout * )ui->widgetLY->layout())->addWidget(&line_y_max); ((QBoxLayout *)ui->widgetLY->layout())->addWidget(&line_y_max);
((QBoxLayout * )ui->widgetLX->layout())->insertWidget(0, &line_x_min); ((QBoxLayout *)ui->widgetLX->layout())->insertWidget(0, &line_x_min);
((QBoxLayout * )ui->widgetLX->layout())->addWidget(&line_x_max); ((QBoxLayout *)ui->widgetLX->layout())->addWidget(&line_x_max);
tm.restart(); tm.restart();
grid_numbers_x = grid_numbers_y = 1; grid_numbers_x = grid_numbers_y = 1;
LN10 = qLn(10.); LN10 = qLn(10.);
line_x_min.setClearButtonVisible(true); line_x_min.setClearButtonVisible(true);
line_x_max.setClearButtonVisible(true); line_x_max.setClearButtonVisible(true);
line_y_min.setClearButtonVisible(true); line_y_min.setClearButtonVisible(true);
@@ -153,12 +153,12 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
connect(&line_x_max, SIGNAL(valueChanged(double)), this, SLOT(lineXMaxChanged(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_min, SIGNAL(valueChanged(double)), this, SLOT(lineYMinChanged(double)));
connect(&line_y_max, SIGNAL(valueChanged(double)), this, SLOT(lineYMaxChanged(double))); connect(&line_y_max, SIGNAL(valueChanged(double)), this, SLOT(lineYMaxChanged(double)));
connect(ui->canvas_raster, SIGNAL(paintEvent(QPaintEvent * )), this, SLOT(canvasPaintEvent())); connect(ui->canvas_raster, SIGNAL(paintEvent(QPaintEvent *)), this, SLOT(canvasPaintEvent()));
prepareCanvas(ui->canvas_raster); prepareCanvas(ui->canvas_raster);
icon_exp_x = QIcon(":/icons/expand_x.png"); icon_exp_x = QIcon(":/icons/expand_x.png");
icon_exp_y = QIcon(":/icons/expand_y.png"); icon_exp_y = QIcon(":/icons/expand_y.png");
icon_exp_sx = QIcon(":/icons/expand_s_x.png"); icon_exp_sx = QIcon(":/icons/expand_s_x.png");
icon_exp_sy = QIcon(":/icons/expand_s_y.png"); icon_exp_sy = QIcon(":/icons/expand_s_y.png");
icon_pause_b = QImage(":/icons/pause-back.png"); icon_pause_b = QImage(":/icons/pause-back.png");
icon_pause_f = QImage(":/icons/pause-front.png"); icon_pause_f = QImage(":/icons/pause-front.png");
aupdate = grid = isFit = navigation = true; aupdate = grid = isFit = navigation = true;
@@ -167,17 +167,17 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
limit_.setCoords(-DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX); limit_.setCoords(-DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX);
eminx = eminy = DBL_MAX; eminx = eminy = DBL_MAX;
emaxx = emaxy = DBL_MIN; emaxx = emaxy = DBL_MIN;
grad_x = grad_y = Auto; grad_x = grad_y = Auto;
axis_type_x = Numeric; axis_type_x = Numeric;
floating_axis_type = Free; floating_axis_type = Free;
min_repaint_int = 25; min_repaint_int = 25;
lastw = lasth = 0; lastw = lasth = 0;
inc_x = 1.; inc_x = 1.;
//buffer = 0; // buffer = 0;
gridx = gridy = 1.; gridx = gridy = 1.;
history = 5.; history = 5.;
visible_time = -1.; visible_time = -1.;
thick = lineThickness(this); thick = lineThickness(this);
#if QT_VERSION_MAJOR >= 5 #if QT_VERSION_MAJOR >= 5
thick *= devicePixelRatio(); thick *= devicePixelRatio();
#endif #endif
@@ -189,13 +189,13 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
selbrush.setStyle(Qt::SolidPattern); selbrush.setStyle(Qt::SolidPattern);
selbrush.setColor(QColor(60, 175, 255, 100)); selbrush.setColor(QColor(60, 175, 255, 100));
text_color = palette().color(QPalette::WindowText); text_color = palette().color(QPalette::WindowText);
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine); grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine);
graphics.append(GraphicType()); graphics.append(GraphicType());
curGraphic = curTrace = 0; curGraphic = curTrace = 0;
selpen = palette().color(QPalette::WindowText); selpen = palette().color(QPalette::WindowText);
selpen.setStyle(Qt::DashLine); selpen.setStyle(Qt::DashLine);
back_color = palette().color(QPalette::Base); back_color = palette().color(QPalette::Base);
buttons_ = AllButtons; buttons_ = AllButtons;
setOpenGL(false); setOpenGL(false);
setButtonsPosition(Graphic::Left); setButtonsPosition(Graphic::Left);
setAntialiasing(false); setAntialiasing(false);
@@ -215,7 +215,7 @@ Graphic::~Graphic() {
delete buttons_menu; delete buttons_menu;
#endif #endif
delete conf; delete conf;
//if (buffer != 0) delete buffer; // if (buffer != 0) delete buffer;
} }
@@ -232,7 +232,7 @@ void Graphic::changeEvent(QEvent * e) {
void Graphic::resizeEvent(QResizeEvent *) { void Graphic::resizeEvent(QResizeEvent *) {
if (leg_update) if (leg_update)
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
QTimer::singleShot(0, this, [this](){updateLegend(false);}); QTimer::singleShot(0, this, [this]() { updateLegend(false); });
#else #else
updateLegend(false); updateLegend(false);
#endif #endif
@@ -241,7 +241,7 @@ void Graphic::resizeEvent(QResizeEvent *) {
void Graphic::showEvent(QShowEvent *) { void Graphic::showEvent(QShowEvent *) {
if (need_createGL && !canvas_gl) { if (need_createGL && !canvas_gl) {
//qDebug() << "create GL on show"; // qDebug() << "create GL on show";
canvas_gl = new UGLWidget(); canvas_gl = new UGLWidget();
ui->layoutCanvas->addWidget(canvas_gl); ui->layoutCanvas->addWidget(canvas_gl);
connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent())); connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent()));
@@ -257,8 +257,7 @@ void Graphic::showEvent(QShowEvent *) {
void Graphic::timerEvent(QTimerEvent * e) { void Graphic::timerEvent(QTimerEvent * e) {
if (e->timerId() == timer_pause) { if (e->timerId() == timer_pause) {
pause_phase += 0.02; pause_phase += 0.02;
if (pause_phase > 1.) if (pause_phase > 1.) pause_phase -= 1.;
pause_phase -= 1.;
update(); update();
} }
if (e->timerId() == timer_record) { if (e->timerId() == timer_record) {
@@ -274,16 +273,16 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
switch (e->type()) { switch (e->type()) {
case QEvent::Gesture: case QEvent::Gesture:
if (!navigation || !gestures) break; if (!navigation || !gestures) break;
foreach (QGesture * g, ((QGestureEvent*)e)->gestures()) foreach(QGesture * g, ((QGestureEvent *)e)->gestures())
procGesture(g); procGesture(g);
break; break;
case QEvent::KeyPress: { case QEvent::KeyPress: {
int k = ((QKeyEvent*)e)->key(); int k = ((QKeyEvent *)e)->key();
if ((k == Qt::Key_Back || k == Qt::Key_Escape) && fullscr) { if ((k == Qt::Key_Back || k == Qt::Key_Escape) && fullscr) {
leaveFullscreen(); leaveFullscreen();
return true; return true;
} }
} break; } break;
case QEvent::TouchBegin: case QEvent::TouchBegin:
if (!navigation || !gestures) break; if (!navigation || !gestures) break;
need_mouse_pan = true; need_mouse_pan = true;
@@ -292,9 +291,9 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
if (!navigation || !gestures) break; if (!navigation || !gestures) break;
QList<QTouchEvent::TouchPoint> tpl = QList<QTouchEvent::TouchPoint> tpl =
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
((QTouchEvent*)e)->touchPoints(); ((QTouchEvent *)e)->touchPoints();
#else #else
((QTouchEvent*)e)->points(); ((QTouchEvent *)e)->points();
#endif #endif
if (tpl.size() == 2) { if (tpl.size() == 2) {
need_mouse_pan = false; need_mouse_pan = false;
@@ -306,7 +305,7 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
#endif #endif
gesture_angle = rad2deg_qpie * qAtan2(qAbs(dp.y()), qAbs(dp.x())); gesture_angle = rad2deg_qpie * qAtan2(qAbs(dp.y()), qAbs(dp.x()));
} }
} break; } break;
default: break; default: break;
} }
} }
@@ -315,13 +314,13 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
void Graphic::prepareCanvas(QWidget * w) { void Graphic::prepareCanvas(QWidget * w) {
connect(w, SIGNAL(mouseMoveEvent(QMouseEvent * )), this, SLOT(canvasMouseMoveEvent(QMouseEvent * ))); connect(w, SIGNAL(mouseMoveEvent(QMouseEvent *)), this, SLOT(canvasMouseMoveEvent(QMouseEvent *)));
connect(w, SIGNAL(mousePressEvent(QMouseEvent * )), this, SLOT(canvasMousePressEvent(QMouseEvent * ))); connect(w, SIGNAL(mousePressEvent(QMouseEvent *)), this, SLOT(canvasMousePressEvent(QMouseEvent *)));
connect(w, SIGNAL(mouseReleaseEvent(QMouseEvent * )), this, SLOT(canvasMouseReleaseEvent(QMouseEvent * ))); connect(w, SIGNAL(mouseReleaseEvent(QMouseEvent *)), this, SLOT(canvasMouseReleaseEvent(QMouseEvent *)));
connect(w, SIGNAL(mouseDoubleClickEvent(QMouseEvent*)), this, SLOT(canvasMouseDoubleClickEvent(QMouseEvent * ))); connect(w, SIGNAL(mouseDoubleClickEvent(QMouseEvent *)), this, SLOT(canvasMouseDoubleClickEvent(QMouseEvent *)));
connect(w, SIGNAL(wheelEvent(QWheelEvent * )), this, SLOT(canvasWheelEvent(QWheelEvent * ))); connect(w, SIGNAL(wheelEvent(QWheelEvent *)), this, SLOT(canvasWheelEvent(QWheelEvent *)));
connect(w, SIGNAL(leaveEvent(QEvent * )), this, SLOT(canvasLeaveEvent(QEvent * ))); connect(w, SIGNAL(leaveEvent(QEvent *)), this, SLOT(canvasLeaveEvent(QEvent *)));
connect(w, SIGNAL(keyPressEvent(QKeyEvent * )), this, SLOT(canvasKeyPressEvent(QKeyEvent * ))); connect(w, SIGNAL(keyPressEvent(QKeyEvent *)), this, SLOT(canvasKeyPressEvent(QKeyEvent *)));
w->grabGesture(Qt::TapAndHoldGesture); w->grabGesture(Qt::TapAndHoldGesture);
w->grabGesture(Qt::PanGesture); w->grabGesture(Qt::PanGesture);
w->grabGesture(Qt::PinchGesture); w->grabGesture(Qt::PinchGesture);
@@ -335,15 +334,15 @@ void Graphic::procGesture(QGesture * g) {
switch (g->gestureType()) { switch (g->gestureType()) {
case Qt::PanGesture: { case Qt::PanGesture: {
if (need_mouse_pan) break; if (need_mouse_pan) break;
QPanGesture * pg = (QPanGesture*)g; QPanGesture * pg = (QPanGesture *)g;
QPointF dp = -pg->delta(); QPointF dp = -pg->delta();
dp.rx() /= getScaleX(); dp.rx() /= getScaleX();
dp.ry() /= getScaleY(); dp.ry() /= getScaleY();
selrect.translate(dp); selrect.translate(dp);
totalUpdate(); totalUpdate();
} break; } break;
case Qt::PinchGesture: { case Qt::PinchGesture: {
QPinchGesture * pg = (QPinchGesture*)g; QPinchGesture * pg = (QPinchGesture *)g;
Qt::KeyboardModifiers km = Qt::NoModifier; Qt::KeyboardModifiers km = Qt::NoModifier;
if (gesture_angle <= 20.) km = Qt::ControlModifier; if (gesture_angle <= 20.) km = Qt::ControlModifier;
if (gesture_angle >= 70.) km = Qt::ShiftModifier; if (gesture_angle >= 70.) km = Qt::ShiftModifier;
@@ -351,33 +350,33 @@ void Graphic::procGesture(QGesture * g) {
if (!fullscr) cp = mapFromGlobal(cp); if (!fullscr) cp = mapFromGlobal(cp);
procZoom(cp, (pg->scaleFactor() - 1.) * 500., km); procZoom(cp, (pg->scaleFactor() - 1.) * 500., km);
totalUpdate(); totalUpdate();
} break; } break;
case Qt::TapAndHoldGesture: { case Qt::TapAndHoldGesture: {
QTapAndHoldGesture * pg = (QTapAndHoldGesture*)g; QTapAndHoldGesture * pg = (QTapAndHoldGesture *)g;
if (pg->state() == Qt::GestureStarted) if (pg->state() == Qt::GestureStarted)
QMetaObject::invokeMethod(this, [this](){showMenu();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
} break; this,
default: [this]() { showMenu(); },
break; Qt::QueuedConnection);
} break;
default: break;
} }
} }
void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km) { 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 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(); double px = view_center.x() - gridborder.x() - margins_.left(), py = hei - view_center.y() + margins_.height();
px = px / wid * selrect.width() + selrect.x(); px = px / wid * selrect.width() + selrect.x();
py = py / hei * selrect.height() + selrect.y(); py = py / hei * selrect.height() + selrect.y();
scl = 1. - dzoom / 500.; scl = 1. - dzoom / 500.;
if (km == Qt::NoModifier) if (km == Qt::NoModifier)
selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl); selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl);
else { else {
if (km == Qt::ControlModifier) if (km == Qt::ControlModifier) selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height());
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);
if (km == Qt::ShiftModifier) if (km == Qt::AltModifier) selrect.translate((dzoom > 0. ? 1. : -1.) * selrect.width() / 2., 0.);
selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
if (km == Qt::AltModifier)
selrect.translate((dzoom > 0. ? 1. : -1.) * selrect.width() / 2., 0.);
} }
} }
@@ -392,23 +391,22 @@ void Graphic::totalUpdate() {
void Graphic::canvasPaintEvent() { void Graphic::canvasPaintEvent() {
if (is_lines_update) return; if (is_lines_update) return;
int wid = canvas->width (),hei = canvas->height(); int wid = canvas->width(), hei = canvas->height();
if (canvas->isHidden() || wid <= 1 || hei <= 1) return; if (canvas->isHidden() || wid <= 1 || hei <= 1) return;
if (!buffer.isNull()) { if (!buffer.isNull()) {
if (lastw != wid || lasth != hei) if (lastw != wid || lasth != hei) buffer = QPixmap();
buffer = QPixmap();
} }
if (buffer.isNull()) { if (buffer.isNull()) {
#if QT_VERSION_MAJOR >= 5 #if QT_VERSION_MAJOR >= 5
const qreal dpr = canvas->devicePixelRatio(); const qreal dpr = canvas->devicePixelRatio();
buffer = QPixmap(canvas->size() * dpr); buffer = QPixmap(canvas->size() * dpr);
buffer.setDevicePixelRatio(dpr); buffer.setDevicePixelRatio(dpr);
#else #else
buffer = QPixmap(canvas->size()); buffer = QPixmap(canvas->size());
#endif #endif
} }
lastw = wid; lastw = wid;
lasth = hei; lasth = hei;
font_sz = fontMetrics().size(0, "0"); font_sz = fontMetrics().size(0, "0");
font_sz.setHeight(font_sz.height() * 1.); font_sz.setHeight(font_sz.height() * 1.);
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
@@ -452,13 +450,14 @@ void Graphic::canvasPaintEvent() {
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y())); painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
emit beforeGraphicPaintEvent(painter); emit beforeGraphicPaintEvent(painter);
painter->setClipping(false); painter->setClipping(false);
if (grid) if (grid) drawGrid();
drawGrid();
p.setRenderHint(QPainter::Antialiasing, aalias); p.setRenderHint(QPainter::Antialiasing, aalias);
#ifdef HAS_GL #ifdef HAS_GL
if (isOGL && !m_fakeGL) { if (isOGL && !m_fakeGL) {
if (aalias) glEnable(GL_MULTISAMPLE); if (aalias)
else glDisable(GL_MULTISAMPLE); glEnable(GL_MULTISAMPLE);
else
glDisable(GL_MULTISAMPLE);
} }
#endif #endif
fp_size.clear(); fp_size.clear();
@@ -476,8 +475,8 @@ void Graphic::canvasPaintEvent() {
void Graphic::canvasMouseMoveEvent(QMouseEvent * e) { void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
isHover = true; isHover = true;
curpos = e->pos(); curpos = e->pos();
curpos_r = canvas2real(curpos); curpos_r = canvas2real(curpos);
QPointF dp; QPointF dp;
QString cursorstr = tr("Cursor: ") + pointCoords(curpos_r); QString cursorstr = tr("Cursor: ") + pointCoords(curpos_r);
@@ -491,38 +490,34 @@ void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
if (gestures) { if (gestures) {
if (!need_mouse_pan) return; if (!need_mouse_pan) return;
curaction = gaMove; curaction = gaMove;
} else } else if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton)
if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton) return; return;
switch (curaction) { switch (curaction) {
case gaZoomInRect: case gaZoomInRect:
ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " + ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " + pointCoords(curpos_r) + ", " + tr("Size") + ": " +
pointCoords(curpos_r) + ", " + tr("Size") + ": " + pointCoords(absPoint(curpos_r - startpos_r))); pointCoords(absPoint(curpos_r - startpos_r)));
repaintCanvas(true); repaintCanvas(true);
break; break;
case gaZoomRangeX: case gaZoomRangeX:
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) + ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) + " -> " + QString::number(curpos_r.x(), 'f', 3) +
" -> " + QString::number(curpos_r.x(), 'f', 3) + ", " + tr("Length") + ": " + ", " + tr("Length") + ": " + QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3)); repaintCanvas(true);
repaintCanvas(true);
break; break;
case gaZoomRangeY: case gaZoomRangeY:
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) + ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) + " -> " + QString::number(curpos_r.y(), 'f', 3) +
" -> " + QString::number(curpos_r.y(), 'f', 3) + ", " + tr("Length") + ": " + ", " + tr("Length") + ": " + QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3)); repaintCanvas(true);
repaintCanvas(true);
break; break;
case gaMove: case gaMove:
dp = e->pos() - prevpos; dp = e->pos() - prevpos;
dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw); dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw);
dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5); dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5);
if (e->modifiers() == Qt::ControlModifier) if (e->modifiers() == Qt::ControlModifier) dp.setY(0.);
dp.setY(0.); if (e->modifiers() == Qt::ShiftModifier) dp.setX(0.);
if (e->modifiers() == Qt::ShiftModifier) selrect.translate(dp);
dp.setX(0.); totalUpdate();
selrect.translate(dp);
totalUpdate();
break; break;
default: break; default: break;
} }
prevpos = e->pos(); prevpos = e->pos();
} }
@@ -533,14 +528,14 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) {
if (!navigation) return; if (!navigation) return;
if (gestures && !need_mouse_pan) return; if (gestures && !need_mouse_pan) return;
setGuidesCursor(); setGuidesCursor();
prevpos = e->pos(); prevpos = e->pos();
startpos = prevpos; startpos = prevpos;
startpos_r = canvas2real(startpos); startpos_r = canvas2real(startpos);
if (cancel || gestures) return; if (cancel || gestures) return;
if (e->button() == QT_MID_BUTTON) curaction = gaMove; if (e->button() == QT_MID_BUTTON) curaction = gaMove;
if (e->button() == Qt::RightButton) { if (e->button() == Qt::RightButton) {
if (bufferActive) { if (bufferActive) {
curpos = startpos; curpos = startpos;
curpos_r = canvas2real(curpos); curpos_r = canvas2real(curpos);
repaintCanvas(true); repaintCanvas(true);
swapToNormal(); swapToNormal();
@@ -553,16 +548,17 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) {
} }
} }
if (e->button() == Qt::LeftButton) { if (e->button() == Qt::LeftButton) {
if (e->modifiers() == Qt::ControlModifier) curaction = gaZoomRangeX; if (e->modifiers() == Qt::ControlModifier)
else if (e->modifiers() == Qt::ShiftModifier) curaction = gaZoomRangeY; curaction = gaZoomRangeX;
else curaction = gaZoomInRect; else if (e->modifiers() == Qt::ShiftModifier)
curaction = gaZoomRangeY;
else
curaction = gaZoomInRect;
switch (curaction) { switch (curaction) {
case gaZoomInRect: case gaZoomInRect:
case gaZoomRangeX: case gaZoomRangeX:
case gaZoomRangeY: case gaZoomRangeY: swapToBuffer(); break;
swapToBuffer(); default: break;
break;
default: break;
} }
} }
setCurrentAction(curaction); setCurrentAction(curaction);
@@ -588,24 +584,24 @@ void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) {
} }
if (e->button() == Qt::LeftButton && (e->buttons() & Qt::RightButton) != Qt::RightButton) { if (e->button() == Qt::LeftButton && (e->buttons() & Qt::RightButton) != Qt::RightButton) {
if (curpos != startpos) { if (curpos != startpos) {
tlp = canvas2real(sr.topLeft()); tlp = canvas2real(sr.topLeft());
brp = canvas2real(sr.bottomRight()); brp = canvas2real(sr.bottomRight());
isFit = false; isFit = false;
switch (curaction) { switch (curaction) {
case gaZoomInRect: case gaZoomInRect:
if (sr.width() <= 1 || sr.height() <= 1) break; if (sr.width() <= 1 || sr.height() <= 1) break;
selrect.setCoords(tlp.x(), brp.y(), brp.x(), tlp.y()); selrect.setCoords(tlp.x(), brp.y(), brp.x(), tlp.y());
setRectToLines(); setRectToLines();
break; break;
case gaZoomRangeX: case gaZoomRangeX:
if (sr.width() <= 1) break; if (sr.width() <= 1) break;
findGraphicsRect(tlp.x(), brp.x()); findGraphicsRect(tlp.x(), brp.x());
break; break;
case gaZoomRangeY: case gaZoomRangeY:
if (sr.height() <= 1) break; if (sr.height() <= 1) break;
findGraphicsRect(0., 0., brp.y(), tlp.y()); findGraphicsRect(0., 0., brp.y(), tlp.y());
break; break;
default: return; default: return;
} }
} }
swapToNormal(); swapToNormal();
@@ -617,7 +613,7 @@ void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) {
} }
void Graphic::canvasMouseDoubleClickEvent(QMouseEvent * ) { void Graphic::canvasMouseDoubleClickEvent(QMouseEvent *) {
if (!navigation) return; if (!navigation) return;
autofit(); autofit();
} }
@@ -641,11 +637,15 @@ void Graphic::canvasWheelEvent(QWheelEvent * e) {
void Graphic::zoom(float factor) { 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 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; double px = wid / 2, py = hei / 2;
px = px / wid * selrect.width() + selrect.x(); px = px / wid * selrect.width() + selrect.x();
py = py / hei * selrect.height() + selrect.y(); 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); selrect.setRect(px - (px - selrect.x()) * factor,
py - (py - selrect.y()) * factor,
selrect.width() * factor,
selrect.height() * factor);
isFit = false; isFit = false;
update(true); update(true);
setRectToLines(); setRectToLines();
@@ -653,12 +653,14 @@ void Graphic::zoom(float factor) {
void Graphic::fullscreen() { void Graphic::fullscreen() {
if (fullscr) leaveFullscreen(); if (fullscr)
else enterFullscreen(); leaveFullscreen();
else
enterFullscreen();
} }
void Graphic::canvasLeaveEvent(QEvent * ) { void Graphic::canvasLeaveEvent(QEvent *) {
isHover = false; isHover = false;
if (guides) update(true); if (guides) update(true);
ui->status->setText(tr("Cursor") + ": ( ; )"); ui->status->setText(tr("Cursor") + ": ( ; )");
@@ -668,8 +670,8 @@ void Graphic::canvasLeaveEvent(QEvent * ) {
void Graphic::canvasKeyPressEvent(QKeyEvent * e) { void Graphic::canvasKeyPressEvent(QKeyEvent * e) {
switch (e->key()) { switch (e->key()) {
case Qt::Key_Escape: leaveFullscreen(); case Qt::Key_Escape: leaveFullscreen();
default: break; default: break;
}; };
} }
@@ -680,7 +682,7 @@ void Graphic::clear() {
graphics[i].polyline_pause.clear(); graphics[i].polyline_pause.clear();
graphics[i]._lod.clear(); graphics[i]._lod.clear();
graphics[i]._lod_pause.clear(); graphics[i]._lod_pause.clear();
graphics[i].max_x = 0.; graphics[i].max_x = 0.;
graphics[i].cvrect = QRectF(); graphics[i].cvrect = QRectF();
} }
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit) on_graphic_buttonAutofit_clicked();
@@ -725,8 +727,8 @@ void Graphic::setHistorySize(double val) {
QPolygonF & pol(graphics[i].polyline); QPolygonF & pol(graphics[i].polyline);
if (pol.isEmpty() || history <= 0.) continue; if (pol.isEmpty() || history <= 0.) continue;
graphics[i].cvrect = QRectF(); graphics[i].cvrect = QRectF();
x = pol.back().x() - history; x = pol.back().x() - history;
for (int j = pol.size() - 2; j >= 0 ; --j) for (int j = pol.size() - 2; j >= 0; --j)
if (pol[j].x() < x) { if (pol[j].x() < x) {
pol.erase(pol.begin(), pol.begin() + j); pol.erase(pol.begin(), pol.begin() + j);
break; break;
@@ -813,8 +815,8 @@ void Graphic::setButtons(Graphic::Buttons b) {
ui->graphic_buttonClose->setVisible(b.testFlag(Close)); ui->graphic_buttonClose->setVisible(b.testFlag(Close));
ui->graphic_checkPause->setVisible(b.testFlag(Pause)); ui->graphic_checkPause->setVisible(b.testFlag(Pause));
ui->graphic_buttonRecord->setVisible(b.testFlag(Record)); ui->graphic_buttonRecord->setVisible(b.testFlag(Record));
if (ui->graphic_buttonAutofit ->isVisible() || ui->graphic_checkGrid ->isVisible() || ui->graphic_checkGuides->isVisible() || if (ui->graphic_buttonAutofit->isVisible() || ui->graphic_checkGrid->isVisible() || ui->graphic_checkGuides->isVisible() ||
ui->graphic_buttonConfigure->isVisible() || ui->graphic_buttonSave->isVisible() || ui->graphic_checkPause ->isVisible()) ui->graphic_buttonConfigure->isVisible() || ui->graphic_buttonSave->isVisible() || ui->graphic_checkPause->isVisible())
ui->verticalSpacer->changeSize(0, 30, QSizePolicy::Preferred, QSizePolicy::Preferred); ui->verticalSpacer->changeSize(0, 30, QSizePolicy::Preferred, QSizePolicy::Preferred);
else else
ui->verticalSpacer->changeSize(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred); ui->verticalSpacer->changeSize(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred);
@@ -830,13 +832,13 @@ void Graphic::setButtonsPosition(Graphic::Alignment a) {
return; return;
#endif #endif
switch (a) { switch (a) {
case Graphic::Left: case Graphic::Left:
ui->widgetLeft->setLayout(ui->layoutButtons); ui->widgetLeft->setLayout(ui->layoutButtons);
ui->widgetLeft->show(); ui->widgetLeft->show();
break; break;
case Graphic::Right: case Graphic::Right:
ui->widgetRight->setLayout(ui->layoutButtons); ui->widgetRight->setLayout(ui->layoutButtons);
ui->widgetRight->show(); ui->widgetRight->show();
break; break;
} }
} }
@@ -862,7 +864,7 @@ void Graphic::addPoints(const QPolygonF & pts, int graphic, bool update_) {
if (graphic >= graphics.size() || graphic < 0 || pts.isEmpty()) return; if (graphic >= graphics.size() || graphic < 0 || pts.isEmpty()) return;
GraphicType & t(graphics[graphic]); GraphicType & t(graphics[graphic]);
if (!t.cvrect.isNull() && !pause_) { if (!t.cvrect.isNull() && !pause_) {
for(const QPointF & p : pts) { for (const QPointF & p: pts) {
if (t.cvrect.top() < p.y()) t.cvrect.setTop(p.y()); 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.bottom() > p.y()) t.cvrect.setBottom(p.y());
if (t.cvrect.right() < p.x()) t.cvrect.setRight(p.x()); if (t.cvrect.right() < p.x()) t.cvrect.setRight(p.x());
@@ -870,7 +872,8 @@ void Graphic::addPoints(const QPolygonF & pts, int graphic, bool update_) {
} }
} }
if (t.polyline.size() == 0) t.max_x = pts.at(0).x(); if (t.polyline.size() == 0) t.max_x = pts.at(0).x();
for(const QPointF & p : pts) if (t.max_x < p.x()) t.max_x = p.x(); for (const QPointF & p: pts)
if (t.max_x < p.x()) t.max_x = p.x();
t.polyline << pts; t.polyline << pts;
tick(graphic, true, update_); tick(graphic, true, update_);
} }
@@ -881,7 +884,8 @@ void Graphic::addPoints(const QVector<double> & pts, int graphic, bool update_)
ps.reserve(pts.size()); ps.reserve(pts.size());
double stx = 0; double stx = 0;
if (!graphics[curGraphic].polyline.isEmpty()) stx = graphics[curGraphic].max_x; if (!graphics[curGraphic].polyline.isEmpty()) stx = graphics[curGraphic].max_x;
for (int i=0; i<pts.size(); ++i) ps << QPointF(stx + i*inc_x, pts[i]); for (int i = 0; i < pts.size(); ++i)
ps << QPointF(stx + i * inc_x, pts[i]);
addPoints(ps, graphic, update_); addPoints(ps, graphic, update_);
} }
@@ -899,13 +903,17 @@ void Graphic::setGraphicData(const QVector<QPointF> & g, int graphic, bool updat
} }
t.max_x = t.polyline[0].x(); t.max_x = t.polyline[0].x();
for (int i = 1; i < t.polyline.size(); ++i) for (int i = 1; i < t.polyline.size(); ++i)
if (t.max_x < t.polyline[i].x()) if (t.max_x < t.polyline[i].x()) t.max_x = t.polyline[i].x();
t.max_x = t.polyline[i].x();
tick(graphic, false, update_); tick(graphic, false, update_);
} }
void Graphic::setGraphicProperties(int graphic, const QString & name, const QColor& color, Qt::PenStyle style, double width, bool visible) { 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; if (graphic < 0 || graphic >= graphics.size()) return;
graphics[graphic].name = name; graphics[graphic].name = name;
graphics[graphic].pen.setColor(color); graphics[graphic].pen.setColor(color);
@@ -924,7 +932,7 @@ void Graphic::addGraphic(const QString & name, const QColor & color, Qt::PenStyl
void Graphic::setVisualRect(const QRectF & rect) { void Graphic::setVisualRect(const QRectF & rect) {
selrect = rect; selrect = rect;
isFit = false; isFit = false;
update(); update();
} }
@@ -962,7 +970,7 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
} }
ts << "\n"; ts << "\n";
bool has_data = true; bool has_data = true;
int ind = 0; int ind = 0;
QString line; QString line;
while (has_data) { while (has_data) {
has_data = false; has_data = false;
@@ -991,8 +999,7 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
} }
++ind; ++ind;
line += "\n"; line += "\n";
if (has_data) if (has_data) ts << line;
ts << line;
} }
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
} }
@@ -1000,14 +1007,14 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
void Graphic::setOpenGL(bool on) { void Graphic::setOpenGL(bool on) {
#ifdef HAS_GL #ifdef HAS_GL
isOGL = on; isOGL = on;
need_createGL = false; need_createGL = false;
if (on && !m_fakeGL) { if (on && !m_fakeGL) {
if (!canvas_gl) { if (!canvas_gl) {
if (!isVisible()) if (!isVisible())
need_createGL = true; need_createGL = true;
else { else {
//qDebug() << "create GL on setter"; // qDebug() << "create GL on setter";
canvas_gl = new UGLWidget(); canvas_gl = new UGLWidget();
ui->layoutCanvas->addWidget(canvas_gl); ui->layoutCanvas->addWidget(canvas_gl);
connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent())); connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent()));
@@ -1020,8 +1027,7 @@ void Graphic::setOpenGL(bool on) {
canvas = canvas_gl; canvas = canvas_gl;
} }
} else { } else {
if (canvas_gl) if (canvas_gl) canvas_gl->hide();
canvas_gl->hide();
ui->canvas_raster->show(); ui->canvas_raster->show();
canvas = ui->canvas_raster; canvas = ui->canvas_raster;
} }
@@ -1043,7 +1049,9 @@ void Graphic::setGraphicsCount(int arg, bool update) {
if (arg < 0) return; if (arg < 0) return;
while (graphics.size() < arg) { while (graphics.size() < arg) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #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))); graphics.append(
GraphicType(tr("y(x)"),
QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115)));
#else #else
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115))); graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115)));
#endif #endif
@@ -1064,7 +1072,7 @@ void Graphic::removeGraphic(int arg, bool update) {
} }
void Graphic::setCustomGridMarkFuncs(std::function<QString (double)> fx, std::function<QString (double)> fy) { void Graphic::setCustomGridMarkFuncs(std::function<QString(double)> fx, std::function<QString(double)> fy) {
func_gridMarkX = fx; func_gridMarkX = fx;
func_gridMarkY = fy; func_gridMarkY = fy;
} }
@@ -1073,12 +1081,12 @@ void Graphic::setCustomGridMarkFuncs(std::function<QString (double)> fx, std::fu
void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, double end_y) { void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, double end_y) {
double cx, cy, maxX, minX, maxY, minY, vx; double cx, cy, maxX, minX, maxY, minY, vx;
bool isRangeX = (start_x != end_x), isRangeY = (start_y != end_y); 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 can_fast = (start_x == 0 && end_x == 0 && start_y == 0 && end_y == 0);
bool anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY); bool anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY);
vx = -DBL_MAX; vx = -DBL_MAX;
minY = minX = DBL_MAX; minY = minX = DBL_MAX;
maxY = maxX = -DBL_MAX; maxY = maxX = -DBL_MAX;
foreach (const GraphicType & t, graphics) { foreach(const GraphicType & t, graphics) {
if (!t.visible) continue; if (!t.visible) continue;
if (vx < (pause_ ? t.max_x_pause : t.max_x)) vx = (pause_ ? t.max_x_pause : t.max_x); if (vx < (pause_ ? t.max_x_pause : t.max_x)) vx = (pause_ ? t.max_x_pause : t.max_x);
} }
@@ -1130,8 +1138,14 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
if (maxY < limit_.top()) maxY = limit_.top(); if (maxY < limit_.top()) maxY = limit_.top();
if (minX > maxX) qSwap<double>(minX, maxX); if (minX > maxX) qSwap<double>(minX, maxX);
if (minY > maxY) qSwap<double>(minY, maxY); 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>(minX - maxX) < 1E-60) {
if (qAbs<double>(minY - maxY) < 1E-60) {minY -= defaultRect().height()/2; maxY += defaultRect().height()/2;} 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 (only_expand_x) {
if (minX > eminx) minX = eminx; if (minX > eminx) minX = eminx;
if (maxX < emaxx) maxX = emaxx; if (maxX < emaxx) maxX = emaxx;
@@ -1140,16 +1154,20 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
if (minY > eminy) minY = eminy; if (minY > eminy) minY = eminy;
if (maxY < emaxy) maxY = emaxy; if (maxY < emaxy) maxY = emaxy;
} }
eminx = minX; emaxx = maxX; eminx = minX;
eminy = minY; emaxy = maxY; emaxx = maxX;
if (isRangeX) selrect.setRect(start_x, minY, end_x - start_x, maxY - minY); eminy = minY;
else if (isRangeY) selrect.setRect(minX, start_y, maxX - minX, end_y - start_y); emaxy = maxY;
else grect.setRect(minX, minY, maxX - minX, maxY - minY); 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(); grect = grect.normalized();
if (isFit) { if (isFit) {
if (visible_time > 0.) { if (visible_time > 0.) {
if (grect.width() > visible_time) if (grect.width() > visible_time) grect.setLeft(grect.right() - visible_time);
grect.setLeft(grect.right() - visible_time);
} }
selrect = grect; selrect = grect;
} }
@@ -1158,28 +1176,29 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
void Graphic::drawAction() { void Graphic::drawAction() {
int wid = canvas->width(), hei = canvas->height() - gridborder.y(), sx = startpos.x(), sy = startpos.y(), cx = curpos.x(), cy = curpos.y(); 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->setPen(selpen);
painter->setBrush(selbrush); painter->setBrush(selbrush);
switch (curaction) { switch (curaction) {
case gaZoomInRect: { case gaZoomInRect: {
QSizeF rsz = QRectF(startpos_r, curpos_r).normalized().size(); QSizeF rsz = QRectF(startpos_r, curpos_r).normalized().size();
painter->drawRect(QRect(startpos, curpos)); painter->drawRect(QRect(startpos, curpos));
fp_size = " x " + pointCoords(QPointF(rsz.width(), rsz.height())); fp_size = " x " + pointCoords(QPointF(rsz.width(), rsz.height()));
} break; } break;
case gaZoomRangeX: case gaZoomRangeX:
painter->drawLine(sx, hei, sx, 0); painter->drawLine(sx, hei, sx, 0);
painter->drawLine(cx, hei, cx, 0); painter->drawLine(cx, hei, cx, 0);
painter->fillRect(sx, 0, cx - sx, hei, selbrush); painter->fillRect(sx, 0, cx - sx, hei, selbrush);
fp_size = " x " + pointCoords(QPointF(qAbs(startpos_r.x() - curpos_r.x()), 0.), true, false); fp_size = " x " + pointCoords(QPointF(qAbs(startpos_r.x() - curpos_r.x()), 0.), true, false);
break; break;
case gaZoomRangeY: case gaZoomRangeY:
painter->drawLine(gridborder.x(), sy, wid, sy); painter->drawLine(gridborder.x(), sy, wid, sy);
painter->drawLine(gridborder.x(), cy, wid, cy); painter->drawLine(gridborder.x(), cy, wid, cy);
painter->fillRect(gridborder.x(), sy, wid - gridborder.x(), cy - sy, selbrush); 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); fp_size = " x " + pointCoords(QPointF(0., qAbs(startpos_r.y() - curpos_r.y())), false, true);
break; break;
default: break; default: break;
} }
} }
@@ -1192,12 +1211,14 @@ void Graphic::drawGrid() {
QPair<QString, QString> str; QPair<QString, QString> str;
range = selrect.bottom() - selrect.top(); range = selrect.bottom() - selrect.top();
if (grad_y == Graphic::Auto) step = splitRange(range, hei / gridy / font_sz.height() / 1.4); if (grad_y == Graphic::Auto)
else step = gridy; step = splitRange(range, hei / gridy / font_sz.height() / 1.4);
else
step = gridy;
start = roundTo(canvas2realY(-hei), step) - step; start = roundTo(canvas2realY(-hei), step) - step;
py = start + step; py = start + step;
cy = 0; cy = 0;
cx = gbx - 5; cx = gbx - 5;
grid_pen.setWidth(qMax<int>(qMax<int>(qRound(thick / 1.4), 1), grid_pen.width())); grid_pen.setWidth(qMax<int>(qMax<int>(qRound(thick / 1.4), 1), grid_pen.width()));
#if QT_VERSION_MAJOR >= 5 #if QT_VERSION_MAJOR >= 5
grid_pen.setCosmetic(true); grid_pen.setCosmetic(true);
@@ -1257,10 +1278,12 @@ void Graphic::drawGrid() {
range = selrect.right() - selrect.left(); range = selrect.right() - selrect.left();
QString df; QString df;
if (axis_type_x == Graphic::Numeric) { if (axis_type_x == Graphic::Numeric) {
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4); if (grad_x == Graphic::Auto)
else step = gridx; step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
else
step = gridx;
start = roundTo(canvas2realX(right), step); start = roundTo(canvas2realX(right), step);
px = start + step; px = start + step;
if (step > 0.) { if (step > 0.) {
cnt = 1000; cnt = 1000;
while (cnt-- > 0) { while (cnt-- > 0) {
@@ -1300,10 +1323,12 @@ void Graphic::drawGrid() {
} else { } else {
int dt_add[DateComponentCount]; int dt_add[DateComponentCount];
int dt_add_lo[DateComponentCount]; int dt_add_lo[DateComponentCount];
for (int i = 0; i < DateComponentCount; ++i) dt_add_lo[i] = dt_add[i] = 0; for (int i = 0; i < DateComponentCount; ++i)
dt_add_lo[i] = dt_add[i] = 0;
DateFormats formats; DateFormats formats;
step = splitRangeDate(range, wid / gridx / font_sz.width() / 1.5, formats, dt_add); step = splitRangeDate(range, wid / gridx / font_sz.width() / 1.5, formats, dt_add);
for (int i = 0; i < DateComponentCount - 1; ++i) dt_add_lo[i + 1] = dt_add[i]; for (int i = 0; i < DateComponentCount - 1; ++i)
dt_add_lo[i + 1] = dt_add[i];
bool is_years = formats.center.isEmpty(); bool is_years = formats.center.isEmpty();
if (step > 0.) { if (step > 0.) {
int up_y = cy - font_sz.height() * 2; int up_y = cy - font_sz.height() * 2;
@@ -1312,7 +1337,7 @@ void Graphic::drawGrid() {
int ddx = 0, pcx = 0; int ddx = 0, pcx = 0;
QDateTime cd = QDateTime::fromMSecsSinceEpoch(canvas2realX(gbx) * grid_numbers_x), cdp, cdc, cdl, cdlp; QDateTime cd = QDateTime::fromMSecsSinceEpoch(canvas2realX(gbx) * grid_numbers_x), cdp, cdc, cdl, cdlp;
QString ds; QString ds;
//qDebug() << step << range << int(wid / gridx / font_sz.width() * 1.4) << cd; // qDebug() << step << range << int(wid / gridx / font_sz.width() * 1.4) << cd;
if (!is_years) { if (!is_years) {
roundDateTime(cd, dt_add); roundDateTime(cd, dt_add);
cdp = cdl = cdlp = cd; cdp = cdl = cdlp = cd;
@@ -1322,13 +1347,13 @@ void Graphic::drawGrid() {
cd.setTime(QTime(0, 0, 0)); cd.setTime(QTime(0, 0, 0));
cd.setDate(QDate(roundTo(cd.date().year(), dt_add[6]) - dt_add[6], 1, 1)); cd.setDate(QDate(roundTo(cd.date().year(), dt_add[6]) - dt_add[6], 1, 1));
} }
//qDebug() << cd << cur_scl[0] << cur_scl[1] << cur_scl[2] << cur_scl[3] << cur_scl[4] << cur_scl[5] << cur_scl[6]; // qDebug() << cd << cur_scl[0] << cur_scl[1] << cur_scl[2] << cur_scl[3] << cur_scl[4] << cur_scl[5] << cur_scl[6];
struct Anchor { struct Anchor {
int x_start, x_end; int x_start, x_end;
QDateTime date; QDateTime date;
}; };
QVector<Anchor> areas_ce, areas_lo; QVector<Anchor> areas_ce, areas_lo;
cnt = 1000; cnt = 1000;
int area_start = gbx, area_start_lo = gbx; int area_start = gbx, area_start_lo = gbx;
pcx = real2canvasX(cd.toMSecsSinceEpoch() / grid_numbers_x); pcx = real2canvasX(cd.toMSecsSinceEpoch() / grid_numbers_x);
while (cnt-- > 0) { while (cnt-- > 0) {
@@ -1341,16 +1366,16 @@ void Graphic::drawGrid() {
if (cx < gbx) continue; if (cx < gbx) continue;
if (cdp != cdc) { if (cdp != cdc) {
int cxc = real2canvasX(cdc.toMSecsSinceEpoch() / grid_numbers_x); int cxc = real2canvasX(cdc.toMSecsSinceEpoch() / grid_numbers_x);
//qDebug() << cx << cxc << ddx << pcx; // qDebug() << cx << cxc << ddx << pcx;
if ((qAbs(cxc - cx) < ddx) && (cx != cxc)) need_text = false; if ((qAbs(cxc - cx) < ddx) && (cx != cxc)) need_text = false;
areas_ce << Anchor{area_start, qMin(cxc, right), cdp}; areas_ce << Anchor{area_start, qMin(cxc, right), cdp};
area_start = areas_ce.back().x_end; area_start = areas_ce.back().x_end;
cd = cdl = cdp = cdc; cd = cdl = cdp = cdc;
cx = cxc; cx = cxc;
roundDateTime(cdl, dt_add_lo); roundDateTime(cdl, dt_add_lo);
if (cdlp != cdl) { if (cdlp != cdl) {
areas_lo << Anchor{area_start_lo, qMin(cxc, right), cdlp}; areas_lo << Anchor{area_start_lo, qMin(cxc, right), cdlp};
cdlp = cdl; cdlp = cdl;
area_start_lo = areas_lo.back().x_end; area_start_lo = areas_lo.back().x_end;
} }
} else { } else {
@@ -1372,11 +1397,9 @@ void Graphic::drawGrid() {
} }
} }
if (!is_years) { if (!is_years) {
if (area_start < right) if (area_start < right) areas_ce << Anchor{area_start, right, cdc};
areas_ce << Anchor{area_start, right, cdc}; if (area_start_lo < right) areas_lo << Anchor{area_start_lo, right, cdl};
if (area_start_lo < right) // qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date;
areas_lo << Anchor{area_start_lo, right, cdl};
//qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date;
painter->setPen(grid_pen); painter->setPen(grid_pen);
for (const auto & a: areas_ce) { for (const auto & a: areas_ce) {
painter->drawLine(a.x_start, hei + 5, a.x_start, ce_y); painter->drawLine(a.x_start, hei + 5, a.x_start, ce_y);
@@ -1389,12 +1412,12 @@ void Graphic::drawGrid() {
painter->setFont(nf); painter->setFont(nf);
auto pfm = painter->fontMetrics(); auto pfm = painter->fontMetrics();
for (const auto & a: areas_ce) { for (const auto & a: areas_ce) {
ds = a.date.toString(formats.center); ds = a.date.toString(formats.center);
auto str_rect = pfm.boundingRect(ds); auto str_rect = pfm.boundingRect(ds);
painter->drawText(a.x_start + (a.x_end - a.x_start - str_rect.width()) / 2, ce_y, ds); painter->drawText(a.x_start + (a.x_end - a.x_start - str_rect.width()) / 2, ce_y, ds);
} }
for (const auto & a: areas_lo) { for (const auto & a: areas_lo) {
ds = a.date.toString(formats.lower); ds = a.date.toString(formats.lower);
auto str_rect = pfm.boundingRect(ds); auto str_rect = pfm.boundingRect(ds);
painter->drawText(a.x_start + (a.x_end - a.x_start - str_rect.width()) / 2, lo_y, ds); painter->drawText(a.x_start + (a.x_end - a.x_start - str_rect.width()) / 2, lo_y, ds);
} }
@@ -1426,7 +1449,7 @@ QPair<QString, QString> Graphic::gridMark(double v) const {
v = 1.; v = 1.;
p += 1; p += 1;
} }
ret.first = QString::fromUtf8("%1·10").arg(v); ret.first = QString::fromUtf8("%1·10").arg(v);
ret.second = QString::number(p); ret.second = QString::number(p);
} else } else
ret.first = QString::number(v, 'g', 8); ret.first = QString::number(v, 'g', 8);
@@ -1437,31 +1460,30 @@ QPair<QString, QString> Graphic::gridMark(double v) const {
void Graphic::fillDateFormats() { void Graphic::fillDateFormats() {
date_formats.clear(); date_formats.clear();
QString tr_ms = tr("ms"), tr_s = tr("s"), tr_m = tr("m"), tr_h = tr("h"); QString tr_ms = tr("ms"), tr_s = tr("s"), tr_m = tr("m"), tr_h = tr("h");
auto trFunc = [&](const DateFormats & src)->DateFormats{ auto trFunc = [&](const DateFormats & src) -> DateFormats {
DateFormats ret; DateFormats ret;
ret.upper = QString(src.upper ).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h); ret.upper = QString(src.upper).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h);
ret.center = QString(src.center).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h); ret.center = QString(src.center).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h);
ret.lower = QString(src.lower ).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h); ret.lower = QString(src.lower).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h);
return ret; return ret;
}; };
date_formats << trFunc(DateFormats{"zzz '%1'", "h '%4' mm '%3' ss '%2'", "yyyy MMM dd(ddd)"}); date_formats << trFunc(DateFormats{"zzz '%1'", "h '%4' mm '%3' ss '%2'", "yyyy MMM dd(ddd)"});
date_formats << trFunc(DateFormats{"ss '%2'" , "h '%4' mm '%3'" , "yyyy MMM dd(ddd)"}); date_formats << trFunc(DateFormats{"ss '%2'", "h '%4' mm '%3'", "yyyy MMM dd(ddd)"});
date_formats << trFunc(DateFormats{"mm '%3'" , "h '%4'" , "yyyy MMM dd(ddd)"}); date_formats << trFunc(DateFormats{"mm '%3'", "h '%4'", "yyyy MMM dd(ddd)"});
date_formats << trFunc(DateFormats{"h '%4'" , "dd(ddd)" , "yyyy MMM" }); date_formats << trFunc(DateFormats{"h '%4'", "dd(ddd)", "yyyy MMM"});
date_formats << trFunc(DateFormats{"dd(ddd)" , "MMM" , "yyyy" }); date_formats << trFunc(DateFormats{"dd(ddd)", "MMM", "yyyy"});
date_formats << trFunc(DateFormats{"MMM" , "yyyy" , "" }); date_formats << trFunc(DateFormats{"MMM", "yyyy", ""});
date_formats << trFunc(DateFormats{"yyyy" , "" , "" }); date_formats << trFunc(DateFormats{"yyyy", "", ""});
} }
void Graphic::drawGraphics() { void Graphic::drawGraphics() {
if (isHover) if (isHover) ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
QPointF srp = -selrect.topLeft(); QPointF srp = -selrect.topLeft();
double sclx, scly, wid = canvas->width(), hei = canvas->height(); double sclx, scly, wid = canvas->width(), hei = canvas->height();
int cwid = (wid - gridborder.x() - margins_.left() - margins_.width()); int cwid = (wid - gridborder.x() - margins_.left() - margins_.width());
sclx = cwid / selrect.width(); sclx = cwid / selrect.width();
scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height(); scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height();
painter->setClipping(true); painter->setClipping(true);
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y())); painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
painter->translate(gridborder.x() + margins_.left(), hei - gridborder.y() - margins_.top()); painter->translate(gridborder.x() + margins_.left(), hei - gridborder.y() - margins_.top());
@@ -1478,23 +1500,23 @@ void Graphic::drawGraphics() {
QVector<QPolygonF> & src_lod(pause_ ? t._lod_pause : t._lod); QVector<QPolygonF> & src_lod(pause_ ? t._lod_pause : t._lod);
int lod = 0; int lod = 0;
if (m_LODOptimization) { if (m_LODOptimization) {
int gpcnt = src_pol.size(); int gpcnt = src_pol.size();
qreal range = src_pol.back().x() - src_pol.front().x(); qreal range = src_pol.back().x() - src_pol.front().x();
qreal ppp = (gpcnt * selrect.width() / qMax(range, 1.E-9) / cwid); qreal ppp = (gpcnt * selrect.width() / qMax(range, 1.E-9) / cwid);
lod = qBound<int>(0, qFloor(log2(ppp) - 1), src_lod.size()); lod = qBound<int>(0, qFloor(log2(ppp) - 1), src_lod.size());
//qDebug() << "draw lod" << lod << src_lod[lod - 1].size(); // qDebug() << "draw lod" << lod << src_lod[lod - 1].size();
} }
t.last_lod = lod; t.last_lod = lod;
QPolygonF & rpol(lod == 0 ? src_pol : src_lod[lod - 1]); QPolygonF & rpol(lod == 0 ? src_pol : src_lod[lod - 1]);
int ind_start = -1, ind_end = -1; int ind_start = -1, ind_end = -1;
if (m_LODOptimization) { if (m_LODOptimization) {
qreal xs = selrect.left(), xe = selrect.right(), _offset = 2. / cwid * selrect.width(); qreal xs = selrect.left(), xe = selrect.right(), _offset = 2. / cwid * selrect.width();
xs -= _offset; xe += _offset; xs -= _offset;
xe += _offset;
for (int i = 0; i < rpol.size(); ++i) { for (int i = 0; i < rpol.size(); ++i) {
qreal px = rpol[i].x(); qreal px = rpol[i].x();
if (px < xs) continue; if (px < xs) continue;
if (ind_start < 0) if (ind_start < 0) ind_start = qMax(0, i - 1);
ind_start = qMax(0, i - 1);
if (px > xe && ind_end < 0) { if (px > xe && ind_end < 0) {
ind_end = qMin(rpol.size(), i + 1); ind_end = qMin(rpol.size(), i + 1);
break; break;
@@ -1502,10 +1524,10 @@ void Graphic::drawGraphics() {
} }
if (ind_start < 0) ind_start = 0; if (ind_start < 0) ind_start = 0;
if (ind_end < 0) ind_end = rpol.size(); if (ind_end < 0) ind_end = rpol.size();
//qDebug() << "bound" << ind_start << ind_end << rpol.size(); // qDebug() << "bound" << ind_start << ind_end << rpol.size();
} else { } else {
ind_start = 0; ind_start = 0;
ind_end = rpol.size(); ind_end = rpol.size();
} }
int polsize = ind_end - ind_start; int polsize = ind_end - ind_start;
if (polsize > 0) { if (polsize > 0) {
@@ -1513,13 +1535,15 @@ void Graphic::drawGraphics() {
if (m_LODOptimization && polsize < rpol.size()) { if (m_LODOptimization && polsize < rpol.size()) {
cpol.resize(polsize); cpol.resize(polsize);
memcpy(cpol.data(), &(rpol[ind_start]), polsize * sizeof(QPointF)); memcpy(cpol.data(), &(rpol[ind_start]), polsize * sizeof(QPointF));
//qDebug() << "copy" << polsize; // qDebug() << "copy" << polsize;
} else { } else {
cpol = rpol; cpol = rpol;
} }
pen = t.pen; pen = t.pen;
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick); if (qRound(pen.widthF()) == pen.widthF())
else pen.setWidthF(pen.widthF()*thick); pen.setWidth(pen.width() * thick);
else
pen.setWidthF(pen.widthF() * thick);
pen.setCosmetic(true); pen.setCosmetic(true);
if (t.lines) { if (t.lines) {
painter->setPen(pen); painter->setPen(pen);
@@ -1530,8 +1554,10 @@ void Graphic::drawGraphics() {
painter->drawPolyline(mat.map(cpol)); painter->drawPolyline(mat.map(cpol));
} }
if (t.points) { if (t.points) {
if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick)); if (qRound(t.pointWidth) == t.pointWidth)
else pen.setWidthF(t.pointWidth*thick); pen.setWidth(qRound(t.pointWidth * thick));
else
pen.setWidthF(t.pointWidth * thick);
painter->setPen(pen); painter->setPen(pen);
painter->drawPoints(mat.map(cpol)); painter->drawPoints(mat.map(cpol));
} }
@@ -1549,9 +1575,9 @@ QString Graphic::pointCoords(QPointF point, bool x, bool y) {
else else
ret += ret +=
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
QDateTime::fromMSecsSinceEpoch(point.x()).toString(Qt::SystemLocaleShortDate); QDateTime::fromMSecsSinceEpoch(point.x()).toString(Qt::SystemLocaleShortDate);
#else #else
locale().toString(QDateTime::fromMSecsSinceEpoch(point.x()), QLocale::ShortFormat); locale().toString(QDateTime::fromMSecsSinceEpoch(point.x()), QLocale::ShortFormat);
#endif #endif
} }
if (y) { if (y) {
@@ -1575,11 +1601,11 @@ void Graphic::drawGuides() {
painter->resetTransform(); painter->resetTransform();
painter->setClipping(true); painter->setClipping(true);
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y())); painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
QPoint apos = curpos; QPoint apos = curpos;
QPointF rpos = canvas2real(apos); QPointF rpos = canvas2real(apos);
QString str; QString str;
str = pointCoords(rpos) + fp_size; str = pointCoords(rpos) + fp_size;
bool trace_found = false; bool trace_found = false;
auto trace_axis_func = [&](bool on_x, double cursor) { auto trace_axis_func = [&](bool on_x, double cursor) {
if (curTrace >= 0 && curTrace < graphics.size()) { if (curTrace >= 0 && curTrace < graphics.size()) {
auto & t(graphics[curTrace]); auto & t(graphics[curTrace]);
@@ -1594,13 +1620,13 @@ void Graphic::drawGuides() {
dist = qAbs<double>((on_x ? pol[i].x() : pol[i].y()) - cursor); dist = qAbs<double>((on_x ? pol[i].x() : pol[i].y()) - cursor);
if (min_dist > dist || min_dist < 0) { if (min_dist > dist || min_dist < 0) {
min_dist = dist; min_dist = dist;
index = i; index = i;
} }
} }
if (index >= 0) { if (index >= 0) {
rpos = pol[index]; rpos = pol[index];
apos = real2canvas(rpos).toPoint(); apos = real2canvas(rpos).toPoint();
str = pointCoords(pol[index]) + fp_size; str = pointCoords(pol[index]) + fp_size;
trace_found = true; trace_found = true;
emit graphicTraceEvent(curTrace, rpos); emit graphicTraceEvent(curTrace, rpos);
} }
@@ -1610,7 +1636,7 @@ void Graphic::drawGuides() {
auto trace_free_func = [&](QPointF cursor) { auto trace_free_func = [&](QPointF cursor) {
double min_dist = -1; double min_dist = -1;
int gr = -1, mag_dist = fontHeight(this) * 2; int gr = -1, mag_dist = fontHeight(this) * 2;
QPointF point, scale = getScale(), dp; QPointF point, scale = getScale(), dp;
for (int g = 0; g < graphics.size(); ++g) { for (int g = 0; g < graphics.size(); ++g) {
auto & t(graphics[g]); auto & t(graphics[g]);
if (t.visible) { if (t.visible) {
@@ -1627,34 +1653,27 @@ void Graphic::drawGuides() {
dist = QVector2D(dp).lengthSquared(); dist = QVector2D(dp).lengthSquared();
if (min_dist > dist || min_dist < 0) { if (min_dist > dist || min_dist < 0) {
min_dist = dist; min_dist = dist;
gr = g; gr = g;
rpos = point; rpos = point;
} }
} }
} }
} }
} }
if (gr >= 0) { if (gr >= 0) {
apos = real2canvas(rpos).toPoint(); apos = real2canvas(rpos).toPoint();
str = " " + graphics[gr].name + ": " + pointCoords(rpos) + fp_size; str = " " + graphics[gr].name + ": " + pointCoords(rpos) + fp_size;
trace_found = true; trace_found = true;
emit graphicTraceEvent(gr, rpos); emit graphicTraceEvent(gr, rpos);
} }
}; };
switch (floating_axis_type) { switch (floating_axis_type) {
case TraceXY: case TraceXY: trace_free_func(rpos); break;
trace_free_func(rpos); case TraceX: trace_axis_func(true, rpos.x()); break;
break; case TraceY: trace_axis_func(false, rpos.y()); break;
case TraceX:
trace_axis_func(true, rpos.x());
break;
case TraceY:
trace_axis_func(false, rpos.y());
break;
default: break; default: break;
} }
if (was_trace && !trace_found) if (was_trace && !trace_found) emit graphicTraceEvent(-1, QPointF());
emit graphicTraceEvent(-1, QPointF());
was_trace = trace_found; was_trace = trace_found;
painter->drawLine(0, apos.y(), wid, apos.y()); painter->drawLine(0, apos.y(), wid, apos.y());
painter->drawLine(apos.x(), 0, apos.x(), hei); painter->drawLine(apos.x(), 0, apos.x(), hei);
@@ -1678,7 +1697,7 @@ void Graphic::drawPause() {
painter->resetTransform(); painter->resetTransform();
painter->translate(canvas->width() - icon_pause_b.width() - 6, 6); painter->translate(canvas->width() - icon_pause_b.width() - 6, 6);
double o = (0.5 - pause_phase) * 2; double o = (0.5 - pause_phase) * 2;
painter->setOpacity(o*o); painter->setOpacity(o * o);
painter->drawImage(0, 0, icon_pause_b); painter->drawImage(0, 0, icon_pause_b);
painter->setOpacity(1.); painter->setOpacity(1.);
painter->drawImage(0, 0, icon_pause_f); painter->drawImage(0, 0, icon_pause_f);
@@ -1689,11 +1708,11 @@ void Graphic::drawPause() {
double roundToSteps(double value, const QVector<double> & steps) { double roundToSteps(double value, const QVector<double> & steps) {
double ret = value, min_err = -1.; double ret = value, min_err = -1.;
for (double v: steps) { for (double v: steps) {
double sv = qRound64(value / v) * v; double sv = qRound64(value / v) * v;
double err = qAbs<double>(value - sv); double err = qAbs<double>(value - sv);
if (min_err < 0 || min_err > err) { if (min_err < 0 || min_err > err) {
min_err = err; min_err = err;
ret = sv; ret = sv;
} }
} }
if (ret < steps[0]) ret = steps[0]; if (ret < steps[0]) ret = steps[0];
@@ -1706,7 +1725,7 @@ double roundToNearest(double value, const QVector<double> & values) {
double err = qAbs<double>(value - v); double err = qAbs<double>(value - v);
if (min_err < 0 || min_err > err) { if (min_err < 0 || min_err > err) {
min_err = err; min_err = err;
ret = v; ret = v;
} }
} }
if (ret < values[0]) ret = values[0]; if (ret < values[0]) ret = values[0];
@@ -1717,13 +1736,13 @@ double roundToNearest(double value, const QVector<double> & values) {
double Graphic::splitRange(double range, int count) { double Graphic::splitRange(double range, int count) {
double digits, step, tln; double digits, step, tln;
range = qAbs<double>(range); range = qAbs<double>(range);
tln = qFloor(qLn(range) / LN10); tln = qFloor(qLn(range) / LN10);
for (int i = 0; i <= 5; ++i) { for (int i = 0; i <= 5; ++i) {
digits = qPow(10., tln - i); digits = qPow(10., tln - i);
step = qRound(range / count / digits); step = qRound(range / count / digits);
if (step > 0.) { if (step > 0.) {
digits = qPow(10., tln - i - 1); digits = qPow(10., tln - i - 1);
step = qRound(range / count / digits); step = qRound(range / count / digits);
break; break;
} }
} }
@@ -1733,22 +1752,32 @@ double Graphic::splitRange(double range, int count) {
double Graphic::splitRangeDate(double range, int count, DateFormats & formats, int step[7]) { double Graphic::splitRangeDate(double range, int count, DateFormats & formats, int step[7]) {
static const qint64 static const qint64 to_sec = 1000LL, to_min = 1000LL * 60, to_hour = 1000LL * 60 * 60, to_day = 1000LL * 60 * 60 * 24,
to_sec = 1000LL, to_month = 1000LL * 60 * 60 * 24 * 30, to_year = 1000LL * 60 * 60 * 24 * 30 * 12;
to_min = 1000LL * 60, double ret = splitRange(range, count);
to_hour = 1000LL * 60 * 60,
to_day = 1000LL * 60 * 60 * 24,
to_month = 1000LL * 60 * 60 * 24 * 30,
to_year = 1000LL * 60 * 60 * 24 * 30 * 12;
double ret = splitRange(range, count);
int format_index = DateYears; int format_index = DateYears;
if (ret < to_sec / 1 ) {format_index = DateMSecs ; step[DateMSecs ] = qRound64(ret);} if (ret < to_sec / 1) {
else if (ret < to_min / 2 ) {format_index = DateSecs ; step[DateSecs ] = roundToNearest(ret / to_sec , {1, 2, 5, 10, 15, 20, 30});} format_index = DateMSecs;
else if (ret < to_hour ) {format_index = DateMinutes; step[DateMinutes] = roundToNearest(ret / to_min , {1, 2, 5, 10, 15, 20, 30});} step[DateMSecs] = qRound64(ret);
else if (ret < to_day ) {format_index = DateHours ; step[DateHours ] = roundToNearest(ret / to_hour , {1, 2, 3, 4, 6, 8, 12});} } else if (ret < to_min / 2) {
else if (ret < to_month / 1.6) {format_index = DateDays ; step[DateDays ] = roundToNearest(ret / to_day , {1, 2, 5, 10});} format_index = DateSecs;
else if (ret < to_year ) {format_index = DateMonths ; step[DateMonths ] = roundToNearest(ret / to_month, {1, 2, 3, 4, 6});} step[DateSecs] = roundToNearest(ret / to_sec, {1, 2, 5, 10, 15, 20, 30});
else {format_index = DateYears ; step[DateYears ] = qRound64(ret / to_year);} } else if (ret < to_hour) {
format_index = DateMinutes;
step[DateMinutes] = roundToNearest(ret / to_min, {1, 2, 5, 10, 15, 20, 30});
} else if (ret < to_day) {
format_index = DateHours;
step[DateHours] = roundToNearest(ret / to_hour, {1, 2, 3, 4, 6, 8, 12});
} else if (ret < to_month / 1.6) {
format_index = DateDays;
step[DateDays] = roundToNearest(ret / to_day, {1, 2, 5, 10});
} else if (ret < to_year) {
format_index = DateMonths;
step[DateMonths] = roundToNearest(ret / to_month, {1, 2, 3, 4, 6});
} else {
format_index = DateYears;
step[DateYears] = qRound64(ret / to_year);
}
formats = date_formats[format_index]; formats = date_formats[format_index];
return ret; return ret;
} }
@@ -1761,25 +1790,35 @@ double Graphic::roundTo(double value, double round_to) {
void Graphic::roundDateTime(QDateTime & dt, int * c) { void Graphic::roundDateTime(QDateTime & dt, int * c) {
QDate d(dt.date()); QTime t(dt.time()); QDate d(dt.date());
if (c[DateMSecs ] != 0) t.setHMS(t.hour(), t.minute(), t.second()); QTime t(dt.time());
if (c[DateSecs ] != 0) t.setHMS(t.hour(), t.minute(), 0); if (c[DateMSecs] != 0) t.setHMS(t.hour(), t.minute(), t.second());
if (c[DateSecs] != 0) t.setHMS(t.hour(), t.minute(), 0);
if (c[DateMinutes] != 0) t.setHMS(t.hour(), 0, 0); if (c[DateMinutes] != 0) t.setHMS(t.hour(), 0, 0);
if (c[DateHours ] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), d.day());} if (c[DateHours] != 0) {
if (c[DateDays ] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), 1);} t.setHMS(0, 0, 0);
if (c[DateMonths ] != 0 || c[DateYears] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), 1, 1);} d.setDate(d.year(), d.month(), d.day());
}
if (c[DateDays] != 0) {
t.setHMS(0, 0, 0);
d.setDate(d.year(), d.month(), 1);
}
if (c[DateMonths] != 0 || c[DateYears] != 0) {
t.setHMS(0, 0, 0);
d.setDate(d.year(), 1, 1);
}
dt = QDateTime(d, t); dt = QDateTime(d, t);
} }
void Graphic::addDateTime(QDateTime & dt, int * c, qint64 mul) { void Graphic::addDateTime(QDateTime & dt, int * c, qint64 mul) {
if (c[DateMSecs ] != 0) dt = dt.addMSecs (mul * c[DateMSecs ]); if (c[DateMSecs] != 0) dt = dt.addMSecs(mul * c[DateMSecs]);
if (c[DateSecs ] != 0) dt = dt.addSecs (mul * c[DateSecs ]); if (c[DateSecs] != 0) dt = dt.addSecs(mul * c[DateSecs]);
if (c[DateMinutes] != 0) dt = dt.addSecs (mul * c[DateMinutes] * 60); if (c[DateMinutes] != 0) dt = dt.addSecs(mul * c[DateMinutes] * 60);
if (c[DateHours ] != 0) dt = dt.addSecs (mul * c[DateHours ] * 60 * 60); if (c[DateHours] != 0) dt = dt.addSecs(mul * c[DateHours] * 60 * 60);
if (c[DateDays ] != 0) dt = dt.addDays (mul * c[DateDays ]); if (c[DateDays] != 0) dt = dt.addDays(mul * c[DateDays]);
if (c[DateMonths ] != 0) dt = dt.addMonths(mul * c[DateMonths ]); if (c[DateMonths] != 0) dt = dt.addMonths(mul * c[DateMonths]);
if (c[DateYears ] != 0) dt = dt.addYears (mul * c[DateYears ]); if (c[DateYears] != 0) dt = dt.addYears(mul * c[DateYears]);
} }
@@ -1813,7 +1852,7 @@ double Graphic::real2canvasY(double py) const {
QPolygonF Graphic::real2canvas(const QPolygonF & real_polygon) const { QPolygonF Graphic::real2canvas(const QPolygonF & real_polygon) const {
QPolygonF ret; QPolygonF ret;
for (int i=0; i<real_polygon.size(); ++i) for (int i = 0; i < real_polygon.size(); ++i)
ret << real2canvas(real_polygon[i]); ret << real2canvas(real_polygon[i]);
return ret; return ret;
} }
@@ -1821,7 +1860,7 @@ QPolygonF Graphic::real2canvas(const QPolygonF & real_polygon) const {
QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const { QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
QPolygonF ret; QPolygonF ret;
for (int i=0; i<canvas_polygon.size(); ++i) for (int i = 0; i < canvas_polygon.size(); ++i)
ret << canvas2real(canvas_polygon[i]); ret << canvas2real(canvas_polygon[i]);
return ret; return ret;
} }
@@ -1830,21 +1869,11 @@ QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
void Graphic::setCurrentAction(GraphicAction action) { void Graphic::setCurrentAction(GraphicAction action) {
curaction = action; curaction = action;
switch (action) { switch (action) {
case gaNone: case gaNone: setGuidesCursor(); break;
setGuidesCursor(); case gaZoomInRect: setCanvasCursor(Qt::CrossCursor); break;
break; case gaZoomRangeX: setCanvasCursor(Qt::SplitHCursor); break;
case gaZoomInRect: case gaZoomRangeY: setCanvasCursor(Qt::SplitVCursor); break;
setCanvasCursor(Qt::CrossCursor); case gaMove: setCanvasCursor(Qt::SizeAllCursor); break;
break;
case gaZoomRangeX:
setCanvasCursor(Qt::SplitHCursor);
break;
case gaZoomRangeY:
setCanvasCursor(Qt::SplitVCursor);
break;
case gaMove:
setCanvasCursor(Qt::SizeAllCursor);
break;
} }
} }
@@ -1852,8 +1881,7 @@ void Graphic::setCurrentAction(GraphicAction action) {
void Graphic::setCanvasCursor(QCursor cursor) { void Graphic::setCanvasCursor(QCursor cursor) {
ui->canvas_raster->setCursor(cursor); ui->canvas_raster->setCursor(cursor);
#ifdef HAS_GL #ifdef HAS_GL
if (canvas_gl) if (canvas_gl) canvas_gl->setCursor(cursor);
canvas_gl->setCursor(cursor);
#endif #endif
} }
@@ -1883,28 +1911,42 @@ void Graphic::swapToBuffer() {
void Graphic::setRectToLines() { void Graphic::setRectToLines() {
is_lines_update = true; is_lines_update = true;
if (line_x_min.isVisible() && line_x_max.isVisible() && line_y_min.isVisible() && line_y_max.isVisible()) { 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); 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 (!line_x_min.hasFocus()) {
if (isFit) line_x_min.setValue(grect.left()); if (isFit)
else line_x_min.setValue(selrect.left()); line_x_min.setValue(grect.left());
else
line_x_min.setValue(selrect.left());
} }
if (!line_x_max.hasFocus()) { if (!line_x_max.hasFocus()) {
if(isFit) line_x_max.setValue(grect.right()); if (isFit)
else line_x_max.setValue(selrect.right()); line_x_max.setValue(grect.right());
else
line_x_max.setValue(selrect.right());
} }
if (!line_y_min.hasFocus()) { if (!line_y_min.hasFocus()) {
if(isFit) line_y_min.setValue(grect.bottom()); if (isFit)
else line_y_min.setValue(selrect.bottom()); line_y_min.setValue(grect.bottom());
else
line_y_min.setValue(selrect.bottom());
} }
if (!line_y_max.hasFocus()) { if (!line_y_max.hasFocus()) {
if(isFit) line_y_max.setValue(grect.top()); if (isFit)
else line_y_max.setValue(selrect.top()); line_y_max.setValue(grect.top());
else
line_y_max.setValue(selrect.top());
} }
line_x_min.setDefaultText(QString::number(grect.left()).toUpper()); line_x_min.setDefaultText(QString::number(grect.left()).toUpper());
line_x_max.setDefaultText(QString::number(grect.right()).toUpper()); line_x_max.setDefaultText(QString::number(grect.right()).toUpper());
line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper()); line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper());
line_y_max.setDefaultText(QString::number(grect.top()).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); line_x_min.blockSignals(false);
line_x_max.blockSignals(false);
line_y_min.blockSignals(false);
line_y_max.blockSignals(false);
} }
is_lines_update = false; is_lines_update = false;
} }
@@ -1925,10 +1967,8 @@ void Graphic::tick(int index, bool slide, bool update_) {
/// TODO: [Graphic] fast autofit while addPoint(double y, ...) /// TODO: [Graphic] fast autofit while addPoint(double y, ...)
if (!t.cvrect.isNull()) { if (!t.cvrect.isNull()) {
QPointF fp(t.polyline.first()); QPointF fp(t.polyline.first());
if (qFuzzyCompare(t.cvrect.left(), fp.x()) || if (qFuzzyCompare(t.cvrect.left(), fp.x()) || qFuzzyCompare(t.cvrect.right(), fp.x()) ||
qFuzzyCompare(t.cvrect.right(), fp.x()) || qFuzzyCompare(t.cvrect.top(), fp.y()) || qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
qFuzzyCompare(t.cvrect.top(), fp.y()) ||
qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
t.cvrect = QRectF(); t.cvrect = QRectF();
} }
} }
@@ -1955,48 +1995,51 @@ void Graphic::calcLOD(int index) {
GraphicType & t(graphics[index]); GraphicType & t(graphics[index]);
t._lod.clear(); t._lod.clear();
int pcnt = t.polyline.size(); int pcnt = t.polyline.size();
//qDebug() << "calcLOD" << index; // qDebug() << "calcLOD" << index;
while (pcnt >= 10) { while (pcnt >= 10) {
QPolygonF & pl(t._lod.isEmpty() ? t.polyline : t._lod.back()); QPolygonF & pl(t._lod.isEmpty() ? t.polyline : t._lod.back());
t._lod.append(QPolygonF()); t._lod.append(QPolygonF());
QPolygonF & cl(t._lod.back()); QPolygonF & cl(t._lod.back());
cl << pl.front(); cl << pl.front();
int qcnt = (pl.size() + 1) / 4; int qcnt = (pl.size() + 1) / 4;
pcnt = qcnt * 2 + 2; pcnt = qcnt * 2 + 2;
int pc = 4; int pc = 4;
qreal mx[2] = {0., 0.}, my[2] = {0., 0.}, my_x[2] = {0., 0.}, px, py; qreal mx[2] = {0., 0.}, my[2] = {0., 0.}, my_x[2] = {0., 0.}, px, py;
for (int i = 0; i < qcnt; ++i) { for (int i = 0; i < qcnt; ++i) {
int j = i*4 + 1; int j = i * 4 + 1;
if (i == qcnt - 1) pc = pl.size() - j - 1; if (i == qcnt - 1) pc = pl.size() - j - 1;
mx[0] = mx[1] = my_x[0] = my_x[1] = pl[j].x(); my[0] = my[1] = pl[j].y(); mx[0] = mx[1] = my_x[0] = my_x[1] = pl[j].x();
my[0] = my[1] = pl[j].y();
for (int k = 1; k < pc; ++k) { for (int k = 1; k < pc; ++k) {
px = pl[j + k].x(); py = pl[j + k].y(); px = pl[j + k].x();
mx[0] = qMin(mx[0], px); mx[1] = qMax(mx[1], px); py = pl[j + k].y();
mx[0] = qMin(mx[0], px);
mx[1] = qMax(mx[1], px);
if (my[0] > py) { if (my[0] > py) {
my[0] = py; my[0] = py;
my_x[0] = px; my_x[0] = px;
} }
if (my[1] < py) { if (my[1] < py) {
my[1] = py; my[1] = py;
my_x[1] = px; my_x[1] = px;
} }
} }
qreal dx =(mx[1] - mx[0]) / 4., cx = (mx[1] + mx[0]) / 2.; qreal dx = (mx[1] - mx[0]) / 4., cx = (mx[1] + mx[0]) / 2.;
if (my_x[1] >= my_x[0]) if (my_x[1] >= my_x[0])
cl << QPointF(cx - dx, my[0]) << QPointF(cx + dx, my[1]); cl << QPointF(cx - dx, my[0]) << QPointF(cx + dx, my[1]);
else else
cl << QPointF(cx - dx, my[1]) << QPointF(cx + dx, my[0]); cl << QPointF(cx - dx, my[1]) << QPointF(cx + dx, my[0]);
} }
cl << pl.back(); cl << pl.back();
//qDebug() << "lod" << t._lod.size() << "->" << cl.size(); // qDebug() << "lod" << t._lod.size() << "->" << cl.size();
} }
} }
void Graphic::on_graphic_buttonAutofit_clicked() { void Graphic::on_graphic_buttonAutofit_clicked() {
isFit = true; isFit = true;
bool isEmpty = true; bool isEmpty = true;
foreach (const GraphicType & t, graphics) { foreach(const GraphicType & t, graphics) {
const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline); const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline);
if (!pol.isEmpty()) { if (!pol.isEmpty()) {
isEmpty = false; isEmpty = false;
@@ -2046,23 +2089,29 @@ void Graphic::on_graphic_buttonConfigure_clicked() {
grid_pen = QPen(conf->ui->colorGrid->color(), conf->ui->spinWidthGrid->value(), (Qt::PenStyle)conf->ui->comboStyleGrid->currentIndex()); grid_pen = QPen(conf->ui->colorGrid->color(), conf->ui->spinWidthGrid->value(), (Qt::PenStyle)conf->ui->comboStyleGrid->currentIndex());
back_color = conf->ui->colorBackground->color(); back_color = conf->ui->colorBackground->color();
text_color = conf->ui->colorText->color(); text_color = conf->ui->colorText->color();
grad_x = conf->ui->checkGridAutoX->isChecked() ? Auto : Fixed; grad_x = conf->ui->checkGridAutoX->isChecked() ? Auto : Fixed;
grad_y = conf->ui->checkGridAutoY->isChecked() ? Auto : Fixed; grad_y = conf->ui->checkGridAutoY->isChecked() ? Auto : Fixed;
gridx = conf->ui->spinGridStepX->value(); gridx = conf->ui->spinGridStepX->value();
gridy = conf->ui->spinGridStepY->value(); gridy = conf->ui->spinGridStepY->value();
setOpenGL(conf->ui->checkOGL->isChecked()); setOpenGL(conf->ui->checkOGL->isChecked());
setAntialiasing(conf->ui->checkAAlias->isChecked()); setAntialiasing(conf->ui->checkAAlias->isChecked());
setBorderInputsVisible(conf->ui->checkInputs->isChecked()); setBorderInputsVisible(conf->ui->checkInputs->isChecked());
setStatusVisible(conf->ui->checkStatus->isChecked()); setStatusVisible(conf->ui->checkStatus->isChecked());
setLegendVisible(conf->ui->checkLegend->isChecked()); setLegendVisible(conf->ui->checkLegend->isChecked());
setMargins(conf->ui->spinMarginL->value(), conf->ui->spinMarginR->value(), conf->ui->spinMarginT->value(), conf->ui->spinMarginB->value()); setMargins(conf->ui->spinMarginL->value(),
conf->ui->spinMarginR->value(),
conf->ui->spinMarginT->value(),
conf->ui->spinMarginB->value());
updateLegend(); updateLegend();
update(); update();
} }
void Graphic::on_graphic_buttonSave_clicked() { void Graphic::on_graphic_buttonSave_clicked() {
QString f = QFileDialog::getSaveFileName(this, tr("Save Image"), ppath, "PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)"); QString f = QFileDialog::getSaveFileName(this,
tr("Save Image"),
ppath,
"PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)");
if (f.isEmpty()) return; if (f.isEmpty()) return;
saveImage(f); saveImage(f);
} }
@@ -2072,7 +2121,8 @@ void Graphic::on_graphic_buttonExport_clicked() {
QString f = QFileDialog::getSaveFileName(this, tr("Export graphics"), ppath, "CSV(*.csv)"); QString f = QFileDialog::getSaveFileName(this, tr("Export graphics"), ppath, "CSV(*.csv)");
if (f.isEmpty()) return; if (f.isEmpty()) return;
QStringList items; QStringList items;
items << "." << ","; items << "."
<< ",";
bool ok; bool ok;
QString item = QInputDialog::getItem(this, tr("Select decimal point"), tr("Decimal point:"), items, 0, false, &ok); QString item = QInputDialog::getItem(this, tr("Select decimal point"), tr("Decimal point:"), items, 0, false, &ok);
if (ok && !item.isEmpty()) exportGraphics(f, item.front()); if (ok && !item.isEmpty()) exportGraphics(f, item.front());
@@ -2092,15 +2142,17 @@ void Graphic::on_graphic_buttonRecord_clicked(bool checked) {
qApp->setOverrideCursor(Qt::BusyCursor); qApp->setOverrideCursor(Qt::BusyCursor);
GifWriter gif_writer; GifWriter gif_writer;
int frame_delay = 10; int frame_delay = 10;
if (GifBegin(&gif_writer, f.toUtf8(), static_cast<uint32_t>(record_imgs.first().width()), if (GifBegin(&gif_writer,
static_cast<uint32_t>(record_imgs.first().height()), f.toUtf8(),
static_cast<uint32_t>(frame_delay))) { static_cast<uint32_t>(record_imgs.first().width()),
for (const QImage & im : record_imgs) { static_cast<uint32_t>(record_imgs.first().height()),
static_cast<uint32_t>(frame_delay))) {
for (const QImage & im: record_imgs) {
if (!GifWriteFrame(&gif_writer, if (!GifWriteFrame(&gif_writer,
im.convertToFormat(QImage::Format_RGBA8888).constBits(), im.convertToFormat(QImage::Format_RGBA8888).constBits(),
static_cast<uint32_t>(im.width()), static_cast<uint32_t>(im.width()),
static_cast<uint32_t>(im.height()), static_cast<uint32_t>(im.height()),
static_cast<uint32_t>(frame_delay))) { static_cast<uint32_t>(frame_delay))) {
GifEnd(&gif_writer); GifEnd(&gif_writer);
qDebug() << "GifWriteFrame ERROR"; qDebug() << "GifWriteFrame ERROR";
} }
@@ -2127,8 +2179,10 @@ void Graphic::updateLegend(bool es) {
pix.fill(back_color); pix.fill(back_color);
QPainter p(&pix); QPainter p(&pix);
QPen pen = graphics[i].pen; QPen pen = graphics[i].pen;
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick); if (qRound(pen.widthF()) == pen.widthF())
else pen.setWidthF(pen.widthF()*thick); pen.setWidth(pen.width() * thick);
else
pen.setWidthF(pen.widthF() * thick);
p.setPen(pen); p.setPen(pen);
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2); p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
p.end(); p.end();
@@ -2139,7 +2193,7 @@ void Graphic::updateLegend(bool es) {
return; return;
} }
leg_update = false; leg_update = false;
int ps = 100; int ps = 100;
for (int r = 0; r < ui->layoutLegend->rowCount(); ++r) for (int r = 0; r < ui->layoutLegend->rowCount(); ++r)
for (int c = 0; c < ui->layoutLegend->columnCount(); ++c) { for (int c = 0; c < ui->layoutLegend->columnCount(); ++c) {
QLayoutItem * li = ui->layoutLegend->itemAtPosition(r, c); QLayoutItem * li = ui->layoutLegend->itemAtPosition(r, c);
@@ -2167,33 +2221,36 @@ void Graphic::updateLegend(bool es) {
if (cps > ps) ps = cps; if (cps > ps) ps = cps;
} }
LegendScrollArea * leg_sa = (LegendScrollArea *)ui->scrollLegend->layout()->itemAt(0)->widget(); LegendScrollArea * leg_sa = (LegendScrollArea *)ui->scrollLegend->layout()->itemAt(0)->widget();
int maxcol = qMax<int>(leg_sa->width() / ps - 1, 1); int maxcol = qMax<int>(leg_sa->width() / ps - 1, 1);
int row = 0, col = 0; int row = 0, col = 0;
bool lv = ui->scrollLegend->isVisibleTo(this); bool lv = ui->scrollLegend->isVisibleTo(this);
ui->scrollLegend->hide(); ui->scrollLegend->hide();
for (int i = 0; i < graphics.size(); i++) { for (int i = 0; i < graphics.size(); i++) {
ui->layoutLegend->addWidget(graphics[i].pb,row,col); ui->layoutLegend->addWidget(graphics[i].pb, row, col);
QCheckBox * check = graphics[i].pb; QCheckBox * check = graphics[i].pb;
check->show(); check->show();
if (leg_sa->minimum_hei == 0) { if (leg_sa->minimum_hei == 0) {
leg_sa->minimum_hei = ui->widgetLegend->sizeHint().height(); leg_sa->minimum_hei = ui->widgetLegend->sizeHint().height();
/*#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) /*#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
QTimer::singleShot(0, this, [this,leg_sa,check](){ QTimer::singleShot(0, this, [this,leg_sa,check](){
leg_sa->minimum_hei = check->sizeHint().height(); leg_sa->minimum_hei = check->sizeHint().height();
leg_sa->updateGeometry(); leg_sa->updateGeometry();
qDebug() << leg_sa->minimum_hei << ui->widgetLegend->sizeHint(); qDebug() << leg_sa->minimum_hei << ui->widgetLegend->sizeHint();
}); });
#else #else
leg_sa->minimum_hei = check->sizeHint().height(); leg_sa->minimum_hei = check->sizeHint().height();
#endif*/ #endif*/
} }
col++; col++;
if (col > maxcol) {col = 0; row++;} if (col > maxcol) {
col = 0;
row++;
}
} }
ui->gridLayout->invalidate(); ui->gridLayout->invalidate();
ui->scrollLegend->setVisible(lv); ui->scrollLegend->setVisible(lv);
leg_sa->updateGeometry(); leg_sa->updateGeometry();
//ui->gridLayout->invalidate(); // ui->gridLayout->invalidate();
leg_update = true; leg_update = true;
if (es) emit graphicSettingsChanged(); if (es) emit graphicSettingsChanged();
} }
@@ -2212,24 +2269,30 @@ void Graphic::updateLegendChecks() {
void Graphic::graphicVisibleChange(bool checked) { void Graphic::graphicVisibleChange(bool checked) {
if (visible_update) return; if (visible_update) return;
QCheckBox * cb = qobject_cast<QCheckBox*>(sender()); QCheckBox * cb = qobject_cast<QCheckBox *>(sender());
int i = cb->property("graphic_num").toInt(); int i = cb->property("graphic_num").toInt();
graphics[i].visible = checked; graphics[i].visible = checked;
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit)
else {update();} on_graphic_buttonAutofit_clicked();
else {
update();
}
emit graphicSettingsChanged(); emit graphicSettingsChanged();
} }
void Graphic::graphicAllVisibleChange(bool checked) { void Graphic::graphicAllVisibleChange(bool checked) {
visible_update = true; visible_update = true;
for (int i=0; i<graphics.size(); i++) { for (int i = 0; i < graphics.size(); i++) {
graphics[i].visible = checked; graphics[i].visible = checked;
graphics[i].pb->setChecked(checked); graphics[i].pb->setChecked(checked);
} }
visible_update = false; visible_update = false;
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit)
else {update();} on_graphic_buttonAutofit_clicked();
else {
update();
}
emit graphicSettingsChanged(); emit graphicSettingsChanged();
} }
@@ -2319,23 +2382,22 @@ bool Graphic::legendVisible() const {
QByteArray Graphic::save() { QByteArray Graphic::save() {
// QByteArray ba; // QByteArray ba;
// QDataStream s(&ba, QIODevice::ReadWrite); // QDataStream s(&ba, QIODevice::ReadWrite);
// s << openGL() << antialiasing() << borderInputsVisible() << statusVisible() << legendVisible(); // s << openGL() << antialiasing() << borderInputsVisible() << statusVisible() << legendVisible();
// s << graphics; // s << graphics;
// return ba; // return ba;
// version '2': // version '2':
ChunkStream cs; ChunkStream cs;
cs.add(1, antialiasing()).add(2, openGL()).add(3, borderInputsVisible()).add(4, statusVisible()).add(5, legendVisible()); 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(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(9, gridPen()).add(10, graduationX()).add(11, graduationY()).add(12, graduationStepX()).add(13, graduationStepY());
cs.add(14, graphics); cs.add(14, graphics);
cs.add(15, isFit).add(16, visualRect()); cs.add(15, isFit).add(16, visualRect());
if (backgroundColor() == palette().color(QPalette::Base) && if (backgroundColor() == palette().color(QPalette::Base) && textColor() == palette().color(QPalette::WindowText) &&
textColor() == palette().color(QPalette::WindowText) && gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText))
gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText)) cs.add(17, true);
cs.add(17, true);
return cs.data().prepend('2'); return cs.data().prepend('2');
} }
@@ -2343,8 +2405,8 @@ QByteArray Graphic::save() {
void Graphic::load(QByteArray ba) { void Graphic::load(QByteArray ba) {
if (ba.isEmpty()) return; if (ba.isEmpty()) return;
char ver = ba[0]; char ver = ba[0];
switch(ver) { switch (ver) {
case '2': {// version '2': case '2': { // version '2':
ba.remove(0, 1); ba.remove(0, 1);
QRectF vrect; QRectF vrect;
ChunkStream cs(ba); ChunkStream cs(ba);
@@ -2356,35 +2418,47 @@ void Graphic::load(QByteArray ba) {
case 3: setBorderInputsVisible(cs.getData<bool>()); break; case 3: setBorderInputsVisible(cs.getData<bool>()); break;
case 4: setStatusVisible(cs.getData<bool>()); break; case 4: setStatusVisible(cs.getData<bool>()); break;
case 5: setLegendVisible(cs.getData<bool>()); break; case 5: setLegendVisible(cs.getData<bool>()); break;
case 6: if (!def_colors) setBackgroundColor(cs.getData<QColor>()); break; case 6:
case 7: if (!def_colors) setTextColor(cs.getData<QColor>()); break; 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 8: setMargins(cs.getData<QRect>()); break;
case 9: if (!def_colors) setGridPen(cs.getData<QPen>()); break; case 9:
if (!def_colors) setGridPen(cs.getData<QPen>());
break;
case 10: setGraduationX(cs.getData<Graduation>()); break; case 10: setGraduationX(cs.getData<Graduation>()); break;
case 11: setGraduationY(cs.getData<Graduation>()); break; case 11: setGraduationY(cs.getData<Graduation>()); break;
case 12: setGraduationStepX(cs.getData<double>()); break; case 12: setGraduationStepX(cs.getData<double>()); break;
case 13: setGraduationStepY(cs.getData<double>()); break; case 13: setGraduationStepY(cs.getData<double>()); break;
case 14: graphics = cs.getData<QVector<GraphicType> >(); break; case 14: graphics = cs.getData<QVector<GraphicType>>(); break;
case 15: isFit = cs.getData<bool>(); break; case 15: isFit = cs.getData<bool>(); break;
case 16: vrect = cs.getData<QRectF>(); break; case 16: vrect = cs.getData<QRectF>(); break;
case 17: if(cs.getData<bool>()) { case 17:
setTextColor(palette().color(QPalette::WindowText)); if (cs.getData<bool>()) {
setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine)); setTextColor(palette().color(QPalette::WindowText));
setBackgroundColor(palette().color(QPalette::Base)); setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine));
def_colors = true; setBackgroundColor(palette().color(QPalette::Base));
} break; def_colors = true;
}
break;
default: break; default: break;
} }
} }
if (!isFit) setVisualRect(vrect); if (!isFit) setVisualRect(vrect);
} break; } break;
default: {// old version 0: default: { // old version 0:
QDataStream s(ba); QDataStream s(ba);
bool a; bool a;
s >> a; setOpenGL(a); s >> a;
s >> a; setAntialiasing(a); setOpenGL(a);
s >> a; setBorderInputsVisible(a); s >> a;
s >> a; setStatusVisible(a); setAntialiasing(a);
s >> a;
setBorderInputsVisible(a);
s >> a;
setStatusVisible(a);
s >> a; s >> a;
s >> graphics; s >> graphics;
setLegendVisible(a); setLegendVisible(a);
@@ -2403,7 +2477,8 @@ void Graphic::setCaption(const QString & str) {
void Graphic::setGraphicVisible(bool visible, int index) { void Graphic::setGraphicVisible(bool visible, int index) {
graphics[index].visible = visible; graphics[index].visible = visible;
updateLegendChecks(); updateLegendChecks();
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit)
on_graphic_buttonAutofit_clicked();
else if (aupdate) else if (aupdate)
update(); update();
} }
@@ -2431,7 +2506,7 @@ void Graphic::setLegendVisible(bool visible) {
ui->scrollLegend->setVisible(visible); ui->scrollLegend->setVisible(visible);
ui->graphic_checkLegend->setChecked(visible); ui->graphic_checkLegend->setChecked(visible);
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
QTimer::singleShot(0, this, [this](){updateLegend();}); QTimer::singleShot(0, this, [this]() { updateLegend(); });
#else #else
updateLegend(); updateLegend();
#endif #endif
+440 -229
View File
@@ -1,46 +1,47 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GRAPHIC_H #ifndef GRAPHIC_H
#define GRAPHIC_H #define GRAPHIC_H
#include <QWidget> #include "evalspinbox.h"
#include <QPainter> #include "graphic_conf.h"
#include <QPixmap> #include "qad_graphic_export.h"
#include <QMouseEvent>
#include <QComboBox> #include <QComboBox>
#include <QDebug> #include <QDebug>
#include <QGridLayout>
#include <QFileDialog>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QTranslator> #include <QFileDialog>
#include <QGestureEvent> #include <QGestureEvent>
#include <QGridLayout>
#include <QMenu> #include <QMenu>
#include <qmath.h> #include <QMouseEvent>
#include <QPainter>
#include <QPixmap>
#include <QTranslator>
#include <QWidget>
#include <float.h> #include <float.h>
#include "graphic_conf.h" #include <qmath.h>
#include "evalspinbox.h"
#include "qad_graphic_export.h"
namespace Ui { namespace Ui {
class Graphic; class Graphic;
} }
@@ -51,8 +52,7 @@ class GraphicPlugin;
Q_DECLARE_METATYPE(QVector<QPointF>) Q_DECLARE_METATYPE(QVector<QPointF>)
class QAD_GRAPHIC_EXPORT Graphic: public QFrame class QAD_GRAPHIC_EXPORT Graphic: public QFrame {
{
Q_OBJECT Q_OBJECT
Q_FLAGS(Buttons) Q_FLAGS(Buttons)
Q_ENUMS(Alignment Graduation AxisType FloatingAxisType) Q_ENUMS(Alignment Graduation AxisType FloatingAxisType)
@@ -127,164 +127,262 @@ public:
Graphic(QWidget * parent = 0); Graphic(QWidget * parent = 0);
virtual ~Graphic(); virtual ~Graphic();
typedef QVector<QVector<QPointF> > GraphicsData; typedef QVector<QVector<QPointF>> GraphicsData;
enum GraphicAction {gaNone, gaZoomInRect, gaZoomRangeX, gaZoomRangeY, gaMove}; enum GraphicAction {
enum Button {NoButtons = 0x0, gaNone,
AllButtons = 0xFFFFFFFF, gaZoomInRect,
Autofit = 0x01, gaZoomRangeX,
Grid = 0x02, gaZoomRangeY,
CursorAxis = 0x04, gaMove
Fullscreen = 0x20, };
BorderInputs = 0x40, enum Button {
Legend = 0x80, NoButtons = 0x0,
Configure = 0x100, AllButtons = 0xFFFFFFFF,
Save = 0x200, Autofit = 0x01,
Export = 0x400, Grid = 0x02,
Clear = 0x800, CursorAxis = 0x04,
Close = 0x1000, Fullscreen = 0x20,
Pause = 0x2000, BorderInputs = 0x40,
Record = 0x4000, Legend = 0x80,
StandartButtons = 0x2BFF Configure = 0x100,
}; Save = 0x200,
enum Alignment {Left, Right}; Export = 0x400,
enum Graduation {Auto, Fixed}; Clear = 0x800,
enum AxisType {Numeric, DateTime}; Close = 0x1000,
enum FloatingAxisType {Free, TraceXY, TraceX, TraceY}; Pause = 0x2000,
Record = 0x4000,
StandartButtons = 0x2BFF
};
enum Alignment {
Left,
Right
};
enum Graduation {
Auto,
Fixed
};
enum AxisType {
Numeric,
DateTime
};
enum FloatingAxisType {
Free,
TraceXY,
TraceX,
TraceY
};
Q_DECLARE_FLAGS(Buttons, Button) Q_DECLARE_FLAGS(Buttons, Button)
QString caption() const; QString caption() const;
QString labelX() const {return label_x;} QString labelX() const { return label_x; }
QString labelY() const {return label_y;} QString labelY() const { return label_y; }
QString graphicName() const {return graphics[curGraphic].name;} QString graphicName() const { return graphics[curGraphic].name; }
QString graphicName(int index) const {return graphics[index].name;} QString graphicName(int index) const { return graphics[index].name; }
QColor backgroundColor() const {return back_color;} QColor backgroundColor() const { return back_color; }
QColor textColor() const {return text_color;} QColor textColor() const { return text_color; }
QColor graphicColor() const {return graphics[curGraphic].pen.color();} QColor graphicColor() const { return graphics[curGraphic].pen.color(); }
QColor graphicColor(int index) const {return graphics[index].pen.color();} QColor graphicColor(int index) const { return graphics[index].pen.color(); }
QColor gridColor() const {return grid_pen.color();} QColor gridColor() const { return grid_pen.color(); }
QColor selectionColor() const {return selpen.color();} QColor selectionColor() const { return selpen.color(); }
Qt::PenStyle graphicStyle() const {return graphics[curGraphic].pen.style();} Qt::PenStyle graphicStyle() const { return graphics[curGraphic].pen.style(); }
Qt::PenStyle graphicStyle(int index) const {return graphics[index].pen.style();} Qt::PenStyle graphicStyle(int index) const { return graphics[index].pen.style(); }
Qt::PenStyle gridStyle() const {return grid_pen.style();} Qt::PenStyle gridStyle() const { return grid_pen.style(); }
Qt::PenStyle selectionStyle() const {return selpen.style();} Qt::PenStyle selectionStyle() const { return selpen.style(); }
double graphicLineWidth() const {return graphics[curGraphic].pen.widthF();} double graphicLineWidth() const { return graphics[curGraphic].pen.widthF(); }
double graphicLineWidth(int index) const {return graphics[index].pen.widthF();} double graphicLineWidth(int index) const { return graphics[index].pen.widthF(); }
double graphicPointWidth() const {return graphics[curGraphic].pointWidth;} double graphicPointWidth() const { return graphics[curGraphic].pointWidth; }
double graphicPointWidth(int index) const {return graphics[index].pointWidth;} double graphicPointWidth(int index) const { return graphics[index].pointWidth; }
QColor graphicFillColor() const {return graphics[curGraphic].fill_color;} QColor graphicFillColor() const { return graphics[curGraphic].fill_color; }
QColor graphicFillColor(int index) const {return graphics[index].fill_color;} QColor graphicFillColor(int index) const { return graphics[index].fill_color; }
bool graphicVisible() const {return graphics[curGraphic].visible;} bool graphicVisible() const { return graphics[curGraphic].visible; }
bool graphicVisible(int index) const {return graphics[index].visible;} bool graphicVisible(int index) const { return graphics[index].visible; }
bool graphicLinesEnabled() const {return graphics[curGraphic].lines;} bool graphicLinesEnabled() const { return graphics[curGraphic].lines; }
bool graphicLinesEnabled(int index) const {return graphics[index].lines;} bool graphicLinesEnabled(int index) const { return graphics[index].lines; }
bool graphicPointsEnabled() const {return graphics[curGraphic].points;} bool graphicPointsEnabled() const { return graphics[curGraphic].points; }
bool graphicPointsEnabled(int index) const {return graphics[index].points;} bool graphicPointsEnabled(int index) const { return graphics[index].points; }
bool graphicFillEnabled() const {return graphics[curGraphic].fill;} bool graphicFillEnabled() const { return graphics[curGraphic].fill; }
bool graphicFillEnabled(int index) const {return graphics[index].fill;} bool graphicFillEnabled(int index) const { return graphics[index].fill; }
QPen graphicPen() const {return graphics[curGraphic].pen;} QPen graphicPen() const { return graphics[curGraphic].pen; }
QPen graphicPen(int index) const {return graphics[index].pen;} QPen graphicPen(int index) const { return graphics[index].pen; }
QPen gridPen() const {return grid_pen;} QPen gridPen() const { return grid_pen; }
QPen selectionPen() const {return selpen;} QPen selectionPen() const { return selpen; }
QBrush selectionBrush() const {return selbrush;} QBrush selectionBrush() const { return selbrush; }
bool navigationEnabled() const {return navigation;} bool navigationEnabled() const { return navigation; }
bool openGL() const {return isOGL;} bool openGL() const { return isOGL; }
bool antialiasing() const {return aalias;} bool antialiasing() const { return aalias; }
bool autoUpdate() const {return aupdate;} bool autoUpdate() const { return aupdate; }
bool gridEnabled() const {return grid;} bool gridEnabled() const { return grid; }
bool borderInputsVisible() const; bool borderInputsVisible() const;
bool statusVisible() const; bool statusVisible() const;
bool legendVisible() const; bool legendVisible() const;
bool paused() const {return pause_;} bool paused() const { return pause_; }
bool onlyExpandY() const {return only_expand_y;} bool onlyExpandY() const { return only_expand_y; }
bool onlyExpandX() const {return only_expand_x;} bool onlyExpandX() const { return only_expand_x; }
bool gesturesNavigation() const {return gestures;} bool gesturesNavigation() const { return gestures; }
bool LODOptimization() const {return m_LODOptimization;} bool LODOptimization() const { return m_LODOptimization; }
bool isAutofitted() const {return isFit;} bool isAutofitted() const { return isFit; }
int currentGraphic() const {return curGraphic;} int currentGraphic() const { return curGraphic; }
int currentTraceGraphic() const {return curTrace;} int currentTraceGraphic() const { return curTrace; }
int graphicsCount() const {return graphics.size();} int graphicsCount() const { return graphics.size(); }
Graphic::Buttons buttons() const {return buttons_;} Graphic::Buttons buttons() const { return buttons_; }
Graphic::Alignment buttonsPosition() const {return align;} Graphic::Alignment buttonsPosition() const { return align; }
double historySize() const {return history;} double historySize() const { return history; }
double maxVisibleTime() const {return visible_time;} double maxVisibleTime() const { return visible_time; }
double autoXIncrement() const {return inc_x;} double autoXIncrement() const { return inc_x; }
QRectF visualRect() const {return selrect;} QRectF visualRect() const { return selrect; }
QRectF defaultRect() const {return def_rect;} QRectF defaultRect() const { return def_rect; }
QRectF limit() const {return limit_;} QRectF limit() const { return limit_; }
QRect margins() const {return margins_;} QRect margins() const { return margins_; }
int minimumRepaintInterval() const {return min_repaint_int;} int minimumRepaintInterval() const { return min_repaint_int; }
double gridNumbersMultiplierX() const {return grid_numbers_x;} double gridNumbersMultiplierX() const { return grid_numbers_x; }
double gridNumbersMultiplierY() const {return grid_numbers_y;} double gridNumbersMultiplierY() const { return grid_numbers_y; }
Graduation graduationX() const {return grad_x;} Graduation graduationX() const { return grad_x; }
Graduation graduationY() const {return grad_y;} Graduation graduationY() const { return grad_y; }
double graduationStepX() const {return gridx;} double graduationStepX() const { return gridx; }
double graduationStepY() const {return gridy;} double graduationStepY() const { return gridy; }
AxisType axisType() const {return axis_type_x;} AxisType axisType() const { return axis_type_x; }
FloatingAxisType floatingAxisType() const {return floating_axis_type;} FloatingAxisType floatingAxisType() const { return floating_axis_type; }
QVector<QPointF> graphicData() const {return graphics[curGraphic].polyline;} QVector<QPointF> graphicData() const { return graphics[curGraphic].polyline; }
QVector<QPointF> graphicData(int index) const {return graphics[index].polyline;} QVector<QPointF> graphicData(int index) const { return graphics[index].polyline; }
GraphicsData graphicsData() const; GraphicsData graphicsData() const;
QByteArray graphicsDataRaw() const; QByteArray graphicsDataRaw() const;
QWidget * viewport() const {return canvas;} QWidget * viewport() const { return canvas; }
QByteArray save(); QByteArray save();
void load(QByteArray ba); void load(QByteArray ba);
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];} GraphicType graphic(int arg) {
const QVector<GraphicType> & allGraphics() const {return graphics;} if (arg < 0 || arg >= graphics.size()) return GraphicType();
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();} 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 canvas2realX(double px) const;
double canvas2realY(double py) const; double canvas2realY(double py) const;
double real2canvasX(double px) const; double real2canvasX(double px) const;
double real2canvasY(double py) const; double real2canvasY(double py) const;
QPointF canvas2real(QPointF canvas_point) const {return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y()));} 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()));} QPointF real2canvas(QPointF real_point) const { return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y())); }
QPolygonF real2canvas(const QPolygonF & real_polygon) const; QPolygonF real2canvas(const QPolygonF & real_polygon) const;
QPolygonF canvas2real(const QPolygonF & canvas_polygon) const; QPolygonF canvas2real(const QPolygonF & canvas_polygon) const;
double getScaleX() const {return real2canvasX(1.) - real2canvasX(0.);} double getScaleX() const { return real2canvasX(1.) - real2canvasX(0.); }
double getScaleY() const {return real2canvasY(1.) - real2canvasY(0.);} double getScaleY() const { return real2canvasY(1.) - real2canvasY(0.); }
QPointF getScale() const {return QPointF(getScaleX(), getScaleY());} QPointF getScale() const { return QPointF(getScaleX(), getScaleY()); }
public slots: public slots:
void setCaption(const QString & str); void setCaption(const QString & str);
void setLabelX(const QString & str) {label_x = str; hasLblX = (str.length() > 0); if (aupdate) update();} void setLabelX(const QString & str) {
void setLabelY(const QString & str) {label_y = str; hasLblY = (str.length() > 0); if (aupdate) update();} label_x = str;
void setGraphicName(const QString & str, int index) {graphics[index].name = str; updateLegend(); if (aupdate) update();} hasLblX = (str.length() > 0);
void setGraphicName(const QString & str) {graphics[curGraphic].name = str; updateLegend(); if (aupdate) update();} 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 setLabelY(const QString & str) {
void setGraphicColor(const QColor & color, int index) {graphics[index].pen.setColor(color); updateLegend(); if (aupdate) update();} label_y = str;
void setGraphicColor(const QColor & color) {setGraphicColor(color, curGraphic);} hasLblY = (str.length() > 0);
void setGridColor(const QColor & color) {grid_pen.setColor(color); if (aupdate) update();} 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 setGraphicName(const QString & str, int index) {
void setGraphicStyle(const Qt::PenStyle & style) {setGraphicStyle(style, curGraphic);} graphics[index].name = str;
void setGridStyle(const Qt::PenStyle & style) {grid_pen.setStyle(style); if (aupdate) update();} updateLegend();
void setSelectionStyle(const Qt::PenStyle & style) {selpen.setStyle(style);} 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); void setGraphicVisible(bool visible, int index);
void setGraphicVisible(bool visible) {setGraphicVisible(visible, curGraphic);} 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, int index) {
void setGraphicLineWidth(double w) {setGraphicLineWidth(w, curGraphic);} if (qRound(w) == w)
void setGraphicPointWidth(double w, int index) {graphics[index].pointWidth = w; updateLegend(); if (aupdate) update();} graphics[index].pen.setWidth(qRound(w));
void setGraphicPointWidth(double w) {setGraphicPointWidth(w, curGraphic);} else
void setGraphicFillColor(const QColor & w, int index) {graphics[index].fill_color = w; updateLegend(); if (aupdate) update();} graphics[index].pen.setWidthF(w);
void setGraphicFillColor(const QColor & w) {setGraphicFillColor(w, curGraphic);} updateLegend();
void setGraphicLinesEnabled(bool w, int index) {graphics[index].lines = w; updateLegend(); if (aupdate) update();} 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 setGraphicLineWidth(double w) { setGraphicLineWidth(w, curGraphic); }
void setGraphicPointsEnabled(bool w) {setGraphicPointsEnabled(w, curGraphic);} void setGraphicPointWidth(double w, int index) {
void setGraphicFillEnabled(bool w, int index) {graphics[index].fill = w; updateLegend(); if (aupdate) update();} graphics[index].pointWidth = w;
void setGraphicFillEnabled(bool w) {setGraphicFillEnabled(w, curGraphic);} updateLegend();
void setGraphicPen(const QPen & pen, int index) {graphics[index].pen = pen; updateLegend(); if (aupdate) update();} if (aupdate) update();
void setGraphicPen(const QPen & pen) {setGraphicPen(pen, curGraphic);} }
void setGridPen(const QPen & pen) {grid_pen = pen; if (aupdate) update();} void setGraphicPointWidth(double w) { setGraphicPointWidth(w, curGraphic); }
void setSelectionPen(const QPen & pen) {selpen = pen;} void setGraphicFillColor(const QColor & w, int index) {
void setSelectionBrush(const QBrush & brush) {selbrush = brush;} graphics[index].fill_color = w;
void setNavigationEnabled(bool on) {navigation = on;} updateLegend();
void setLODOptimization(bool yes) {m_LODOptimization = yes;} 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 setLODOptimization(bool yes) { m_LODOptimization = yes; }
void setOpenGL(bool on); void setOpenGL(bool on);
void setAntialiasing(bool enabled); void setAntialiasing(bool enabled);
void setAutoUpdate(bool enabled) {aupdate = enabled;} void setAutoUpdate(bool enabled) { aupdate = enabled; }
void setGridEnabled(bool enabled); void setGridEnabled(bool enabled);
void setBorderInputsVisible(bool visible); void setBorderInputsVisible(bool visible);
void setStatusVisible(bool visible); void setStatusVisible(bool visible);
@@ -294,66 +392,149 @@ public slots:
void setButtonsPosition(Graphic::Alignment a); void setButtonsPosition(Graphic::Alignment a);
void setHistorySize(double val); void setHistorySize(double val);
void setMaxVisibleTime(double val); void setMaxVisibleTime(double val);
void setAutoXIncrement(double val) {inc_x = val;} void setAutoXIncrement(double val) { inc_x = val; }
void setLimit(const QRectF & val) {limit_ = val;} void setLimit(const QRectF & val) { limit_ = val; }
void setMargins(const QRect & val) {margins_ = val; update();} void setMargins(const QRect & val) {
void setMargins(int left_, int right_, int top_, int bottom_) {setMargins(QRect(left_, bottom_, right_, top_));} margins_ = val;
void setLeftMargin(int value) {margins_.moveLeft(value); setMargins(margins_);} update();
void setRightMargin(int value) {margins_.setWidth(value); setMargins(margins_);} }
void setTopMargin(int value) {margins_.setHeight(value); setMargins(margins_);} void setMargins(int left_, int right_, int top_, int bottom_) { setMargins(QRect(left_, bottom_, right_, top_)); }
void setBottomMargin(int value) {margins_.moveTop(value); setMargins(margins_);} void setLeftMargin(int value) {
void setMinimumRepaintInterval(const int & val) {min_repaint_int = val;} 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 setOnlyExpandY(bool yes);
void setOnlyExpandX(bool yes); void setOnlyExpandX(bool yes);
void setGesturesNavigation(bool yes); void setGesturesNavigation(bool yes);
void setGraphicsData(const GraphicsData & gd); void setGraphicsData(const GraphicsData & gd);
void setGraphicsDataRaw(const QByteArray & ba); void setGraphicsDataRaw(const QByteArray & ba);
void setGridNumbersMultiplierX(double value) {grid_numbers_x = value; updateGraphics();} void setGridNumbersMultiplierX(double value) {
void setGridNumbersMultiplierY(double value) {grid_numbers_y = value; updateGraphics();} grid_numbers_x = value;
void setGraduationX(Graduation value) {grad_x = value; if (aupdate) update();;} updateGraphics();
void setGraduationY(Graduation value) {grad_y = value; if (aupdate) update();;} }
void setGraduationStepX(double sx) {gridx = sx; if (aupdate) update();} void setGridNumbersMultiplierY(double value) {
void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();} grid_numbers_y = value;
void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();} updateGraphics();
void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();} }
void setFloatingAxisType(FloatingAxisType t) {floating_axis_type = t; setGuidesCursor(); if (aupdate) update();} 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 setFloatingAxisType(FloatingAxisType t) {
floating_axis_type = t;
setGuidesCursor();
if (aupdate) update();
}
void setFloatingAxisEnabled(bool on); void setFloatingAxisEnabled(bool on);
void addPoint(const QPointF & p, int graphic, bool update_ = true); void addPoint(const QPointF & p, int graphic, bool update_ = true);
void addPoint(const QPointF & p, bool update = true) {addPoint(p, curGraphic, update);} 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, 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 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, int graphic, bool update = true) {
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);} 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 addPoints(const QPolygonF & pts, int graphic, bool update_ = true); void addPoints(const QPolygonF & pts, int graphic, bool update_ = true);
void addPoints(const QPolygonF & pts, bool update = true) {addPoints(pts, curGraphic, update);} void addPoints(const QPolygonF & pts, bool update = true) { addPoints(pts, curGraphic, update); }
void addPoints(const QVector<double> & pts, int graphic, bool update_ = true); void addPoints(const QVector<double> & pts, int graphic, bool update_ = true);
void addPoints(const QVector<double> & pts, bool update = true) {addPoints(pts, curGraphic, update);} void addPoints(const QVector<double> & pts, bool update = true) { addPoints(pts, curGraphic, update); }
void setGraphicData(const QVector<QPointF> & g, int graphic, bool update_ = true); void setGraphicData(const QVector<QPointF> & g, int graphic, bool update_ = true);
void setGraphicData(const QVector<QPointF> & g) {setGraphicData(g, curGraphic);} 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(const QString & name,
void setGraphicProperties(int graphic, const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true); const QColor & color = Qt::darkRed,
void addGraphic(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true); Qt::PenStyle style = Qt::SolidLine,
void addGraphic(const GraphicType & gd, bool update = true) {graphics << gd; if (update) updateLegend();} 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 setVisualRect(const QRectF & rect);
void setDefaultRect(const QRectF & rect); void setDefaultRect(const QRectF & rect);
void autofit() {on_graphic_buttonAutofit_clicked();} void autofit() { on_graphic_buttonAutofit_clicked(); }
void saveImage(QString filename); void saveImage(QString filename);
void exportGraphics(QString filename, QChar decimal_point); void exportGraphics(QString filename, QChar decimal_point);
void clear(); void clear();
void update(bool force); void update(bool force);
void update() {update(false);} void update() { update(false); }
void updateGraphics() {findGraphicsRect(); update();} void updateGraphics() {
void setCurrentGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curGraphic = arg;} findGraphicsRect();
void setTraceGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curTrace = arg;} update();
}
void setCurrentGraphic(int arg) {
if (arg < 0 || arg >= graphics.size()) return;
curGraphic = arg;
}
void setTraceGraphic(int arg) {
if (arg < 0 || arg >= graphics.size()) return;
curTrace = arg;
}
void setGraphicsCount(int arg, bool update = true); void setGraphicsCount(int arg, bool update = true);
void removeGraphic(int arg, bool update = true); void removeGraphic(int arg, bool update = true);
void setCustomGridMarkFuncs(std::function<QString(double val)> fx, std::function<QString(double val)> fy); void setCustomGridMarkFuncs(std::function<QString(double val)> fx, std::function<QString(double val)> fy);
void zoom(float factor); void zoom(float factor);
void zoomIn() {zoom(1. / 1.2);} void zoomIn() { zoom(1. / 1.2); }
void zoomOut() {zoom(1.2);} void zoomOut() { zoom(1.2); }
void fullscreen(); void fullscreen();
@@ -365,9 +546,9 @@ protected:
}; };
void changeEvent(QEvent * e) override; void changeEvent(QEvent * e) override;
void resizeEvent(QResizeEvent * ) override; void resizeEvent(QResizeEvent *) override;
void showEvent(QShowEvent * ) override; void showEvent(QShowEvent *) override;
QSize sizeHint() const override {return QSize(400, 300);} QSize sizeHint() const override { return QSize(400, 300); }
void timerEvent(QTimerEvent * e) override; void timerEvent(QTimerEvent * e) override;
bool eventFilter(QObject * o, QEvent * e) override; bool eventFilter(QObject * o, QEvent * e) override;
@@ -379,7 +560,11 @@ protected:
void findGraphicsRect(double start_x = 0., double end_x = 0., double start_y = 0., double end_y = 0.); 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 tick(int index, bool slide = true, bool update = true);
void calcLOD(int index); void calcLOD(int index);
void repaintCanvas(bool force = false) {if (tm.elapsed() < min_repaint_int && !force) return; tm.restart(); canvas->update();} void repaintCanvas(bool force = false) {
if (tm.elapsed() < min_repaint_int && !force) return;
tm.restart();
canvas->update();
}
void drawGraphics(); void drawGraphics();
void drawGrid(); void drawGrid();
void drawGuides(); void drawGuides();
@@ -390,7 +575,7 @@ protected:
void setCanvasCursor(QCursor cursor); void setCanvasCursor(QCursor cursor);
void setGuidesCursor(); void setGuidesCursor();
void swapToBuffer(); void swapToBuffer();
void swapToNormal() {bufferActive = false;} void swapToNormal() { bufferActive = false; }
void setRectToLines(); void setRectToLines();
void checkLines(); void checkLines();
double splitRange(double range, int count = 1); double splitRange(double range, int count = 1);
@@ -398,7 +583,7 @@ protected:
double roundTo(double value, double round_to); double roundTo(double value, double round_to);
void roundDateTime(QDateTime & dt, int * c); void roundDateTime(QDateTime & dt, int * c);
void addDateTime(QDateTime & dt, int * c, qint64 mul = 1); void addDateTime(QDateTime & dt, int * c, qint64 mul = 1);
QPointF absPoint(QPointF point) {return QPointF(qAbs(point.x()), qAbs(point.y()));} QPointF absPoint(QPointF point) { return QPointF(qAbs(point.x()), qAbs(point.y())); }
QString pointCoords(QPointF point, bool x = true, bool y = true); QString pointCoords(QPointF point, bool x = true, bool y = true);
QPair<QString, QString> gridMark(double v) const; QPair<QString, QString> gridMark(double v) const;
void fillDateFormats(); void fillDateFormats();
@@ -438,56 +623,76 @@ protected:
double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle; double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle;
int lastw, lasth, min_repaint_int, thick; int lastw, lasth, min_repaint_int, thick;
int timer_pause, timer_record; int timer_pause, timer_record;
bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL, need_createGL; bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL,
bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan, was_trace; need_createGL;
bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan,
was_trace;
std::function<QString(double val)> func_gridMarkX, func_gridMarkY; std::function<QString(double val)> func_gridMarkX, func_gridMarkY;
QVector<DateFormats> date_formats; QVector<DateFormats> date_formats;
QList<QImage> record_imgs; QList<QImage> record_imgs;
protected slots: protected slots:
void canvasPaintEvent(); void canvasPaintEvent();
void canvasMouseMoveEvent(QMouseEvent * ); void canvasMouseMoveEvent(QMouseEvent *);
void canvasMousePressEvent(QMouseEvent * ); void canvasMousePressEvent(QMouseEvent *);
void canvasMouseReleaseEvent(QMouseEvent * ); void canvasMouseReleaseEvent(QMouseEvent *);
void canvasMouseDoubleClickEvent(QMouseEvent * ); void canvasMouseDoubleClickEvent(QMouseEvent *);
void canvasWheelEvent(QWheelEvent * ); void canvasWheelEvent(QWheelEvent *);
void canvasLeaveEvent(QEvent * ); void canvasLeaveEvent(QEvent *);
void canvasKeyPressEvent(QKeyEvent * ); void canvasKeyPressEvent(QKeyEvent *);
void graphicVisibleChange(bool checked); void graphicVisibleChange(bool checked);
void graphicAllVisibleChange(bool checked); void graphicAllVisibleChange(bool checked);
void lineXMinChanged(double value) {selrect.setLeft(value); checkLines();} void lineXMinChanged(double value) {
void lineXMaxChanged(double value) {selrect.setRight(value); checkLines();} selrect.setLeft(value);
void lineYMinChanged(double value) {selrect.setBottom(value); checkLines();} checkLines();
void lineYMaxChanged(double value) {selrect.setTop(value); checkLines();} }
void on_graphic_buttonClose_clicked() {emit closeRequest(this);} void lineXMaxChanged(double value) {
void on_graphic_buttonClear_clicked() {clear(); emit cleared();} selrect.setRight(value);
checkLines();
}
void lineYMinChanged(double value) {
selrect.setBottom(value);
checkLines();
}
void lineYMaxChanged(double value) {
selrect.setTop(value);
checkLines();
}
void on_graphic_buttonClose_clicked() { emit closeRequest(this); }
void on_graphic_buttonClear_clicked() {
clear();
emit cleared();
}
void on_graphic_buttonAutofit_clicked(); void on_graphic_buttonAutofit_clicked();
void on_graphic_buttonConfigure_clicked(); void on_graphic_buttonConfigure_clicked();
void on_graphic_buttonFullscreen_clicked() {fullscreen();} void on_graphic_buttonFullscreen_clicked() { fullscreen(); }
void on_graphic_buttonSave_clicked(); void on_graphic_buttonSave_clicked();
void on_graphic_buttonExport_clicked(); void on_graphic_buttonExport_clicked();
void on_graphic_buttonRecord_clicked(bool checked); void on_graphic_buttonRecord_clicked(bool checked);
void on_graphic_checkGrid_toggled(bool checked) {grid = checked; update();} void on_graphic_checkGrid_toggled(bool checked) {
grid = checked;
update();
}
void on_graphic_checkGuides_toggled(bool checked); void on_graphic_checkGuides_toggled(bool checked);
void on_graphic_actionExpandX_triggered(bool checked); void on_graphic_actionExpandX_triggered(bool checked);
void on_graphic_actionExpandY_triggered(bool checked); void on_graphic_actionExpandY_triggered(bool checked);
void on_graphic_checkBorderInputs_toggled(bool checked) {setBorderInputsVisible(checked);} void on_graphic_checkBorderInputs_toggled(bool checked) { setBorderInputsVisible(checked); }
void on_graphic_checkLegend_toggled(bool checked) {setLegendVisible(checked);} void on_graphic_checkLegend_toggled(bool checked) { setLegendVisible(checked); }
void on_graphic_checkPause_toggled(bool checked) {setPaused(checked);} void on_graphic_checkPause_toggled(bool checked) { setPaused(checked); }
void actionGuidesTriggered(QAction * a); void actionGuidesTriggered(QAction * a);
void enterFullscreen(); void enterFullscreen();
void leaveFullscreen(); void leaveFullscreen();
void showMenu(); void showMenu();
signals: signals:
void beforeGraphicPaintEvent(QPainter * ); void beforeGraphicPaintEvent(QPainter *);
void graphicPaintEvent(QPainter * ); void graphicPaintEvent(QPainter *);
void graphicMouseMoveEvent(QPointF point, int buttons); void graphicMouseMoveEvent(QPointF point, int buttons);
void graphicMousePressEvent(QPointF point, int buttons); void graphicMousePressEvent(QPointF point, int buttons);
void graphicMouseReleaseEvent(QPointF point, int buttons); void graphicMouseReleaseEvent(QPointF point, int buttons);
void graphicWheelEvent(QPointF point, int delta); void graphicWheelEvent(QPointF point, int delta);
void graphicTraceEvent(int graphic, QPointF point); void graphicTraceEvent(int graphic, QPointF point);
void closeRequest(QWidget * ); void closeRequest(QWidget *);
void cleared(); void cleared();
void visualRectChanged(); void visualRectChanged();
void graphicSettingsChanged(); void graphicSettingsChanged();
@@ -499,14 +704,20 @@ Q_DECLARE_METATYPE(Graphic::GraphicsData)
Q_DECLARE_OPERATORS_FOR_FLAGS(Graphic::Buttons) 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, const Graphic::Graduation & v) {
inline QDataStream & operator >>(QDataStream & s, Graphic::Graduation & v) {s >> *((int*)(&v)); return s;} s << (int)v;
return s;
}
inline QDataStream & operator>>(QDataStream & s, Graphic::Graduation & v) {
s >> *((int *)(&v));
return s;
}
class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ { class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ {
public: public:
__GraphicRegistrator__() { __GraphicRegistrator__() {
qRegisterMetaType<QVector<QPointF> >("QVector<QPointF>"); qRegisterMetaType<QVector<QPointF>>("QVector<QPointF>");
qRegisterMetaType<Graphic::GraphicsData>("Graphic::GraphicsData"); qRegisterMetaType<Graphic::GraphicsData>("Graphic::GraphicsData");
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
qRegisterMetaTypeStreamOperators<Graphic::GraphicsData>("Graphic::GraphicsData"); qRegisterMetaTypeStreamOperators<Graphic::GraphicsData>("Graphic::GraphicsData");
+7 -5
View File
@@ -1,4 +1,5 @@
#include "graphic_conf.h" #include "graphic_conf.h"
#include "qad_types.h" #include "qad_types.h"
#include "ui_graphic_conf.h" #include "ui_graphic_conf.h"
@@ -7,11 +8,10 @@ GraphicConf::GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent): QD
ui = new Ui::GraphicConf(); ui = new Ui::GraphicConf();
ui->setupUi(this); ui->setupUi(this);
QStringList styles; QStringList styles;
int fh = qMax<int>(fontMetrics().size(0, "0").height(), 22); int fh = qMax<int>(fontMetrics().size(0, "0").height(), 22);
int thick = lineThickness(this); int thick = lineThickness(this);
QSize sz(fh * 2.5, fh); QSize sz(fh * 2.5, fh);
styles << tr("NoPen") << tr("Solid") << tr("Dash") styles << tr("NoPen") << tr("Solid") << tr("Dash") << tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
ui->comboStyleGrid->setIconSize(sz); ui->comboStyleGrid->setIconSize(sz);
ui->comboStyleGraphic->setIconSize(sz); ui->comboStyleGraphic->setIconSize(sz);
ui->cbGraphicNames->setIconSize(sz); ui->cbGraphicNames->setIconSize(sz);
@@ -72,8 +72,10 @@ void GraphicConf::on_comboStyleGraphic_currentIndexChanged(int index) {
void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) { void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) {
if (graphicItems.isEmpty()) return; if (graphicItems.isEmpty()) return;
if (qRound(value) == value) graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value)); if (qRound(value) == value)
else graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value); graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value));
else
graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value);
} }
+44 -31
View File
@@ -1,54 +1,61 @@
/* /*
QAD - Qt ADvanced QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GRAPHIC_CONF_H #ifndef GRAPHIC_CONF_H
#define GRAPHIC_CONF_H #define GRAPHIC_CONF_H
#include <QDialog>
#include <QCheckBox>
#include <QPen>
#include <QPainter>
#include "qad_graphic_export.h" #include "qad_graphic_export.h"
#include <QCheckBox>
#include <QDialog>
#include <QPainter>
#include <QPen>
namespace Ui { namespace Ui {
class GraphicConf; class GraphicConf;
} }
struct QAD_GRAPHIC_EXPORT GraphicType { 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) { GraphicType(QString name_ = "y(x)",
QColor color = Qt::red,
Qt::PenStyle style = Qt::SolidLine,
double width = 0.,
bool visible_ = true) {
pen.setColor(color); pen.setColor(color);
pen.setStyle(style); pen.setStyle(style);
lines = true; lines = true;
points = false; points = false;
fill = false; fill = false;
fill_color = Qt::yellow; fill_color = Qt::yellow;
if (qRound(width) == width) pen.setWidth(qRound(width)); if (qRound(width) == width)
else pen.setWidthF(width); pen.setWidth(qRound(width));
else
pen.setWidthF(width);
pen.setWidth(1); pen.setWidth(1);
pen.setCosmetic(true); pen.setCosmetic(true);
max_x = 0.; max_x = 0.;
name = name_; name = name_;
visible = visible_; visible = visible_;
pointWidth = 2.; pointWidth = 2.;
pb = new QCheckBox(name); pb = new QCheckBox(name);
} }
//~GraphicType() {delete pb;} //~GraphicType() {delete pb;}
QString name; QString name;
@@ -72,14 +79,20 @@ struct QAD_GRAPHIC_EXPORT GraphicType {
}; };
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, const GraphicType & v) {
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;} 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 class QAD_GRAPHIC_EXPORT GraphicConf: public QDialog {
{
Q_OBJECT Q_OBJECT
friend class Graphic; friend class Graphic;
public: public:
explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0); explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0);
+6 -7
View File
@@ -1,5 +1,7 @@
#include "graphic.h"
#include "graphicplugin.h" #include "graphicplugin.h"
#include "graphic.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -10,8 +12,7 @@ GraphicPlugin::GraphicPlugin(QObject * parent): QObject(parent) {
void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
m_designer = true; m_designer = true;
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -26,8 +27,7 @@ bool GraphicPlugin::isInitialized() const {
QWidget * GraphicPlugin::createWidget(QWidget * parent) { QWidget * GraphicPlugin::createWidget(QWidget * parent) {
auto ret = new Graphic(parent); auto ret = new Graphic(parent);
if (m_designer) if (m_designer) ret->m_fakeGL = true;
ret->m_fakeGL = true;
return ret; return ret;
} }
@@ -48,7 +48,7 @@ QIcon GraphicPlugin::icon() const {
QString GraphicPlugin::toolTip() const { QString GraphicPlugin::toolTip() const {
return QLatin1String("");//QLatin1String("Widget for display any math graphics with grid and navigation"); return QLatin1String(""); // QLatin1String("Widget for display any math graphics with grid and navigation");
} }
@@ -70,4 +70,3 @@ QString GraphicPlugin::domXml() const {
QString GraphicPlugin::includeFile() const { QString GraphicPlugin::includeFile() const {
return QLatin1String("graphic.h"); return QLatin1String("graphic.h");
} }
+3 -3
View File
@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class GraphicPlugin: public QObject, public QDesignerCustomWidgetInterface class GraphicPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized, m_designer; bool m_initialized, m_designer;
}; };
#endif #endif
+3 -3
View File
@@ -1,13 +1,13 @@
#include "qad_graphic.h" #include "qad_graphic.h"
#include "graphicplugin.h" #include "graphicplugin.h"
QADGraphic::QADGraphic(QObject * parent): QObject(parent) QADGraphic::QADGraphic(QObject * parent): QObject(parent) {
{
m_widgets.append(new GraphicPlugin(this)); m_widgets.append(new GraphicPlugin(this));
} }
QList<QDesignerCustomWidgetInterface * > QADGraphic::customWidgets() const { QList<QDesignerCustomWidgetInterface *> QADGraphic::customWidgets() const {
return m_widgets; return m_widgets;
} }
+7 -6
View File
@@ -1,23 +1,24 @@
#ifndef QAD_GRAPHIC_H #ifndef QAD_GRAPHIC_H
#define QAD_GRAPHIC_H #define QAD_GRAPHIC_H
#include <QtDesigner/QtDesigner>
#include <QtCore/qplugin.h> #include <QtCore/qplugin.h>
#include <QtDesigner/QtDesigner>
class QADGraphic: public QObject, public QDesignerCustomWidgetCollectionInterface class QADGraphic
{ : public QObject
, public QDesignerCustomWidgetCollectionInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "qad.graphic") Q_PLUGIN_METADATA(IID "qad.graphic")
#endif #endif
public: public:
explicit QADGraphic(QObject * parent = 0); explicit QADGraphic(QObject * parent = 0);
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const; virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
private: private:
QList<QDesignerCustomWidgetInterface * > m_widgets; QList<QDesignerCustomWidgetInterface *> m_widgets;
}; };
#endif // QAD_GRAPHIC_H #endif // QAD_GRAPHIC_H
+15 -11
View File
@@ -1,8 +1,8 @@
#ifndef UGLWIDGET_H #ifndef UGLWIDGET_H
#define UGLWIDGET_H #define UGLWIDGET_H
#include <QWidget>
#include <QDebug> #include <QDebug>
#include <QWidget>
#if QT_VERSION >= 0x050400 #if QT_VERSION >= 0x050400
# include <QOpenGLWidget> # include <QOpenGLWidget>
typedef QOpenGLWidget __GLWidget__; typedef QOpenGLWidget __GLWidget__;
@@ -10,32 +10,37 @@ typedef QOpenGLWidget __GLWidget__;
# include <QGLWidget> # include <QGLWidget>
typedef QGLWidget __GLWidget__; typedef QGLWidget __GLWidget__;
# ifndef GL_MULTISAMPLE # ifndef GL_MULTISAMPLE
# define GL_MULTISAMPLE 0x809D # define GL_MULTISAMPLE 0x809D
# endif # endif
#endif #endif
#include "qad_graphic_export.h" #include "qad_graphic_export.h"
class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__ class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__ {
{
Q_OBJECT Q_OBJECT
public: public:
#if QT_VERSION >= 0x050400 #if QT_VERSION >= 0x050400
UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {QSurfaceFormat sf = format(); sf.setSamples(8); setFormat(sf);} UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {
QSurfaceFormat sf = format();
sf.setSamples(8);
setFormat(sf);
}
#else #else
UGLWidget(QWidget * parent = 0): __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {} UGLWidget(QWidget * parent = 0)
: __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {}
#endif #endif
//UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {} // UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {}
#if QT_VERSION >= 0x050400 #if QT_VERSION >= 0x050400
QImage grabFrameBuffer() {return grabFramebuffer();} QImage grabFrameBuffer() { return grabFramebuffer(); }
#endif #endif
protected: protected:
#if QT_VERSION >= 0x050400 #if QT_VERSION >= 0x050400
virtual void paintGL() {emit paintSignal();} virtual void paintGL() { emit paintSignal(); }
#else #else
virtual void paintEvent(QPaintEvent * ) {emit paintSignal();} virtual void paintEvent(QPaintEvent *) { emit paintSignal(); }
#endif #endif
virtual void resizeEvent(QResizeEvent * e) { virtual void resizeEvent(QResizeEvent * e) {
__GLWidget__::resizeEvent(e); __GLWidget__::resizeEvent(e);
@@ -63,7 +68,6 @@ signals:
void wheelEvent(QWheelEvent * e); void wheelEvent(QWheelEvent * e);
void resizeSignal(); void resizeSignal();
void paintSignal(); void paintSignal();
}; };
#endif #endif
+7 -7
View File
@@ -1,17 +1,18 @@
#ifndef UWIDGET_H #ifndef UWIDGET_H
#define UWIDGET_H #define UWIDGET_H
#include <QWidget> #include "qad_graphic_export.h"
#include <QEvent>
#include <QPainter> #include <QPainter>
#include <QStyle> #include <QStyle>
#include <QStyleOption> #include <QStyleOption>
#include <QEvent> #include <QWidget>
#include "qad_graphic_export.h"
class QAD_GRAPHIC_EXPORT UWidget: public QWidget class QAD_GRAPHIC_EXPORT UWidget: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
UWidget(QWidget * parent = 0): QWidget(parent) {} UWidget(QWidget * parent = 0): QWidget(parent) {}
@@ -27,7 +28,7 @@ private:
#endif #endif
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
emit paintEvent((QPaintEvent * )e); emit paintEvent((QPaintEvent *)e);
return true; return true;
} }
@@ -51,7 +52,6 @@ signals:
void showEvent(QShowEvent * e); void showEvent(QShowEvent * e);
void wheelEvent(QWheelEvent * e); void wheelEvent(QWheelEvent * e);
void paintEvent(QPaintEvent * e); void paintEvent(QPaintEvent * e);
}; };
#endif #endif
+10 -8
View File
@@ -1,14 +1,16 @@
#include "piqt.h" #include "piqt.h"
#include "qvariantedit.h" #include "qvariantedit.h"
#ifdef PIQT_HAS_GEOPOSITION #ifdef PIQT_HAS_GEOPOSITION
# include <QGeoCoordinate>
# include "pigeoposition.h" # include "pigeoposition.h"
# include <QGeoCoordinate>
#endif #endif
const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el) { const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el) {
QAD::Enum ret; QAD::Enum ret;
piForeachC (PIVariantTypes::Enumerator & e, el.enum_list) piForeachC(PIVariantTypes::Enumerator & e, el.enum_list)
ret << QAD::Enumerator(e.value, PI2QString(e.name)); ret << QAD::Enumerator(e.value, PI2QString(e.name));
ret.selectValue(el.selectedValue()); ret.selectValue(el.selectedValue());
return ret; return ret;
@@ -17,7 +19,7 @@ const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el) {
const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el) { const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el) {
PIVariantTypes::Enum ret; PIVariantTypes::Enum ret;
foreach (const QAD::Enumerator & e, el.enum_list) foreach(const QAD::Enumerator & e, el.enum_list)
ret << PIVariantTypes::Enumerator(e.value, Q2PIString(e.name)); ret << PIVariantTypes::Enumerator(e.value, Q2PIString(e.name));
ret.selectValue(el.selectedValue()); ret.selectValue(el.selectedValue());
return ret; return ret;
@@ -54,7 +56,7 @@ const QVariant PI2QVariant(const PIVariant & v) {
case PIVariant::pivIODevice: return QVariant::fromValue(PI2QADIODevice(v.toIODevice())); case PIVariant::pivIODevice: return QVariant::fromValue(PI2QADIODevice(v.toIODevice()));
case PIVariant::pivMathVector: return QVariant::fromValue(PI2QMathVector(v.toMathVector())); case PIVariant::pivMathVector: return QVariant::fromValue(PI2QMathVector(v.toMathVector()));
case PIVariant::pivMathMatrix: return QVariant::fromValue(PI2QMathMatrix(v.toMathMatrix())); case PIVariant::pivMathMatrix: return QVariant::fromValue(PI2QMathMatrix(v.toMathMatrix()));
//case PIVariant::pivSystemTime: return QVariant(v.to()); // case PIVariant::pivSystemTime: return QVariant(v.to());
default: return QVariant(); default: return QVariant();
} }
return QVariant(); return QVariant();
@@ -168,13 +170,13 @@ const PIVariant Q2PIVariant(const QVariant & v) {
case QMetaType::QLine: case QMetaType::QLine:
case QMetaType::QLineF: case QMetaType::QLineF:
#endif #endif
return PIVariant(Q2PILine(v.toLineF())); return PIVariant(Q2PILine(v.toLineF()));
default: break; default: break;
} }
if (v.canConvert<float>()) return PIVariant(v.value<float>()); if (v.canConvert<float>()) return PIVariant(v.value<float>());
if (v.canConvert<QAD::Enum>()) return PIVariant(QAD2PIEnum(v.value<QAD::Enum>())); if (v.canConvert<QAD::Enum>()) return PIVariant(QAD2PIEnum(v.value<QAD::Enum>()));
if (v.canConvert<QAD::File>()) return PIVariant(QAD2PIFile(v.value<QAD::File>())); if (v.canConvert<QAD::File>()) return PIVariant(QAD2PIFile(v.value<QAD::File>()));
if (v.canConvert<QAD::Dir>()) return PIVariant(QAD2PIDir(v.value<QAD::Dir>())); if (v.canConvert<QAD::Dir>()) return PIVariant(QAD2PIDir(v.value<QAD::Dir>()));
if (v.canConvert<QAD::IODevice>()) return PIVariant(QAD2PIIODevice(v.value<QAD::IODevice>())); if (v.canConvert<QAD::IODevice>()) return PIVariant(QAD2PIIODevice(v.value<QAD::IODevice>()));
if (v.canConvert<QAD::MathVector>()) return PIVariant(Q2PIMathVector(v.value<QAD::MathVector>())); if (v.canConvert<QAD::MathVector>()) return PIVariant(Q2PIMathVector(v.value<QAD::MathVector>()));
if (v.canConvert<QAD::MathMatrix>()) return PIVariant(Q2PIMathMatrix(v.value<QAD::MathMatrix>())); if (v.canConvert<QAD::MathMatrix>()) return PIVariant(Q2PIMathMatrix(v.value<QAD::MathMatrix>()));
@@ -185,8 +187,8 @@ const PIVariant Q2PIVariant(const QVariant & v) {
const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v) { const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v) {
PIVariantTypes::IODevice d; PIVariantTypes::IODevice d;
d.set(Q2PIPropertyStorage(v.props)); d.set(Q2PIPropertyStorage(v.props));
d.prefix = Q2PIString(v.prefix); d.prefix = Q2PIString(v.prefix);
d.mode = v.mode; d.mode = v.mode;
d.options = v.options; d.options = v.options;
return d; return d;
} }
+532 -190
View File
@@ -1,43 +1,43 @@
/* /*
PIQt - PIP <-> Qt convertions PIQt - PIP <-> Qt convertions
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PIQT_H #ifndef PIQT_H
#define PIQT_H #define PIQT_H
#include <QVector3D>
#include <QPolygonF>
#include <QDateTime>
#include <QColor>
#include <QImage>
#include "pimathmatrix.h" #include "pimathmatrix.h"
#include "pipropertystorage.h" #include "pipropertystorage.h"
#include "qad_types.h"
#include "piqt_macros.h" #include "piqt_macros.h"
#include "qad_types.h"
#include <QColor>
#include <QDateTime>
#include <QImage>
#include <QPolygonF>
#include <QVector3D>
#if QT_VERSION_MAJOR == 5 #if QT_VERSION_MAJOR == 5
# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
# define PIQT_HAS_GEOPOSITION # define PIQT_HAS_GEOPOSITION
# endif # endif
#endif #endif
#if QT_VERSION_MAJOR == 6 #if QT_VERSION_MAJOR == 6
# if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) # if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
# define PIQT_HAS_GEOPOSITION # define PIQT_HAS_GEOPOSITION
# endif # endif
#endif #endif
#ifdef PIQT_HAS_GEOPOSITION #ifdef PIQT_HAS_GEOPOSITION
@@ -50,114 +50,187 @@ class PIGeoPosition;
QAD_PIQT_EXPORT const QVariant PI2QVariant(const PIVariant & v); QAD_PIQT_EXPORT const QVariant PI2QVariant(const PIVariant & v);
QAD_PIQT_EXPORT const PIVariant Q2PIVariant(const QVariant & v); QAD_PIQT_EXPORT const PIVariant Q2PIVariant(const QVariant & v);
//inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());} // inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());}
inline const QString PI2QString(const PIString & v) {return QString::fromUtf8(v.dataUTF8());} inline const QString PI2QString(const PIString & v) {
#if PIP_VERSION >= PIP_MAKE_VERSION(2,38,0) return QString::fromUtf8(v.dataUTF8());
inline const QString PI2QString(const PIConstChars & v) {return QString::fromLatin1(v.data(), v.length());} }
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 38, 0)
inline const QString PI2QString(const PIConstChars & v) {
return QString::fromLatin1(v.data(), v.length());
}
#endif #endif
//inline const PIString Q2PIString(const QString & v) {return PIString(v.toLocal8Bit().data());} // inline const PIString Q2PIString(const QString & v) {return PIString(v.toLocal8Bit().data());}
inline const PIString Q2PIString(const QString & v) {return PIString::fromUTF8(v.toUtf8().data());} inline const PIString Q2PIString(const QString & v) {
return PIString::fromUTF8(v.toUtf8().data());
}
inline const QStringList PI2QStringList(const PIStringList & v) {QStringList ret; piForeachC (PIString & s, v) ret << PI2QString(s); return ret;} inline const QStringList PI2QStringList(const PIStringList & v) {
QStringList ret;
piForeachC(PIString & s, v)
ret << PI2QString(s);
return ret;
}
inline const PIStringList Q2PIStringList(const QStringList & v) {PIStringList ret; foreach (const QString & s, v) ret << Q2PIString(s); return ret;} inline const PIStringList Q2PIStringList(const QStringList & v) {
PIStringList ret;
foreach(const QString & s, v)
ret << Q2PIString(s);
return ret;
}
inline const QByteArray PI2QByteArray(const PIByteArray & v) {return QByteArray((const char *)(v.data()), v.size_s());} inline const QByteArray PI2QByteArray(const PIByteArray & v) {
return QByteArray((const char *)(v.data()), v.size_s());
}
inline const PIByteArray Q2PIByteArray(const QByteArray & v) {return PIByteArray(v.constData(), v.size());} inline const PIByteArray Q2PIByteArray(const QByteArray & v) {
return PIByteArray(v.constData(), v.size());
}
inline const QPointF PI2QVector2(const PIMathVectorT2d & v) {return QPointF(v[0], v[1]);} inline const QPointF PI2QVector2(const PIMathVectorT2d & v) {
inline const QVector3D PI2QVector3(const PIMathVectorT3d & v) {return QVector3D(v[0], v[1], v[2]);} return QPointF(v[0], v[1]);
}
inline const QVector3D PI2QVector3(const PIMathVectorT3d & v) {
return QVector3D(v[0], v[1], v[2]);
}
inline const PIMathVectorT2d Q2PIVector2(const QPointF & v) {return PIMathVectorT2d({double(v.x()), double(v.y())});} inline const PIMathVectorT2d Q2PIVector2(const QPointF & v) {
inline const PIMathVectorT3d Q2PIVector3(const QVector3D & v) {return PIMathVectorT3d({double(v.x()), double(v.y()), double(v.z())});} return PIMathVectorT2d({double(v.x()), double(v.y())});
}
inline const PIMathVectorT3d Q2PIVector3(const QVector3D & v) {
return PIMathVectorT3d({double(v.x()), double(v.y()), double(v.z())});
}
inline const QPointF PI2QPoint(const PIPointd & v) {return QPointF(v.x, v.y);} inline const QPointF PI2QPoint(const PIPointd & v) {
inline const PIPointd Q2PIPoint(const QPointF & v) {return PIPointd(v.x(), v.y());} return QPointF(v.x, v.y);
}
inline const PIPointd Q2PIPoint(const QPointF & v) {
return PIPointd(v.x(), v.y());
}
inline const QRectF PI2QRect(const PIRectd & v) {return QRectF(v.left(), v.bottom(), v.width(), v.height());} inline const QRectF PI2QRect(const PIRectd & v) {
inline const PIRectd Q2PIRect(const QRectF & v) {return PIRectd(v.left(), v.top(), v.width(), v.height());} return QRectF(v.left(), v.bottom(), v.width(), v.height());
}
inline const PIRectd Q2PIRect(const QRectF & v) {
return PIRectd(v.left(), v.top(), v.width(), v.height());
}
inline const QLineF PI2QLine(const PILined & v) {return QLineF(PI2QPoint(v.p0), PI2QPoint(v.p1));} inline const QLineF PI2QLine(const PILined & v) {
inline const PILined Q2PILine(const QLineF & v) {return PILined(Q2PIPoint(v.p1()), Q2PIPoint(v.p2()));} return QLineF(PI2QPoint(v.p0), PI2QPoint(v.p1));
}
inline const PILined Q2PILine(const QLineF & v) {
return PILined(Q2PIPoint(v.p1()), Q2PIPoint(v.p2()));
}
inline const QAD::MathVector PI2QMathVector(const PIMathVectord & v) { inline const QAD::MathVector PI2QMathVector(const PIMathVectord & v) {
QVector<double> q = QVector<double>(v.size()); QVector<double> q = QVector<double>(v.size());
memcpy(q.data(), v.data(), q.size()*sizeof(double)); memcpy(q.data(), v.data(), q.size() * sizeof(double));
return QAD::MathVector(q); return QAD::MathVector(q);
} }
inline const PIMathVectord Q2PIMathVector(const QAD::MathVector & v) { inline const PIMathVectord Q2PIMathVector(const QAD::MathVector & v) {
PIMathVectord p = PIMathVectord(v.v.size()); PIMathVectord p = PIMathVectord(v.v.size());
memcpy(p.data(), v.v.data(), p.size()*sizeof(double)); memcpy(p.data(), v.v.data(), p.size() * sizeof(double));
return p; return p;
} }
inline const QAD::MathMatrix PI2QMathMatrix(const PIMathMatrixd & v) { inline const QAD::MathMatrix PI2QMathMatrix(const PIMathMatrixd & v) {
PIVector<PIVector<double> > p = v.toVectors(); PIVector<PIVector<double>> p = v.toVectors();
QVector<QVector<double> > q = QVector<QVector<double> >(p.size()); QVector<QVector<double>> q = QVector<QVector<double>>(p.size());
for (int i = 0; i < q.size(); ++i) { for (int i = 0; i < q.size(); ++i) {
q[i].resize(p[i].size()); q[i].resize(p[i].size());
memcpy(q[i].data(), p[i].data(), q[i].size()*sizeof(double)); memcpy(q[i].data(), p[i].data(), q[i].size() * sizeof(double));
} }
return QAD::MathMatrix(q); return QAD::MathMatrix(q);
} }
inline const PIMathMatrixd Q2PIMathMatrix(const QAD::MathMatrix & v) { inline const PIMathMatrixd Q2PIMathMatrix(const QAD::MathMatrix & v) {
PIVector<PIVector<double> > p = PIVector<PIVector<double> >(v.m.size()); PIVector<PIVector<double>> p = PIVector<PIVector<double>>(v.m.size());
for (int i = 0; i < v.m.size(); ++i) { for (int i = 0; i < v.m.size(); ++i) {
p[i].resize(v.m[i].size()); p[i].resize(v.m[i].size());
memcpy(p[i].data(), v.m[i].data(), p[i].size()*sizeof(double)); memcpy(p[i].data(), v.m[i].data(), p[i].size() * sizeof(double));
} }
return PIMathMatrixd(p); return PIMathMatrixd(p);
} }
inline const QDate PI2QDate(const PIDate & v) {return QDate(v.year, v.month, v.day);} inline const QDate PI2QDate(const PIDate & v) {
inline const QTime PI2QTime(const PITime & v) {return QTime(v.hours, v.minutes, v.seconds, v.milliseconds);} return QDate(v.year, v.month, v.day);
inline const QDateTime PI2QDateTime(const PIDateTime & v) {return QDateTime(PI2QDate(v.date()), PI2QTime(v.time()));} }
inline const QTime PI2QTime(const PITime & v) {
return QTime(v.hours, v.minutes, v.seconds, v.milliseconds);
}
inline const QDateTime PI2QDateTime(const PIDateTime & v) {
return QDateTime(PI2QDate(v.date()), PI2QTime(v.time()));
}
inline const PIDate Q2PIDate(const QDate & v) {return PIDate(v.year(), v.month(), v.day());} inline const PIDate Q2PIDate(const QDate & v) {
inline const PITime Q2PITime(const QTime & v) {return PITime(v.hour(), v.minute(), v.second(), v.msec());} return PIDate(v.year(), v.month(), v.day());
inline const PIDateTime Q2PIDateTime(const QDateTime & v) {return PIDateTime(Q2PIDate(v.date()), Q2PITime(v.time()));} }
inline const PITime Q2PITime(const QTime & v) {
return PITime(v.hour(), v.minute(), v.second(), v.msec());
}
inline const PIDateTime Q2PIDateTime(const QDateTime & v) {
return PIDateTime(Q2PIDate(v.date()), Q2PITime(v.time()));
}
inline const QColor PI2QColor(const PIVariantTypes::Color & v) {return QColor::fromRgba(v.rgba);} inline const QColor PI2QColor(const PIVariantTypes::Color & v) {
inline const PIVariantTypes::Color Q2PIColor(const QColor & v) {return PIVariantTypes::Color(v.rgba());} return QColor::fromRgba(v.rgba);
}
inline const PIVariantTypes::Color Q2PIColor(const QColor & v) {
return PIVariantTypes::Color(v.rgba());
}
template<typename T> template<typename T>
inline const QVector<T> PI2QVector(const PIVector<T> & v) {QVector<T> ret; ret.reserve(v.size_s()); for (int i = 0; i < v.size_s(); ++i) ret << v[i]; return ret;} inline const QVector<T> PI2QVector(const PIVector<T> & v) {
QVector<T> ret;
ret.reserve(v.size_s());
for (int i = 0; i < v.size_s(); ++i)
ret << v[i];
return ret;
}
template<typename T> template<typename T>
inline const PIVector<T> Q2PIVector(const QVector<T> & v) {if (v.isEmpty()) return PIVector<T>(); return PIVector<T>(v.constData(), (size_t)v.size());} inline const PIVector<T> Q2PIVector(const QVector<T> & v) {
if (v.isEmpty()) return PIVector<T>();
return PIVector<T>(v.constData(), (size_t)v.size());
}
template <typename K, typename T> template<typename K, typename T>
inline QMap<K, T> PI2QMap(const PIMap<K, T> & v) { inline QMap<K, T> PI2QMap(const PIMap<K, T> & v) {
QMap<K, T> ret; QMap<K, T> ret;
auto it = v.makeIterator(); auto it = v.makeIterator();
while (it.hasNext()) {it.next(); ret[it.key()] = it.value();} while (it.hasNext()) {
return ret;} it.next();
template <typename K, typename T> ret[it.key()] = it.value();
}
return ret;
}
template<typename K, typename T>
inline PIMap<K, T> Q2PIMap(const QMap<K, T> & v) { inline PIMap<K, T> Q2PIMap(const QMap<K, T> & v) {
PIMap<K, T> ret; PIMap<K, T> ret;
ret.reserve((size_t)v.size()); ret.reserve((size_t)v.size());
QMapIterator<K, T> it(v); QMapIterator<K, T> it(v);
while (it.hasNext()) {it.next(); ret[it.key()] = it.value();} while (it.hasNext()) {
return ret;} it.next();
ret[it.key()] = it.value();
}
return ret;
}
inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) { inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) {
PIPropertyStorage ret; PIPropertyStorage ret;
foreach (const PropertyStorage::Property & p, props) foreach(const PropertyStorage::Property & p, props)
ret.addProperty(Q2PIString(p.name), Q2PIVariant(p.value), Q2PIString(p.comment), p.flags); ret.addProperty(Q2PIString(p.name), Q2PIVariant(p.value), Q2PIString(p.comment), p.flags);
return ret; return ret;
} }
inline PropertyStorage PI2QPropertyStorage(const PIPropertyStorage & props) { inline PropertyStorage PI2QPropertyStorage(const PIPropertyStorage & props) {
PropertyStorage ret; PropertyStorage ret;
piForeachC (PIPropertyStorage::Property & p, props) piForeachC(PIPropertyStorage::Property & p, props)
ret.addProperty(PI2QString(p.name), PI2QVariant(p.value), PI2QString(p.comment), p.flags); ret.addProperty(PI2QString(p.name), PI2QVariant(p.value), PI2QString(p.comment), p.flags);
return ret; return ret;
} }
@@ -172,186 +245,451 @@ QAD_PIQT_EXPORT const PIVariantTypes::File QAD2PIFile(const QAD::File & v);
QAD_PIQT_EXPORT const PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v); QAD_PIQT_EXPORT const PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v);
QAD_PIQT_EXPORT const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v); QAD_PIQT_EXPORT const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v);
//inline const PIVariant QString2PIVariant(const QString & v) {return PIVariant::readFromString(QString2PIString(v));} // inline const PIVariant QString2PIVariant(const QString & v) {return PIVariant::readFromString(QString2PIString(v));}
#ifdef PIQT_HAS_GEOPOSITION #ifdef PIQT_HAS_GEOPOSITION
QAD_PIQT_EXPORT const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v); QAD_PIQT_EXPORT const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v);
QAD_PIQT_EXPORT const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v); QAD_PIQT_EXPORT const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v);
#endif #endif
template <typename From> template<typename From>
class __PIQtConverter { class __PIQtConverter {
public: public:
__PIQtConverter(const From & v): val(v) {} __PIQtConverter(const From & v): val(v) {}
template <typename To> operator To() {return To();} template<typename To>
operator To() {
return To();
}
From val; From val;
}; };
template<typename From> inline __PIQtConverter<From> __PIQtConvert(const From & f) {return __PIQtConverter<From>(f);} template<typename From>
inline __PIQtConverter<From> __PIQtConvert(const From & f) {
return __PIQtConverter<From>(f);
}
#define _PIQt_CONVERT(ft, tt, ftc, tfc) \ #define _PIQt_CONVERT(ft, tt, ftc, tfc) \
template<> template<> inline __PIQtConverter<ft>::operator tt() {return ftc(val);} \ template<> \
template<> template<> inline __PIQtConverter<tt>::operator ft() {return tfc(val);} template<> \
inline __PIQtConverter<ft>::operator tt() { \
return ftc(val); \
} \
template<> \
template<> \
inline __PIQtConverter<tt>::operator ft() { \
return tfc(val); \
}
#define _PIQt_CONVERT_S(t) _PIQt_CONVERT(PI##t, Q##t, PI2Q##t, Q2PI##t) #define _PIQt_CONVERT_S(t) _PIQt_CONVERT(PI##t, Q##t, PI2Q##t, Q2PI##t)
_PIQt_CONVERT_S(String) _PIQt_CONVERT_S(String) _PIQt_CONVERT_S(ByteArray) _PIQt_CONVERT_S(Time) _PIQt_CONVERT_S(Date) _PIQt_CONVERT_S(DateTime)
_PIQt_CONVERT_S(ByteArray) _PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2) _PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3)
_PIQt_CONVERT_S(Time)
_PIQt_CONVERT_S(Date)
_PIQt_CONVERT_S(DateTime)
_PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2)
_PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3)
#define piqt __PIQtConvert #define piqt __PIQtConvert
#define qtpi __PIQtConvert #define qtpi __PIQtConvert
#ifndef PIP_BINARY_STREAM #ifndef PIP_BINARY_STREAM
inline PIByteArray & operator <<(PIByteArray & s, const QString & v) {s << Q2PIString(v); return s;} inline PIByteArray &
inline PIByteArray & operator >>(PIByteArray & s, QString & v) {PIString t; s >> t; v = PI2QString(t); return s;} operator<<(PIByteArray & s, const QString & v) {
inline PIByteArray & operator <<(PIByteArray & s, const QStringList & v) {s << Q2PIStringList(v); return s;} s << Q2PIString(v);
inline PIByteArray & operator >>(PIByteArray & s, QStringList & v) {PIStringList t; s >> t; v = PI2QStringList(t); return s;} return s;
template <typename T> inline PIByteArray & operator <<(PIByteArray & s, const QVector<T> & v) {s << PIVector<T>(v.constData(), (size_t)v.size()); return s;} }
template <typename T> inline PIByteArray & operator >>(PIByteArray & s, QVector<T> & v) { inline PIByteArray & operator>>(PIByteArray & s, QString & v) {
PIVector<T> t; s >> t; PIString t;
v.resize(t.size_s()); s >> t;
for (int i = 0; i < t.size_s(); ++i) v = PI2QString(t);
v[i] = t[i]; return s;
return s;} }
template <typename K, typename T> inline PIByteArray & operator <<(PIByteArray & s, const QMap<K, T> & v) { inline PIByteArray & operator<<(PIByteArray & s, const QStringList & v) {
PIMap<K, T> t; s << Q2PIStringList(v);
t.reserve(v.size()); return s;
QMapIterator<K, T> it(v); }
while (it.hasNext()) {it.next(); t[it.key()] = it.value();} inline PIByteArray & operator>>(PIByteArray & s, QStringList & v) {
s << t; PIStringList t;
return s;} s >> t;
template <typename K, typename T> inline PIByteArray & operator >>(PIByteArray & s, QMap<K, T> & v) { v = PI2QStringList(t);
v.clear(); return s;
PIMap<K, T> t; s >> t; }
auto it = t.makeIterator(); template<typename T>
while (it.hasNext()) {it.next(); v[it.key()] = it.value();} inline PIByteArray & operator<<(PIByteArray & s, const QVector<T> & v) {
return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QPolygonF & v) {s << (QVector<QPointF>)v; return s;}
inline PIByteArray & operator >>(PIByteArray & s, QPolygonF & v) {QVector<QPointF> t; s >> t; v = t; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QByteArray & v) {s << Q2PIByteArray(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QByteArray & v) {PIByteArray t; s >> t; v = PI2QByteArray(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QDate & v) {s << Q2PIDate(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QDate & v) {PIDate t; s >> t; v = PI2QDate(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QTime & v) {s << Q2PITime(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QTime & v) {PITime t; s >> t; v = PI2QTime(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QDateTime & v) {s << Q2PIDateTime(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QDateTime & v) {PIDateTime t; s >> t; v = PI2QDateTime(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QVariant & v) {s << Q2PIVariant(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QVariant & v) {PIVariant t; s >> t; v = PI2QVariant(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PropertyStorage & v) {s << Q2PIPropertyStorage(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, PropertyStorage & v) {PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QColor & v) {s << Q2PIColor(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QColor & v) {PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::Enum & v) {s << QAD2PIEnum(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::Enum & v) {PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::File & v) {s << QAD2PIFile(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::File & v) {PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::Dir & v) {s << QAD2PIDir(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::Dir & v) {PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::IODevice & v) {s << QAD2PIIODevice(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::IODevice & v) {PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QImage & v) {
QByteArray ba; QBuffer buf(&ba);
v.save(&buf, "png");
s << Q2PIByteArray(ba);
return s;}
inline PIByteArray & operator >>(PIByteArray & s, QImage & v) {
PIByteArray pba; s >> pba;
QByteArray ba = PI2QByteArray(pba);
if (!v.loadFromData(ba, "png"))
v = QImage();
return s;}
#else
template<typename P, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const QVector<T> & v) {
s << PIVector<T>(v.constData(), (size_t)v.size()); s << PIVector<T>(v.constData(), (size_t)v.size());
return s; return s;
} }
template<typename P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, QVector<T> & v) { template<typename T>
PIVector<T> t; s >> t; inline PIByteArray & operator>>(PIByteArray & s, QVector<T> & v) {
PIVector<T> t;
s >> t;
v.resize(t.size_s());
for (int i = 0; i < t.size_s(); ++i)
v[i] = t[i];
return s;
}
template<typename K, typename T>
inline PIByteArray & operator<<(PIByteArray & s, const QMap<K, T> & v) {
PIMap<K, T> t;
t.reserve(v.size());
QMapIterator<K, T> it(v);
while (it.hasNext()) {
it.next();
t[it.key()] = it.value();
}
s << t;
return s;
}
template<typename K, typename T>
inline PIByteArray & operator>>(PIByteArray & s, QMap<K, T> & v) {
v.clear();
PIMap<K, T> t;
s >> t;
auto it = t.makeIterator();
while (it.hasNext()) {
it.next();
v[it.key()] = it.value();
}
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QPolygonF & v) {
s << (QVector<QPointF>)v;
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QPolygonF & v) {
QVector<QPointF> t;
s >> t;
v = t;
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QByteArray & v) {
s << Q2PIByteArray(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QByteArray & v) {
PIByteArray t;
s >> t;
v = PI2QByteArray(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QDate & v) {
s << Q2PIDate(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QDate & v) {
PIDate t;
s >> t;
v = PI2QDate(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QTime & v) {
s << Q2PITime(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QTime & v) {
PITime t;
s >> t;
v = PI2QTime(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QDateTime & v) {
s << Q2PIDateTime(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QDateTime & v) {
PIDateTime t;
s >> t;
v = PI2QDateTime(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QVariant & v) {
s << Q2PIVariant(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QVariant & v) {
PIVariant t;
s >> t;
v = PI2QVariant(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const PropertyStorage & v) {
s << Q2PIPropertyStorage(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, PropertyStorage & v) {
PIPropertyStorage t;
s >> t;
v = PI2QPropertyStorage(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QColor & v) {
s << Q2PIColor(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QColor & v) {
PIVariantTypes::Color t;
s >> t;
v = PI2QColor(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::Enum & v) {
s << QAD2PIEnum(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::Enum & v) {
PIVariantTypes::Enum t;
s >> t;
v = PI2QADEnum(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::File & v) {
s << QAD2PIFile(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::File & v) {
PIVariantTypes::File t;
s >> t;
v = PI2QADFile(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::Dir & v) {
s << QAD2PIDir(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::Dir & v) {
PIVariantTypes::Dir t;
s >> t;
v = PI2QADDir(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::IODevice & v) {
s << QAD2PIIODevice(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::IODevice & v) {
PIVariantTypes::IODevice t;
s >> t;
v = PI2QADIODevice(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QImage & v) {
QByteArray ba;
QBuffer buf(&ba);
v.save(&buf, "png");
s << Q2PIByteArray(ba);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QImage & v) {
PIByteArray pba;
s >> pba;
QByteArray ba = PI2QByteArray(pba);
if (!v.loadFromData(ba, "png")) v = QImage();
return s;
}
#else
template<typename P, typename T>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const QVector<T> & v) {
s << PIVector<T>(v.constData(), (size_t)v.size());
return s;
}
template<typename P, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, QVector<T> & v) {
PIVector<T> t;
s >> t;
v.resize(t.size_s()); v.resize(t.size_s());
for (int i = 0; i < t.size_s(); ++i) for (int i = 0; i < t.size_s(); ++i)
v[i] = t[i]; v[i] = t[i];
return s; return s;
} }
template<typename P, typename K, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const QMap<K, T> & v) { template<typename P, typename K, typename T>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const QMap<K, T> & v) {
PIMap<K, T> t; PIMap<K, T> t;
t.reserve(v.size()); t.reserve(v.size());
QMapIterator<K, T> it(v); QMapIterator<K, T> it(v);
while (it.hasNext()) {it.next(); t[it.key()] = it.value();} while (it.hasNext()) {
it.next();
t[it.key()] = it.value();
}
s << t; s << t;
return s; return s;
} }
template<typename P, typename K, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, QMap<K, T> & v) { template<typename P, typename K, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, QMap<K, T> & v) {
v.clear(); v.clear();
PIMap<K, T> t; s >> t; PIMap<K, T> t;
s >> t;
auto it = t.makeIterator(); auto it = t.makeIterator();
while (it.hasNext()) {it.next(); v[it.key()] = it.value();} while (it.hasNext()) {
it.next();
v[it.key()] = it.value();
}
return s; return s;
} }
BINARY_STREAM_WRITE(QString) {s << Q2PIString(v); return s;} BINARY_STREAM_WRITE(QString) {
BINARY_STREAM_READ (QString) {PIString t; s >> t; v = PI2QString(t); return s;} s << Q2PIString(v);
return s;
}
BINARY_STREAM_READ(QString) {
PIString t;
s >> t;
v = PI2QString(t);
return s;
}
BINARY_STREAM_WRITE(QStringList) {s << Q2PIStringList(v); return s;} BINARY_STREAM_WRITE(QStringList) {
BINARY_STREAM_READ (QStringList) {PIStringList t; s >> t; v = PI2QStringList(t); return s;} s << Q2PIStringList(v);
return s;
}
BINARY_STREAM_READ(QStringList) {
PIStringList t;
s >> t;
v = PI2QStringList(t);
return s;
}
BINARY_STREAM_WRITE(QPolygonF) {s << (QVector<QPointF>)v; return s;} BINARY_STREAM_WRITE(QPolygonF) {
BINARY_STREAM_READ (QPolygonF) {QVector<QPointF> t; s >> t; v = t; return s;} s << (QVector<QPointF>)v;
return s;
}
BINARY_STREAM_READ(QPolygonF) {
QVector<QPointF> t;
s >> t;
v = t;
return s;
}
BINARY_STREAM_WRITE(QByteArray) {s << Q2PIByteArray(v); return s;} BINARY_STREAM_WRITE(QByteArray) {
BINARY_STREAM_READ (QByteArray) {PIByteArray t; s >> t; v = PI2QByteArray(t); return s;} s << Q2PIByteArray(v);
return s;
}
BINARY_STREAM_READ(QByteArray) {
PIByteArray t;
s >> t;
v = PI2QByteArray(t);
return s;
}
BINARY_STREAM_WRITE(QDate) {s << Q2PIDate(v); return s;} BINARY_STREAM_WRITE(QDate) {
BINARY_STREAM_READ (QDate) {PIDate t; s >> t; v = PI2QDate(t); return s;} s << Q2PIDate(v);
return s;
}
BINARY_STREAM_READ(QDate) {
PIDate t;
s >> t;
v = PI2QDate(t);
return s;
}
BINARY_STREAM_WRITE(QTime) {s << Q2PITime(v); return s;} BINARY_STREAM_WRITE(QTime) {
BINARY_STREAM_READ (QTime) {PITime t; s >> t; v = PI2QTime(t); return s;} s << Q2PITime(v);
return s;
}
BINARY_STREAM_READ(QTime) {
PITime t;
s >> t;
v = PI2QTime(t);
return s;
}
BINARY_STREAM_WRITE(QDateTime) {s << Q2PIDateTime(v); return s;} BINARY_STREAM_WRITE(QDateTime) {
BINARY_STREAM_READ (QDateTime) {PIDateTime t; s >> t; v = PI2QDateTime(t); return s;} s << Q2PIDateTime(v);
return s;
}
BINARY_STREAM_READ(QDateTime) {
PIDateTime t;
s >> t;
v = PI2QDateTime(t);
return s;
}
BINARY_STREAM_WRITE(QVariant) {s << Q2PIVariant(v); return s;} BINARY_STREAM_WRITE(QVariant) {
BINARY_STREAM_READ (QVariant) {PIVariant t; s >> t; v = PI2QVariant(t); return s;} s << Q2PIVariant(v);
return s;
}
BINARY_STREAM_READ(QVariant) {
PIVariant t;
s >> t;
v = PI2QVariant(t);
return s;
}
BINARY_STREAM_WRITE(PropertyStorage) {s << Q2PIPropertyStorage(v); return s;} BINARY_STREAM_WRITE(PropertyStorage) {
BINARY_STREAM_READ (PropertyStorage) {PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s;} s << Q2PIPropertyStorage(v);
return s;
}
BINARY_STREAM_READ(PropertyStorage) {
PIPropertyStorage t;
s >> t;
v = PI2QPropertyStorage(t);
return s;
}
BINARY_STREAM_WRITE(QColor) {s << Q2PIColor(v); return s;} BINARY_STREAM_WRITE(QColor) {
BINARY_STREAM_READ (QColor) {PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s;} s << Q2PIColor(v);
return s;
}
BINARY_STREAM_READ(QColor) {
PIVariantTypes::Color t;
s >> t;
v = PI2QColor(t);
return s;
}
BINARY_STREAM_WRITE(QAD::Enum) {s << QAD2PIEnum(v); return s;} BINARY_STREAM_WRITE(QAD::Enum) {
BINARY_STREAM_READ (QAD::Enum) {PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s;} s << QAD2PIEnum(v);
return s;
}
BINARY_STREAM_READ(QAD::Enum) {
PIVariantTypes::Enum t;
s >> t;
v = PI2QADEnum(t);
return s;
}
BINARY_STREAM_WRITE(QAD::File) {s << QAD2PIFile(v); return s;} BINARY_STREAM_WRITE(QAD::File) {
BINARY_STREAM_READ (QAD::File) {PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s;} s << QAD2PIFile(v);
return s;
}
BINARY_STREAM_READ(QAD::File) {
PIVariantTypes::File t;
s >> t;
v = PI2QADFile(t);
return s;
}
BINARY_STREAM_WRITE(QAD::Dir) {s << QAD2PIDir(v); return s;} BINARY_STREAM_WRITE(QAD::Dir) {
BINARY_STREAM_READ (QAD::Dir) {PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s;} s << QAD2PIDir(v);
return s;
}
BINARY_STREAM_READ(QAD::Dir) {
PIVariantTypes::Dir t;
s >> t;
v = PI2QADDir(t);
return s;
}
BINARY_STREAM_WRITE(QAD::IODevice) {s << QAD2PIIODevice(v); return s;} BINARY_STREAM_WRITE(QAD::IODevice) {
BINARY_STREAM_READ (QAD::IODevice) {PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s;} s << QAD2PIIODevice(v);
return s;
}
BINARY_STREAM_READ(QAD::IODevice) {
PIVariantTypes::IODevice t;
s >> t;
v = PI2QADIODevice(t);
return s;
}
BINARY_STREAM_WRITE(QImage) { BINARY_STREAM_WRITE(QImage) {
QByteArray ba; QBuffer buf(&ba); QByteArray ba;
QBuffer buf(&ba);
v.save(&buf, "png"); v.save(&buf, "png");
s << Q2PIByteArray(ba); s << Q2PIByteArray(ba);
return s; return s;
} }
BINARY_STREAM_READ (QImage) { BINARY_STREAM_READ(QImage) {
PIByteArray pba; s >> pba; PIByteArray pba;
s >> pba;
QByteArray ba = PI2QByteArray(pba); QByteArray ba = PI2QByteArray(pba);
if (!v.loadFromData(ba, "png")) if (!v.loadFromData(ba, "png")) v = QImage();
v = QImage();
return s; return s;
} }
@@ -360,7 +698,8 @@ BINARY_STREAM_READ (QImage) {
/// pure Qt /// pure Qt
template <typename T> QByteArray qSerialize(const T & value, int version = -1) { template<typename T>
QByteArray qSerialize(const T & value, int version = -1) {
QByteArray ret; QByteArray ret;
QDataStream s(&ret, QIODevice::ReadWrite); QDataStream s(&ret, QIODevice::ReadWrite);
if (version > 0) s.setVersion((QDataStream::Version)version); if (version > 0) s.setVersion((QDataStream::Version)version);
@@ -368,7 +707,8 @@ template <typename T> QByteArray qSerialize(const T & value, int version = -1) {
return ret; return ret;
} }
template <typename T> T qDeserialize(const QByteArray & data, int version = -1) { template<typename T>
T qDeserialize(const QByteArray & data, int version = -1) {
T ret; T ret;
if (!data.isEmpty()) { if (!data.isEmpty()) {
QDataStream s(data); QDataStream s(data);
@@ -382,13 +722,15 @@ template <typename T> T qDeserialize(const QByteArray & data, int version = -1)
/// PIP with QByteArray /// PIP with QByteArray
template <typename T> QByteArray piqSerialize(const T & value) { template<typename T>
QByteArray piqSerialize(const T & value) {
PIByteArray ret; PIByteArray ret;
ret << value; ret << value;
return PI2QByteArray(ret); return PI2QByteArray(ret);
} }
template <typename T> T piqDeserialize(const QByteArray & data) { template<typename T>
T piqDeserialize(const QByteArray & data) {
T ret; T ret;
if (!data.isEmpty()) { if (!data.isEmpty()) {
PIByteArray ba = Q2PIByteArray(data); PIByteArray ba = Q2PIByteArray(data);
+44 -33
View File
@@ -1,29 +1,30 @@
/* /*
PIQt - PIP <-> Qt convertions PIQt - PIP <-> Qt convertions
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PIQT_MACROS_H #ifndef PIQT_MACROS_H
#define PIQT_MACROS_H #define PIQT_MACROS_H
#include <piobject.h>
#include <QObject>
#include "qad_piqt_export.h" #include "qad_piqt_export.h"
#include <QObject>
#include <piobject.h>
/// connect PIP event "event" of object "src" directly to Qt slot "slot" of object "tgt" /// connect PIP event "event" of object "src" directly to Qt slot "slot" of object "tgt"
/// e.g. PIQCONNECT(&pip_obj, someEvent, &qt_obj, someSlot) /// e.g. PIQCONNECT(&pip_obj, someEvent, &qt_obj, someSlot)
@@ -33,8 +34,7 @@
/// connect PIP event "event" of object "src" to Qt slot "slot" of object "tgt" via Qt::QueuedConnection /// connect PIP event "event" of object "src" to Qt slot "slot" of object "tgt" via Qt::QueuedConnection
/// Note! All argument types must be registered in Qt meta-system! /// Note! All argument types must be registered in Qt meta-system!
/// e.g. PIQCONNECT_QUEUED(&pip_obj, someEvent, &qt_obj, someSlot) /// e.g. PIQCONNECT_QUEUED(&pip_obj, someEvent, &qt_obj, someSlot)
#define PIQCONNECT_QUEUED(src, event, tgt, slot) \ #define PIQCONNECT_QUEUED(src, event, tgt, slot) PIQt::piqConnectQ(src, #event, &(src)->__stat_eh_##event##__, tgt, #slot);
PIQt::piqConnectQ(src, #event, &(src)->__stat_eh_##event##__, tgt, #slot);
/// connect Qt signal "sig" of object "src" directly to PIP event handler "handler" of object "tgt" /// connect Qt signal "sig" of object "src" directly to PIP event handler "handler" of object "tgt"
@@ -46,33 +46,44 @@
namespace PIQt { namespace PIQt {
template<typename T> T removePtr(T*) {} template<typename T>
template<typename T> QArgument<T> qargument(const T & v) { T removePtr(T *) {}
template<typename T>
QArgument<T> qargument(const T & v) {
return QArgument<T>( return QArgument<T>(
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
QMetaType::typeName(qMetaTypeId<T>()) QMetaType::typeName(qMetaTypeId<T>())
#else #else
QMetaType::fromType<T>().name() QMetaType::fromType<T>().name()
#endif #endif
, v);} ,
v);
template <typename SR, typename O, typename... ARGS>
void piqConnect(PIObject * source, const char * event, void(*func)(void*,ARGS...), O * target, SR(O::*slot)(ARGS...)) {
PIObject::piConnectLS(source, PIStringAscii(event), PIObject::__newFunctor(func, [target,slot](ARGS... args){(target->*slot)(args...);}), LOCATION);
} }
template <typename... ARGS> template<typename SR, typename O, typename... ARGS>
void piqConnectQ(PIObject * source, const char * event, void(*func)(void*,ARGS...), QObject * target, const char * slot) { void piqConnect(PIObject * source, const char * event, void (*func)(void *, ARGS...), O * target, SR (O::*slot)(ARGS...)) {
PIObject::piConnectLS(source, PIStringAscii(event), PIObject::__newFunctor(func, [target,slot](ARGS... args){ PIObject::piConnectLS(source,
QMetaObject::invokeMethod(target, slot, Qt::QueuedConnection, qargument(args)...); PIStringAscii(event),
}), LOCATION); PIObject::__newFunctor(func, [target, slot](ARGS... args) { (target->*slot)(args...); }),
LOCATION);
} }
template <typename SR, typename O, typename... ARGS> template<typename... ARGS>
QMetaObject::Connection qpiConnect(O * source, SR(O::*signal)(ARGS...), PIObject * target, void(*handler)(void*,ARGS...)) { void piqConnectQ(PIObject * source, const char * event, void (*func)(void *, ARGS...), QObject * target, const char * slot) {
return QObject::connect(source, signal, source, [target,handler](ARGS... args){handler(target, args...);}); PIObject::piConnectLS(source,
PIStringAscii(event),
PIObject::__newFunctor(func,
[target, slot](ARGS... args) {
QMetaObject::invokeMethod(target, slot, Qt::QueuedConnection, qargument(args)...);
}),
LOCATION);
} }
template<typename SR, typename O, typename... ARGS>
QMetaObject::Connection qpiConnect(O * source, SR (O::*signal)(ARGS...), PIObject * target, void (*handler)(void *, ARGS...)) {
return QObject::connect(source, signal, source, [target, handler](ARGS... args) { handler(target, args...); });
} }
} // namespace PIQt
#endif // PIQT_MACROS_H #endif // PIQT_MACROS_H
+11 -5
View File
@@ -18,13 +18,19 @@ bool QPIConnection::loadFromCMFile(const QString & file) {
void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) { void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) {
//piCout << from << PICoutManipulators::Hex << data; // piCout << from << PICoutManipulators::Hex << data;
QMetaObject::invokeMethod(this, "qDataReceivedEvent", Qt::QueuedConnection, QMetaObject::invokeMethod(this,
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data))); "qDataReceivedEvent",
Qt::QueuedConnection,
Q_ARG(QString, PI2QString(from)),
Q_ARG(QByteArray, PI2QByteArray(data)));
} }
void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) { void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) {
QMetaObject::invokeMethod(this, "qPacketReceivedEvent", Qt::QueuedConnection, QMetaObject::invokeMethod(this,
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data))); "qPacketReceivedEvent",
Qt::QueuedConnection,
Q_ARG(QString, PI2QString(from)),
Q_ARG(QByteArray, PI2QByteArray(data)));
} }
+23 -20
View File
@@ -1,46 +1,50 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef QPICONNECTION_H #ifndef QPICONNECTION_H
#define QPICONNECTION_H #define QPICONNECTION_H
#include <QObject>
#include <QMetaObject>
#include "piconnection.h" #include "piconnection.h"
#include "qpiconfig.h"
#include "piqt.h" #include "piqt.h"
#include "qad_piqt_export.h" #include "qad_piqt_export.h"
#include "qpiconfig.h"
#include <QMetaObject>
#include <QObject>
class QAD_PIQT_EXPORT QPIConnection: public QObject, public PIConnection { class QAD_PIQT_EXPORT QPIConnection
: public QObject
, public PIConnection {
Q_OBJECT Q_OBJECT
PIOBJECT_SUBCLASS(QPIConnection, PIConnection); PIOBJECT_SUBCLASS(QPIConnection, PIConnection);
public: public:
QPIConnection(const QString & name = QString()); QPIConnection(const QString & name = QString());
bool loadFromCMFile(const QString & file); bool loadFromCMFile(const QString & file);
protected: protected:
#if PIP_VERSION >= PIP_MAKE_VERSION(2,38,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 38, 0)
void propertyChanged(const char *) override {setObjectName(PI2QString(name()));} void propertyChanged(const char *) override { setObjectName(PI2QString(name())); }
#else #else
void propertyChanged(const PIString &) override {setObjectName(PI2QString(name()));} void propertyChanged(const PIString &) override { setObjectName(PI2QString(name())); }
#endif #endif
EVENT_HANDLER2(void, piDataRec, const PIString &, from, const PIByteArray &, data); EVENT_HANDLER2(void, piDataRec, const PIString &, from, const PIByteArray &, data);
EVENT_HANDLER2(void, piPacketRec, const PIString &, from, const PIByteArray &, data); EVENT_HANDLER2(void, piPacketRec, const PIString &, from, const PIByteArray &, data);
@@ -50,7 +54,6 @@ public slots:
signals: signals:
void qDataReceivedEvent(QString from, QByteArray data); void qDataReceivedEvent(QString from, QByteArray data);
void qPacketReceivedEvent(QString from, QByteArray data); void qPacketReceivedEvent(QString from, QByteArray data);
}; };
#endif // QPICONNECTION_H #endif // QPICONNECTION_H
+97 -94
View File
@@ -1,9 +1,11 @@
#include "ui_piqt_connection_edit.h"
#include "piqt_connection_edit.h" #include "piqt_connection_edit.h"
#include "picodeinfo.h"
#include "piqt.h"
#include "piqt_connection_view.h" #include "piqt_connection_view.h"
#include "piqt_highlighter.h" #include "piqt_highlighter.h"
#include "piqt.h" #include "ui_piqt_connection_edit.h"
#include "picodeinfo.h"
#include <QCheckBox> #include <QCheckBox>
#include <QMessageBox> #include <QMessageBox>
@@ -13,14 +15,15 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
ui->setupUi(this); ui->setupUi(this);
new ConfigHighlighter(ui->codeEdit->document()); new ConfigHighlighter(ui->codeEdit->document());
loading = false; loading = false;
connect(ui->blockView, SIGNAL(schemeAction(BlockItemBase::Action,QList<QGraphicsItem*>)), this, SLOT(recreateRequest())); connect(ui->blockView, SIGNAL(schemeAction(BlockItemBase::Action, QList<QGraphicsItem *>)), this, SLOT(recreateRequest()));
connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
conn = 0; conn = 0;
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode"); PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
if (ei) { if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
#if PIP_VERSION >= PIP_MAKE_VERSION(2,39,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"),
QVariant::fromValue<int>(e.value));
#else #else
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
#endif #endif
@@ -28,9 +31,9 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1); ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption"); ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
if (ei) { if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) { piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) {
QCheckBox * cb = new QCheckBox(); QCheckBox * cb = new QCheckBox();
#if PIP_VERSION >= PIP_MAKE_VERSION(2,39,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
cb->setText(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")")); cb->setText(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"));
#else #else
cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")")); cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"));
@@ -41,9 +44,10 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
} }
ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode"); ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode");
if (ei) { if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
#if PIP_VERSION >= PIP_MAKE_VERSION(2,39,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ui->comboSplit->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboSplit->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"),
QVariant::fromValue<int>(e.value));
#else #else
ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
#endif #endif
@@ -61,13 +65,15 @@ ConnectionEdit::~ConnectionEdit() {
void ConnectionEdit::accept() { void ConnectionEdit::accept() {
//bool ok = false; // bool ok = false;
QList<BlockItem * > bl = ui->blockView->allDevices(); QList<BlockItem *> bl = ui->blockView->allDevices();
foreach (BlockItem * i, bl) foreach(BlockItem * i, bl)
foreach (BlockItem * j, bl) foreach(BlockItem * j, bl)
if (i != j) if (i != j)
if (((DeviceItem*)i)->name() == ((DeviceItem*)j)->name()) { if (((DeviceItem *)i)->name() == ((DeviceItem *)j)->name()) {
QMessageBox::critical(this, windowTitle() + " - " + tr("error") + "!", tr("Equal devices names: \"%1\"!").arg(((DeviceItem*)i)->name())); QMessageBox::critical(this,
windowTitle() + " - " + tr("error") + "!",
tr("Equal devices names: \"%1\"!").arg(((DeviceItem *)i)->name()));
return; return;
} }
QDialog::accept(); QDialog::accept();
@@ -85,21 +91,19 @@ QByteArray ConnectionEdit::model() const {
QDataStream s(&ret, QIODevice::ReadWrite); QDataStream s(&ret, QIODevice::ReadWrite);
QString cn = PI2QString(conn ? conn->name() : PIString()); QString cn = PI2QString(conn ? conn->name() : PIString());
s << cn; s << cn;
QList<BlockBusItem*> busl = ui->blockView->buses(); QList<BlockBusItem *> busl = ui->blockView->buses();
s << busl.size(); s << busl.size();
foreach (BlockBusItem * b, busl) foreach(BlockBusItem * b, busl)
s << b->save(); s << b->save();
QList<BlockItem*> blockl = ui->blockView->blocks(); QList<BlockItem *> blockl = ui->blockView->blocks();
s << blockl.size(); s << blockl.size();
foreach (BlockItem * b, blockl) { foreach(BlockItem * b, blockl) {
int type = b->propertyByName("__type").value.toInt(); int type = b->propertyByName("__type").value.toInt();
s << type; s << type;
switch (type) { switch (type) {
case __CV_Device: case __CV_Device:
case __CV_Filter: case __CV_Filter:
case __CV_Sender: case __CV_Sender: s << b->save(); break;
s << b->save();
break;
} }
} }
return ret; return ret;
@@ -136,7 +140,9 @@ void ConnectionEdit::setModel(const QByteArray & m) {
s >> sz; s >> sz;
for (int i = 0; i < sz; ++i) { for (int i = 0; i < sz; ++i) {
BlockBusItem * b = new BlockBusItem(); BlockBusItem * b = new BlockBusItem();
QByteArray ba; s >> ba; b->load(ba); QByteArray ba;
s >> ba;
b->load(ba);
ui->blockView->addItem(b); ui->blockView->addItem(b);
} }
s >> sz; s >> sz;
@@ -148,26 +154,26 @@ void ConnectionEdit::setModel(const QByteArray & m) {
switch (type) { switch (type) {
case __CV_Device: case __CV_Device:
b = new DeviceItem(); b = new DeviceItem();
s >> ba; b->load(ba); s >> ba;
if (!b->isPropertyExists("bufferSize")) b->load(ba);
((DeviceItem*)b)->setBufferSize(4096); if (!b->isPropertyExists("bufferSize")) ((DeviceItem *)b)->setBufferSize(4096);
((DeviceItem*)b)->rename(); ((DeviceItem *)b)->rename();
break; break;
case __CV_Filter: case __CV_Filter:
b = new FilterItem(); b = new FilterItem();
s >> ba; b->load(ba); s >> ba;
if (!b->isPropertyExists("bufferSize")) b->load(ba);
((FilterItem*)b)->setBufferSize(65536); if (!b->isPropertyExists("bufferSize")) ((FilterItem *)b)->setBufferSize(65536);
((FilterItem*)b)->rename(); ((FilterItem *)b)->rename();
break; break;
case __CV_Sender: case __CV_Sender:
b = new SenderItem(); b = new SenderItem();
s >> ba; b->load(ba); s >> ba;
((SenderItem*)b)->rename(); b->load(ba);
((SenderItem *)b)->rename();
break; break;
} }
if (b) if (b) ui->blockView->addItem(b);
ui->blockView->addItem(b);
} }
ui->blockView->reconnectAll(); ui->blockView->reconnectAll();
loading = false; loading = false;
@@ -176,18 +182,18 @@ void ConnectionEdit::setModel(const QByteArray & m) {
void ConnectionEdit::selectionChanged() { void ConnectionEdit::selectionChanged() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
ui->buttonRemove->setEnabled(!si.isEmpty()); ui->buttonRemove->setEnabled(!si.isEmpty());
ui->buttonDeviceModify->setEnabled(false); ui->buttonDeviceModify->setEnabled(false);
ui->buttonFilterModify->setEnabled(false); ui->buttonFilterModify->setEnabled(false);
ui->buttonSenderModify->setEnabled(false); ui->buttonSenderModify->setEnabled(false);
if (si.size() != 1) return; if (si.size() != 1) return;
BlockItem * b = qgraphicsitem_cast<BlockItem*>(si[0]); BlockItem * b = qgraphicsitem_cast<BlockItem *>(si[0]);
if (!b) return; if (!b) return;
int type = b->propertyByName("__type").value.toInt(); int type = b->propertyByName("__type").value.toInt();
if (type == __CV_Device) { if (type == __CV_Device) {
ui->tabWidget->setCurrentIndex(0); ui->tabWidget->setCurrentIndex(0);
DeviceItem * di = (DeviceItem*)b; DeviceItem * di = (DeviceItem *)b;
ui->buttonDeviceModify->setEnabled(true); ui->buttonDeviceModify->setEnabled(true);
for (int i = 0; i < ui->comboMode->count(); ++i) for (int i = 0; i < ui->comboMode->count(); ++i)
if (ui->comboMode->itemData(i).toInt() == di->mode()) { if (ui->comboMode->itemData(i).toInt() == di->mode()) {
@@ -202,7 +208,7 @@ void ConnectionEdit::selectionChanged() {
} }
if (type == __CV_Filter) { if (type == __CV_Filter) {
ui->tabWidget->setCurrentIndex(1); ui->tabWidget->setCurrentIndex(1);
FilterItem * fi = (FilterItem*)b; FilterItem * fi = (FilterItem *)b;
ui->buttonFilterModify->setEnabled(true); ui->buttonFilterModify->setEnabled(true);
for (int i = 0; i < ui->comboSplit->count(); ++i) for (int i = 0; i < ui->comboSplit->count(); ++i)
if (ui->comboSplit->itemData(i).toInt() == fi->mode()) { if (ui->comboSplit->itemData(i).toInt() == fi->mode()) {
@@ -219,13 +225,12 @@ void ConnectionEdit::selectionChanged() {
} }
if (type == __CV_Sender) { if (type == __CV_Sender) {
ui->tabWidget->setCurrentIndex(2); ui->tabWidget->setCurrentIndex(2);
SenderItem * si = (SenderItem*)b; SenderItem * si = (SenderItem *)b;
ui->buttonSenderModify->setEnabled(true); ui->buttonSenderModify->setEnabled(true);
ui->lineSender->setText(si->name()); ui->lineSender->setText(si->name());
ui->lineData->setText(si->data()); ui->lineData->setText(si->data());
ui->spinFrequency->setValue(si->frequency()); ui->spinFrequency->setValue(si->frequency());
} }
} }
@@ -268,10 +273,9 @@ void ConnectionEdit::applySender(SenderItem * b) {
int ConnectionEdit::getOptions() const { int ConnectionEdit::getOptions() const {
int ret(0); int ret(0);
for (int i = 0; i < ui->layoutOptions->count(); ++i) { for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget()); QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue; if (!cb) continue;
if (cb->isChecked()) if (cb->isChecked()) ret |= cb->property("__value").toInt();
ret |= cb->property("__value").toInt();
} }
return ret; return ret;
} }
@@ -279,27 +283,29 @@ int ConnectionEdit::getOptions() const {
void ConnectionEdit::setOptions(int o) { void ConnectionEdit::setOptions(int o) {
for (int i = 0; i < ui->layoutOptions->count(); ++i) { for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget()); QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue; if (!cb) continue;
int cbf = cb->property("__value").toInt(); int cbf = cb->property("__value").toInt();
//qDebug() << cbf; // qDebug() << cbf;
cb->setChecked((o & cbf) == cbf); cb->setChecked((o & cbf) == cbf);
} }
} }
void ConnectionEdit::recreateConnection() { void ConnectionEdit::recreateConnection() {
//qDebug() << "recreate"; // qDebug() << "recreate";
if (loading) return; if (loading) return;
ui->blockView->reconnectAll(); ui->blockView->reconnectAll();
if (conn) delete conn; if (conn) delete conn;
PIString cn = Q2PIString(ui->lineName->text()); PIString cn = Q2PIString(ui->lineName->text());
if (cn.isEmpty()) conn = new PIConnection(); if (cn.isEmpty())
else conn = new PIConnection(cn); conn = new PIConnection();
QList<BlockItem*> devs = ui->blockView->allDevices(); else
foreach (BlockItem * b, devs) { conn = new PIConnection(cn);
DeviceItem * di = (DeviceItem*)b; QList<BlockItem *> devs = ui->blockView->allDevices();
//qDebug() << di->path(); foreach(BlockItem * b, devs) {
DeviceItem * di = (DeviceItem *)b;
// qDebug() << di->path();
PIIODevice * dev = conn->addDevice(Q2PIString(di->path()), di->mode()); PIIODevice * dev = conn->addDevice(Q2PIString(di->path()), di->mode());
if (!dev) continue; if (!dev) continue;
dev->setOptions(di->options()); dev->setOptions(di->options());
@@ -308,35 +314,35 @@ void ConnectionEdit::recreateConnection() {
PIDiagnostics * diag = conn->diagnostic(dev); PIDiagnostics * diag = conn->diagnostic(dev);
if (diag) diag->setDisconnectTimeout(di->disconnectTimeout()); if (diag) diag->setDisconnectTimeout(di->disconnectTimeout());
} }
foreach (BlockItem * b, devs) { foreach(BlockItem * b, devs) {
DeviceItem * di = (DeviceItem*)b; DeviceItem * di = (DeviceItem *)b;
PIIODevice * dev = conn->deviceByName(Q2PIString(di->name())); PIIODevice * dev = conn->deviceByName(Q2PIString(di->name()));
if (!dev) continue; if (!dev) continue;
BlockItemPin * p = b->pinByText("read"); BlockItemPin * p = b->pinByText("read");
if (!p) continue; if (!p) continue;
QList<BlockBusItem*> buses = p->connectedBuses(), nbuses; QList<BlockBusItem *> buses = p->connectedBuses(), nbuses;
QSet<BlockBusItem*> pbuses; QSet<BlockBusItem *> pbuses;
while (!buses.isEmpty()) { while (!buses.isEmpty()) {
nbuses.clear(); nbuses.clear();
foreach (BlockBusItem * bus, buses) { foreach(BlockBusItem * bus, buses) {
QList<BlockItem*> cb = bus->connectedBlocks(); QList<BlockItem *> cb = bus->connectedBlocks();
if (cb.size() != 2) continue; if (cb.size() != 2) continue;
FilterItem * fi_t(0); FilterItem * fi_t(0);
BlockItem * bi_f(0); BlockItem * bi_f(0);
if (cb[0]->pinAtBus(bus)->text() == "in") { if (cb[0]->pinAtBus(bus)->text() == "in") {
fi_t = (FilterItem*)(cb[0]); fi_t = (FilterItem *)(cb[0]);
bi_f = (cb[1]); bi_f = (cb[1]);
} else if (cb[1]->pinAtBus(bus)->text() == "in") { } else if (cb[1]->pinAtBus(bus)->text() == "in") {
fi_t = (FilterItem*)(cb[1]); fi_t = (FilterItem *)(cb[1]);
bi_f = (cb[0]); bi_f = (cb[0]);
} }
if (!fi_t || !bi_f) continue; if (!fi_t || !bi_f) continue;
PIString name_from; PIString name_from;
int type = bi_f->propertyByName("__type").value.toInt(); int type = bi_f->propertyByName("__type").value.toInt();
if (type == __CV_Device) name_from = Q2PIString(((DeviceItem*)bi_f)->name()); if (type == __CV_Device) name_from = Q2PIString(((DeviceItem *)bi_f)->name());
if (type == __CV_Filter) name_from = Q2PIString(((FilterItem*)bi_f)->name()); if (type == __CV_Filter) name_from = Q2PIString(((FilterItem *)bi_f)->name());
if (name_from.isEmpty()) continue; if (name_from.isEmpty()) continue;
PIPacketExtractor * pe = conn->addFilter(Q2PIString(fi_t->name()),conn->deviceByName(name_from), fi_t->mode()); PIPacketExtractor * pe = conn->addFilter(Q2PIString(fi_t->name()), conn->deviceByName(name_from), fi_t->mode());
if (!pe) continue; if (!pe) continue;
pe->setHeader(PIByteArray::fromUserInput(Q2PIString(fi_t->header()))); pe->setHeader(PIByteArray::fromUserInput(Q2PIString(fi_t->header())));
pe->setFooter(PIByteArray::fromUserInput(Q2PIString(fi_t->footer()))); pe->setFooter(PIByteArray::fromUserInput(Q2PIString(fi_t->footer())));
@@ -345,8 +351,8 @@ void ConnectionEdit::recreateConnection() {
pe->setThreadedReadBufferSize(fi_t->bufferSize()); pe->setThreadedReadBufferSize(fi_t->bufferSize());
PIDiagnostics * diag = conn->diagnostic(pe); PIDiagnostics * diag = conn->diagnostic(pe);
if (diag) diag->setDisconnectTimeout(fi_t->disconnectTimeout()); if (diag) diag->setDisconnectTimeout(fi_t->disconnectTimeout());
QList<BlockBusItem*> nb = fi_t->pinByText("out")->connectedBuses(); QList<BlockBusItem *> nb = fi_t->pinByText("out")->connectedBuses();
foreach (BlockBusItem * b_, nb) foreach(BlockBusItem * b_, nb)
if (!pbuses.contains(b_)) { if (!pbuses.contains(b_)) {
pbuses << b_; pbuses << b_;
nbuses << b_; nbuses << b_;
@@ -355,34 +361,34 @@ void ConnectionEdit::recreateConnection() {
buses = nbuses; buses = nbuses;
} }
} }
foreach (BlockItem * b, devs) { foreach(BlockItem * b, devs) {
BlockItemPin * p = b->pinByText("write"); BlockItemPin * p = b->pinByText("write");
if (!p) continue; if (!p) continue;
QList<BlockBusItem*> buses = p->connectedBuses(); QList<BlockBusItem *> buses = p->connectedBuses();
foreach (BlockBusItem * bus, buses) { foreach(BlockBusItem * bus, buses) {
QList<BlockItem*> cb = bus->connectedBlocks(); QList<BlockItem *> cb = bus->connectedBlocks();
if (cb.size() != 2) continue; if (cb.size() != 2) continue;
BlockItem * bi_f(0); BlockItem * bi_f(0);
DeviceItem * di_t(0); DeviceItem * di_t(0);
if (cb[0]->pinAtBus(bus)->text() == "write") { if (cb[0]->pinAtBus(bus)->text() == "write") {
di_t = (DeviceItem*)(cb[0]); di_t = (DeviceItem *)(cb[0]);
bi_f = (cb[1]); bi_f = (cb[1]);
} else if (cb[1]->pinAtBus(bus)->text() == "write") { } else if (cb[1]->pinAtBus(bus)->text() == "write") {
di_t = (DeviceItem*)(cb[1]); di_t = (DeviceItem *)(cb[1]);
bi_f = (cb[0]); bi_f = (cb[0]);
} }
if (!bi_f || !di_t) continue; if (!bi_f || !di_t) continue;
QString name_from; QString name_from;
int type = bi_f->propertyByName("__type").value.toInt(); int type = bi_f->propertyByName("__type").value.toInt();
if (type == __CV_Sender) { if (type == __CV_Sender) {
SenderItem * si = ((SenderItem*)bi_f); SenderItem * si = ((SenderItem *)bi_f);
si->name(); si->name();
conn->addSender(Q2PIString(si->name()), Q2PIString(di_t->path()), si->frequency()); conn->addSender(Q2PIString(si->name()), Q2PIString(di_t->path()), si->frequency());
if (!si->data().isEmpty()) if (!si->data().isEmpty())
conn->setSenderFixedData(Q2PIString(si->name()), PIByteArray::fromUserInput(Q2PIString(si->data()))); conn->setSenderFixedData(Q2PIString(si->name()), PIByteArray::fromUserInput(Q2PIString(si->data())));
} else { } else {
if (type == __CV_Device) name_from = ((DeviceItem*)bi_f)->name(); if (type == __CV_Device) name_from = ((DeviceItem *)bi_f)->name();
if (type == __CV_Filter) name_from = ((FilterItem*)bi_f)->name(); if (type == __CV_Filter) name_from = ((FilterItem *)bi_f)->name();
if (name_from.isEmpty()) continue; if (name_from.isEmpty()) continue;
conn->addChannel(Q2PIString(name_from), Q2PIString(di_t->name())); conn->addChannel(Q2PIString(name_from), Q2PIString(di_t->name()));
} }
@@ -411,12 +417,11 @@ void ConnectionEdit::on_buttonFilterAdd_clicked() {
void ConnectionEdit::on_buttonFilterModify_clicked() { void ConnectionEdit::on_buttonFilterModify_clicked() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return; if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return; if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter) if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter) return;
return; applyFilter(qgraphicsitem_cast<FilterItem *>(si[0]));
applyFilter(qgraphicsitem_cast<FilterItem*>(si[0]));
} }
@@ -435,12 +440,11 @@ void ConnectionEdit::on_buttonDeviceAdd_clicked() {
void ConnectionEdit::on_buttonDeviceModify_clicked() { void ConnectionEdit::on_buttonDeviceModify_clicked() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return; if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return; if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Device) if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Device) return;
return; applyDevice(qgraphicsitem_cast<DeviceItem *>(si[0]));
applyDevice(qgraphicsitem_cast<DeviceItem*>(si[0]));
} }
@@ -451,12 +455,11 @@ void ConnectionEdit::on_buttonSenderAdd_clicked() {
void ConnectionEdit::on_buttonSenderModify_clicked() { void ConnectionEdit::on_buttonSenderModify_clicked() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return; if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return; if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender) if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender) return;
return; applySender(qgraphicsitem_cast<SenderItem *>(si[0]));
applySender(qgraphicsitem_cast<SenderItem*>(si[0]));
} }
+19 -16
View File
@@ -1,32 +1,33 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CONNECTION_EDIT_H #ifndef CONNECTION_EDIT_H
#define CONNECTION_EDIT_H #define CONNECTION_EDIT_H
#include <QDialog>
#include "piconnection.h" #include "piconnection.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include <QDialog>
namespace Ui { namespace Ui {
class ConnectionEdit; class ConnectionEdit;
} }
class FilterItem; class FilterItem;
@@ -35,6 +36,7 @@ class SenderItem;
class QAD_PIQT_UTILS_EXPORT ConnectionEdit: public QDialog { class QAD_PIQT_UTILS_EXPORT ConnectionEdit: public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectionEdit(QWidget * parent = 0); explicit ConnectionEdit(QWidget * parent = 0);
~ConnectionEdit(); ~ConnectionEdit();
@@ -62,7 +64,9 @@ private:
int udevicenum; int udevicenum;
private slots: private slots:
void recreateRequest() {if (!loading) QMetaObject::invokeMethod(this, "recreateConnection", Qt::QueuedConnection);} void recreateRequest() {
if (!loading) QMetaObject::invokeMethod(this, "recreateConnection", Qt::QueuedConnection);
}
void on_buttonRemove_clicked(); void on_buttonRemove_clicked();
void on_buttonClear_clicked(); void on_buttonClear_clicked();
void on_buttonFilterAdd_clicked(); void on_buttonFilterAdd_clicked();
@@ -76,7 +80,6 @@ private slots:
public slots: public slots:
void recreateConnection(); void recreateConnection();
}; };
#endif // CONNECTION_EDIT_H #endif // CONNECTION_EDIT_H
+39 -33
View File
@@ -1,6 +1,8 @@
#include "piqt_connection_view.h" #include "piqt_connection_view.h"
#include "picodeinfo.h" #include "picodeinfo.h"
#include "piqt.h" #include "piqt.h"
#include <alignedtextitem.h> #include <alignedtextitem.h>
@@ -11,7 +13,8 @@ DeviceItem::DeviceItem(): BlockItem() {
setColor(QColor(192, 192, 255)); setColor(QColor(192, 192, 255));
text_name = new AlignedTextItem(); text_name = new AlignedTextItem();
text_path = new AlignedTextItem(); text_path = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true); QFont fnt(text_name->font());
fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt); text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.); text_name->setPos(0., -size().height() / 2.);
@@ -29,19 +32,29 @@ DeviceItem::DeviceItem(): BlockItem() {
void DeviceItem::rename() { void DeviceItem::rename() {
QString ms; QString ms;
BlockItemPin * pr = pinByText("read"), * pw = pinByText("write"); BlockItemPin *pr = pinByText("read"), *pw = pinByText("write");
switch (mode()) { switch (mode()) {
case PIIODevice::ReadOnly: ms = "ro"; pr->show(); pw->hide(); break; case PIIODevice::ReadOnly:
case PIIODevice::WriteOnly: ms = "wo"; pr->hide(); pw->show(); break; ms = "ro";
case PIIODevice::ReadWrite: ms = "rw"; pr->show(); pw->show(); break; pr->show();
pw->hide();
break;
case PIIODevice::WriteOnly:
ms = "wo";
pr->hide();
pw->show();
break;
case PIIODevice::ReadWrite:
ms = "rw";
pr->show();
pw->show();
break;
} }
text_name->setText(name() + " (" + ms + ")"); text_name->setText(name() + " (" + ms + ")");
text_path->setText(path()); text_path->setText(path());
} }
FilterItem::FilterItem(): BlockItem() { FilterItem::FilterItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Filter)); addProperty(BlockItem::Property("__type", "", __CV_Filter));
addProperty(BlockItem::Property("bufferSize", "", 65536)); addProperty(BlockItem::Property("bufferSize", "", 65536));
@@ -50,7 +63,8 @@ FilterItem::FilterItem(): BlockItem() {
setColor(QColor(192, 255, 192)); setColor(QColor(192, 255, 192));
text_name = new AlignedTextItem(); text_name = new AlignedTextItem();
text_mode = new AlignedTextItem(); text_mode = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true); QFont fnt(text_name->font());
fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt); text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.); text_name->setPos(0., -size().height() / 2.);
@@ -71,9 +85,9 @@ void FilterItem::rename() {
QString ms; QString ms;
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode", 0); PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode", 0);
if (ei) { if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & i, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & i, ei->members)
if (i.value == mode()) { if (i.value == mode()) {
#if PIP_VERSION >= PIP_MAKE_VERSION(2,39,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ms = PI2QString(i.name.toString()); ms = PI2QString(i.name.toString());
#else #else
ms = PI2QString(i.name); ms = PI2QString(i.name);
@@ -82,20 +96,18 @@ void FilterItem::rename() {
} }
} }
text_mode->setText(ms); text_mode->setText(ms);
} }
SenderItem::SenderItem(): BlockItem() { SenderItem::SenderItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Sender)); addProperty(BlockItem::Property("__type", "", __CV_Sender));
setSize(140, 80); setSize(140, 80);
setPos(-200, 0); setPos(-200, 0);
setColor(QColor(255, 192, 192)); setColor(QColor(255, 192, 192));
text_name = new AlignedTextItem(); text_name = new AlignedTextItem();
text_frequency = new AlignedTextItem(); text_frequency = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true); QFont fnt(text_name->font());
fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt); text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.); text_name->setPos(0., -size().height() / 2.);
@@ -116,14 +128,10 @@ void SenderItem::rename() {
} }
ConnectionView::ConnectionView(QWidget * parent): BlockView(parent) {}
ConnectionView::ConnectionView(QWidget * parent): BlockView(parent) { ConnectionView::~ConnectionView() {}
}
ConnectionView::~ConnectionView() {
}
DeviceItem * ConnectionView::addDevice(const QString & name, const QString & path) { DeviceItem * ConnectionView::addDevice(const QString & name, const QString & path) {
@@ -166,10 +174,9 @@ SenderItem * ConnectionView::addSender(const QString & name) {
DeviceItem * ConnectionView::findDevice(const QString & name) const { DeviceItem * ConnectionView::findDevice(const QString & name) const {
QList<BlockItem*> blockl = blocks(); QList<BlockItem *> blockl = blocks();
foreach (BlockItem * b, blockl) foreach(BlockItem * b, blockl)
if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device)) if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device)) return (DeviceItem *)b;
return (DeviceItem*)b;
return 0; return 0;
} }
@@ -179,14 +186,14 @@ void ConnectionView::loadBus(BlockBusItem * bus) {
} }
void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem * > coll) { void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem *> coll) {
if (coll.isEmpty()) return; if (coll.isEmpty()) return;
QList<QRectF> collr; QList<QRectF> collr;
foreach (BlockItem * i, coll) foreach(BlockItem * i, coll)
collr << i->sceneBoundingRect(); collr << i->sceneBoundingRect();
while (true) { while (true) {
QRectF br = b->sceneBoundingRect(); QRectF br = b->sceneBoundingRect();
bool ok = true; bool ok = true;
for (int i = 0; i < collr.size(); ++i) for (int i = 0; i < collr.size(); ++i)
if (br.intersects(collr[i])) { if (br.intersects(collr[i])) {
ok = false; ok = false;
@@ -199,10 +206,9 @@ void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem * > coll) {
} }
QList<BlockItem * > ConnectionView::allByType(int type_) const { QList<BlockItem *> ConnectionView::allByType(int type_) const {
QList<BlockItem*> blockl = blocks(), ret; QList<BlockItem *> blockl = blocks(), ret;
foreach (BlockItem * b, blockl) foreach(BlockItem * b, blockl)
if (b->propertyByName("__type").value.toInt() == type_) if (b->propertyByName("__type").value.toInt() == type_) ret << b;
ret << b;
return ret; return ret;
} }
+107 -59
View File
@@ -1,20 +1,20 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CONNECTION_VIEW_H #ifndef CONNECTION_VIEW_H
@@ -33,25 +33,42 @@ class QAD_PIQT_UTILS_EXPORT DeviceItem: public BlockItem {
public: public:
DeviceItem(); DeviceItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();} void setName(const QString & n) {
void setPath(const QString & p) {addProperty(BlockItem::Property("device", "", p)); rename();} addProperty(BlockItem::Property("name", "", n));
void setMode(PIIODevice::DeviceMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();} rename();
void setOptions(PIIODevice::DeviceOptions o) {addProperty(BlockItem::Property("options", "", int(o))); rename();} }
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();} void setPath(const QString & p) {
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();} addProperty(BlockItem::Property("device", "", p));
rename();
}
void setMode(PIIODevice::DeviceMode m) {
addProperty(BlockItem::Property("mode", "", int(m)));
rename();
}
void setOptions(PIIODevice::DeviceOptions o) {
addProperty(BlockItem::Property("options", "", int(o)));
rename();
}
void setDisconnectTimeout(double v) {
addProperty(BlockItem::Property("disconnectTimeout", "", v));
rename();
}
void setBufferSize(int v) {
addProperty(BlockItem::Property("bufferSize", "", v));
rename();
}
QString name() const {return propertyByName("name").value.toString();} QString name() const { return propertyByName("name").value.toString(); }
QString path() const {return propertyByName("device").value.toString();} QString path() const { return propertyByName("device").value.toString(); }
PIIODevice::DeviceMode mode() const {return PIIODevice::DeviceMode(propertyByName("mode").value.toInt());} PIIODevice::DeviceMode mode() const { return PIIODevice::DeviceMode(propertyByName("mode").value.toInt()); }
PIIODevice::DeviceOptions options() const {return PIIODevice::DeviceOptions(propertyByName("options").value.toInt());} PIIODevice::DeviceOptions options() const { return PIIODevice::DeviceOptions(propertyByName("options").value.toInt()); }
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();} double disconnectTimeout() const { return propertyByName("disconnectTimeout").value.toDouble(); }
int bufferSize() const {return propertyByName("bufferSize").value.toInt();} int bufferSize() const { return propertyByName("bufferSize").value.toInt(); }
void rename(); void rename();
protected: protected:
AlignedTextItem * text_name, * text_path; AlignedTextItem *text_name, *text_path;
}; };
@@ -59,29 +76,52 @@ class QAD_PIQT_UTILS_EXPORT FilterItem: public BlockItem {
public: public:
FilterItem(); FilterItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();} void setName(const QString & n) {
void setMode(PIPacketExtractor::SplitMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();} addProperty(BlockItem::Property("name", "", n));
void setHeader(const QString & v) {addProperty(BlockItem::Property("header", "", v)); rename();} rename();
void setFooter(const QString & v) {addProperty(BlockItem::Property("footer", "", v)); rename();} }
void setTimeout(double v) {addProperty(BlockItem::Property("timeout", "", v)); rename();} void setMode(PIPacketExtractor::SplitMode m) {
void setPacketSize(int v) {addProperty(BlockItem::Property("size", "", v)); rename();} addProperty(BlockItem::Property("mode", "", int(m)));
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();} rename();
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();} }
void setHeader(const QString & v) {
addProperty(BlockItem::Property("header", "", v));
rename();
}
void setFooter(const QString & v) {
addProperty(BlockItem::Property("footer", "", v));
rename();
}
void setTimeout(double v) {
addProperty(BlockItem::Property("timeout", "", v));
rename();
}
void setPacketSize(int v) {
addProperty(BlockItem::Property("size", "", v));
rename();
}
void setDisconnectTimeout(double v) {
addProperty(BlockItem::Property("disconnectTimeout", "", v));
rename();
}
void setBufferSize(int v) {
addProperty(BlockItem::Property("bufferSize", "", v));
rename();
}
QString name() const {return propertyByName("name").value.toString();} QString name() const { return propertyByName("name").value.toString(); }
PIPacketExtractor::SplitMode mode() const {return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt());} PIPacketExtractor::SplitMode mode() const { return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt()); }
QString header() const {return propertyByName("header").value.toString();} QString header() const { return propertyByName("header").value.toString(); }
QString footer() const {return propertyByName("footer").value.toString();} QString footer() const { return propertyByName("footer").value.toString(); }
double timeout() const {return propertyByName("timeout").value.toDouble();} double timeout() const { return propertyByName("timeout").value.toDouble(); }
int packetSize() const {return propertyByName("size").value.toInt();} int packetSize() const { return propertyByName("size").value.toInt(); }
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();} double disconnectTimeout() const { return propertyByName("disconnectTimeout").value.toDouble(); }
int bufferSize() const {return propertyByName("bufferSize").value.toInt();} int bufferSize() const { return propertyByName("bufferSize").value.toInt(); }
void rename(); void rename();
protected: protected:
AlignedTextItem * text_name, * text_mode; AlignedTextItem *text_name, *text_mode;
}; };
@@ -89,24 +129,33 @@ class QAD_PIQT_UTILS_EXPORT SenderItem: public BlockItem {
public: public:
SenderItem(); SenderItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();} void setName(const QString & n) {
void setData(const QString & p) {addProperty(BlockItem::Property("data", "", p)); rename();} addProperty(BlockItem::Property("name", "", n));
void setFrequency(double m) {addProperty(BlockItem::Property("frequency", "", m)); rename();} rename();
}
void setData(const QString & p) {
addProperty(BlockItem::Property("data", "", p));
rename();
}
void setFrequency(double m) {
addProperty(BlockItem::Property("frequency", "", m));
rename();
}
QString name() const {return propertyByName("name").value.toString();} QString name() const { return propertyByName("name").value.toString(); }
QString data() const {return propertyByName("data").value.toString();} QString data() const { return propertyByName("data").value.toString(); }
double frequency() const {return propertyByName("frequency").value.toDouble();} double frequency() const { return propertyByName("frequency").value.toDouble(); }
void rename(); void rename();
protected: protected:
AlignedTextItem * text_name, * text_frequency; AlignedTextItem *text_name, *text_frequency;
}; };
class QAD_PIQT_UTILS_EXPORT ConnectionView: public BlockView { class QAD_PIQT_UTILS_EXPORT ConnectionView: public BlockView {
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectionView(QWidget * parent = 0); explicit ConnectionView(QWidget * parent = 0);
~ConnectionView(); ~ConnectionView();
@@ -115,19 +164,18 @@ public:
FilterItem * addFilter(const QString & name); FilterItem * addFilter(const QString & name);
SenderItem * addSender(const QString & name); SenderItem * addSender(const QString & name);
DeviceItem * findDevice(const QString & name) const; DeviceItem * findDevice(const QString & name) const;
QList<BlockItem * > allDevices() const {return allByType(__CV_Device);} QList<BlockItem *> allDevices() const { return allByType(__CV_Device); }
QList<BlockItem * > allFilters() const {return allByType(__CV_Filter);} QList<BlockItem *> allFilters() const { return allByType(__CV_Filter); }
QList<BlockItem * > allSenders() const {return allByType(__CV_Sender);} QList<BlockItem *> allSenders() const { return allByType(__CV_Sender); }
private: private:
QSize sizeHint() const {return QSize(800, 600);} QSize sizeHint() const { return QSize(800, 600); }
void loadBus(BlockBusItem * bus); void loadBus(BlockBusItem * bus);
void placeBlock(BlockItem * b, QList<BlockItem*> coll); void placeBlock(BlockItem * b, QList<BlockItem *> coll);
QList<BlockItem * > allByType(int type_) const; QList<BlockItem *> allByType(int type_) const;
private slots: private slots:
}; };
#endif // CONNECTION_VIEW_H #endif // CONNECTION_VIEW_H
+10 -10
View File
@@ -6,30 +6,30 @@ ConfigHighlighter::ConfigHighlighter(QTextDocument * parent): QSyntaxHighlighter
valueNameFormat.setForeground(QColor(0, 64, 154)); valueNameFormat.setForeground(QColor(0, 64, 154));
rule.pattern = QRegularExpression("[^=]"); //"\\b[A-Za-z0-9_]+(?=\\()"); rule.pattern = QRegularExpression("[^=]"); //"\\b[A-Za-z0-9_]+(?=\\()");
rule.format = valueNameFormat; rule.format = valueNameFormat;
highlightingRules.append(rule); highlightingRules.append(rule);
valueFormat.setForeground(QColor(192, 0, 0)); valueFormat.setForeground(QColor(192, 0, 0));
rule.pattern = QRegularExpression("=[^\n]*"); rule.pattern = QRegularExpression("=[^\n]*");
rule.format = valueFormat; rule.format = valueFormat;
highlightingRules.append(rule); highlightingRules.append(rule);
equalFormat.setFontWeight(QFont::Bold); equalFormat.setFontWeight(QFont::Bold);
equalFormat.setForeground(QColor(96, 126, 0)); equalFormat.setForeground(QColor(96, 126, 0));
rule.pattern = QRegularExpression("="); rule.pattern = QRegularExpression("=");
rule.format = equalFormat; rule.format = equalFormat;
highlightingRules.append(rule); highlightingRules.append(rule);
sectionFormat.setFontWeight(QFont::Bold); sectionFormat.setFontWeight(QFont::Bold);
sectionFormat.setForeground(QColor(0, 32, 64)); sectionFormat.setForeground(QColor(0, 32, 64));
rule.pattern = QRegularExpression("\\[.*\\]"); rule.pattern = QRegularExpression("\\[.*\\]");
rule.format = sectionFormat; rule.format = sectionFormat;
highlightingRules.append(rule); highlightingRules.append(rule);
substFormat.setForeground(QColor(192, 0, 192)); substFormat.setForeground(QColor(192, 0, 192));
rule.pattern = QRegularExpression("\\$\\{.*\\}+"); rule.pattern = QRegularExpression("\\$\\{.*\\}+");
//rule.pattern.setMinimal(true); // rule.pattern.setMinimal(true);
rule.format = substFormat; rule.format = substFormat;
highlightingRules.append(rule); highlightingRules.append(rule);
rule.pattern = QRegularExpression("\\$\\{[^\\{]*\\}+"); rule.pattern = QRegularExpression("\\$\\{[^\\{]*\\}+");
highlightingRules.append(rule); highlightingRules.append(rule);
@@ -37,18 +37,18 @@ ConfigHighlighter::ConfigHighlighter(QTextDocument * parent): QSyntaxHighlighter
singleLineCommentFormat.setFontItalic(true); singleLineCommentFormat.setFontItalic(true);
singleLineCommentFormat.setForeground(QColor(128, 128, 128)); singleLineCommentFormat.setForeground(QColor(128, 128, 128));
rule.pattern = QRegularExpression("#[^\n]*"); rule.pattern = QRegularExpression("#[^\n]*");
rule.format = singleLineCommentFormat; rule.format = singleLineCommentFormat;
highlightingRules.append(rule); highlightingRules.append(rule);
spaceFormat.setForeground(QColor(210, 210, 210)); spaceFormat.setForeground(QColor(210, 210, 210));
//commentStartExpression = QRegExp("/\\*"); // commentStartExpression = QRegExp("/\\*");
//commentEndExpression = QRegExp("\\*/"); // commentEndExpression = QRegExp("\\*/");
} }
void ConfigHighlighter::highlightBlock(const QString & text) { void ConfigHighlighter::highlightBlock(const QString & text) {
foreach (const HighlightingRule &rule, highlightingRules) { foreach(const HighlightingRule & rule, highlightingRules) {
QRegularExpression expression(rule.pattern); QRegularExpression expression(rule.pattern);
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
QRegularExpressionMatchIterator i = expression.globalMatch(text); QRegularExpressionMatchIterator i = expression.globalMatch(text);
+18 -18
View File
@@ -1,48 +1,48 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CONF_HIGHLIGHTER_H #ifndef CONF_HIGHLIGHTER_H
#define CONF_HIGHLIGHTER_H #define CONF_HIGHLIGHTER_H
#include <QSyntaxHighlighter> #include <QSyntaxHighlighter>
#include <QTextCursor>
#include <QTextCharFormat> #include <QTextCharFormat>
#include <QTextCursor>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QRegularExpression> # include <QRegularExpression>
#else #else
# include <QRegExp> # include <QRegExp>
typedef QRegExp QRegularExpression; typedef QRegExp QRegularExpression;
#endif #endif
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
class QTextDocument; class QTextDocument;
class QAD_PIQT_UTILS_EXPORT ConfigHighlighter : public QSyntaxHighlighter class QAD_PIQT_UTILS_EXPORT ConfigHighlighter: public QSyntaxHighlighter {
{
Q_OBJECT Q_OBJECT
public: public:
ConfigHighlighter(QTextDocument *parent = 0); ConfigHighlighter(QTextDocument * parent = 0);
QTextCursor cursor; QTextCursor cursor;
private: private:
void highlightBlock(const QString &text); void highlightBlock(const QString & text);
struct QAD_PIQT_UTILS_EXPORT HighlightingRule { struct QAD_PIQT_UTILS_EXPORT HighlightingRule {
QRegularExpression pattern; QRegularExpression pattern;
+10 -9
View File
@@ -1,17 +1,19 @@
#include "piqt_iodevice_edit.h" #include "piqt_iodevice_edit.h"
#include "piqt_iodevice_edit_dialog.h" #include "piqt_iodevice_edit_dialog.h"
#include "qvariantedit_custom.h" #include "qvariantedit_custom.h"
#include <QBoxLayout>
#include <QLineEdit> #include <QLineEdit>
#include <QToolButton> #include <QToolButton>
#include <QBoxLayout>
#include <piqt.h>
#include <piiodevice.h> #include <piiodevice.h>
#include <piqt.h>
IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) { IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) {
dlg = new IODeviceEditDialog(); dlg = new IODeviceEditDialog();
line = new QLineEdit(); line = new QLineEdit();
btn = new QToolButton(); btn = new QToolButton();
setLayout(new QBoxLayout(QBoxLayout::LeftToRight)); setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
layout()->setContentsMargins(0, 0, 0, 0); layout()->setContentsMargins(0, 0, 0, 0);
layout()->addWidget(line); layout()->addWidget(line);
@@ -65,11 +67,10 @@ void IODeviceEdit::buttonDlg_clicked() {
} }
class Factory: public QVariantEditorFactoryBase { class Factory: public QVariantEditorFactoryBase {
public: public:
Factory() {} Factory() {}
virtual QWidget * createEditor() {return new IODeviceEdit();} virtual QWidget * createEditor() { return new IODeviceEdit(); }
}; };
@@ -81,11 +82,11 @@ __IODeviceEditRegistrator__::__IODeviceEditRegistrator__() {
void QAD_IODevice_toString(const QVariant & v, QString & r) { void QAD_IODevice_toString(const QVariant & v, QString & r) {
PIVariantTypes::IODevice sd = Q2PIVariant(v).toIODevice(); PIVariantTypes::IODevice sd = Q2PIVariant(v).toIODevice();
// piCout << sd; // piCout << sd;
PIIODevice * rd = PIIODevice::createFromVariant(sd); PIIODevice * rd = PIIODevice::createFromVariant(sd);
if (rd) { if (rd) {
PIString ps = rd->constructFullPath(); PIString ps = rd->constructFullPath();
r = PI2QString(ps); r = PI2QString(ps);
} else { } else {
piCout << "error in " << sd; piCout << "error in " << sd;
} }
+16 -15
View File
@@ -1,28 +1,29 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PIQT_IODEVICE_EDIT_H #ifndef PIQT_IODEVICE_EDIT_H
#define PIQT_IODEVICE_EDIT_H #define PIQT_IODEVICE_EDIT_H
#include <QWidget>
#include "qad_types.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include "qad_types.h"
#include <QWidget>
class QLineEdit; class QLineEdit;
class QToolButton; class QToolButton;
@@ -33,6 +34,7 @@ class QAD_PIQT_UTILS_EXPORT IODeviceEdit: public QWidget {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
public: public:
explicit IODeviceEdit(QWidget * parent = 0); explicit IODeviceEdit(QWidget * parent = 0);
~IODeviceEdit(); ~IODeviceEdit();
@@ -57,7 +59,6 @@ private slots:
signals: signals:
void valueChanged(); void valueChanged();
}; };
+20 -20
View File
@@ -1,8 +1,10 @@
#include "ui_piqt_iodevice_edit_dialog.h"
#include "piqt_iodevice_edit_dialog.h" #include "piqt_iodevice_edit_dialog.h"
#include "piqt.h"
#include "picodeinfo.h" #include "picodeinfo.h"
#include "piiodevice.h" #include "piiodevice.h"
#include "piqt.h"
#include "ui_piqt_iodevice_edit_dialog.h"
#include <QCheckBox> #include <QCheckBox>
@@ -11,9 +13,10 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
ui->setupUi(this); ui->setupUi(this);
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode"); PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
if (ei) { if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
#if PIP_VERSION >= PIP_MAKE_VERSION(2,39,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"),
QVariant::fromValue<int>(e.value));
#else #else
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
#endif #endif
@@ -21,9 +24,9 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1); ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption"); ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
if (ei) { if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) { piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) {
QCheckBox * cb = new QCheckBox(); QCheckBox * cb = new QCheckBox();
#if PIP_VERSION >= PIP_MAKE_VERSION(2,39,0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
cb->setText(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")")); cb->setText(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"));
#else #else
cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")")); cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"));
@@ -33,23 +36,21 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
} }
} }
PIStringList pl = PIIODevice::availablePrefixes(); PIStringList pl = PIIODevice::availablePrefixes();
piForeachC (PIString & p, pl) { piForeachC(PIString & p, pl) {
ui->comboType->addItem(PI2QString(p)); ui->comboType->addItem(PI2QString(p));
} }
} }
IODeviceEditDialog::~IODeviceEditDialog() { IODeviceEditDialog::~IODeviceEditDialog() {}
}
int IODeviceEditDialog::getOptions() const { int IODeviceEditDialog::getOptions() const {
int ret = 0; int ret = 0;
for (int i = 0; i < ui->layoutOptions->count(); ++i) { for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget()); QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue; if (!cb) continue;
if (cb->isChecked()) if (cb->isChecked()) ret |= cb->property("__value").toInt();
ret |= cb->property("__value").toInt();
} }
return ret; return ret;
} }
@@ -57,7 +58,7 @@ int IODeviceEditDialog::getOptions() const {
void IODeviceEditDialog::setOptions(int o) { void IODeviceEditDialog::setOptions(int o) {
for (int i = 0; i < ui->layoutOptions->count(); ++i) { for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget()); QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue; if (!cb) continue;
int cbf = cb->property("__value").toInt(); int cbf = cb->property("__value").toInt();
cb->setChecked((o & cbf) == cbf); cb->setChecked((o & cbf) == cbf);
@@ -67,7 +68,7 @@ void IODeviceEditDialog::setOptions(int o) {
void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) { void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) {
PIString prefix = Q2PIString(ui->comboType->currentText()); PIString prefix = Q2PIString(ui->comboType->currentText());
auto * d = PIIODevice::createFromFullPath(prefix + "://"); auto * d = PIIODevice::createFromFullPath(prefix + "://");
if (d) { if (d) {
ps = PI2QPropertyStorage(d->constructVariant().get()); ps = PI2QPropertyStorage(d->constructVariant().get());
ui->widgetProperties->setStorage(&ps); ui->widgetProperties->setStorage(&ps);
@@ -78,8 +79,7 @@ void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) {
QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) { QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) {
setValue(d); setValue(d);
if (QDialog::exec() != QDialog::Accepted) if (QDialog::exec() != QDialog::Accepted) return QAD::IODevice();
return QAD::IODevice();
return value(); return value();
} }
@@ -87,10 +87,10 @@ QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) {
QAD::IODevice IODeviceEditDialog::value() const { QAD::IODevice IODeviceEditDialog::value() const {
QAD::IODevice d; QAD::IODevice d;
ui->widgetProperties->applyProperties(); ui->widgetProperties->applyProperties();
d.prefix = ui->comboType->currentText(); d.prefix = ui->comboType->currentText();
d.mode = ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt(); d.mode = ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt();
d.options = getOptions(); d.options = getOptions();
d.props = ps; d.props = ps;
return d; return d;
} }
+17 -16
View File
@@ -1,36 +1,38 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PIQT_IODEVICE_EDIT_DIALOG_H #ifndef PIQT_IODEVICE_EDIT_DIALOG_H
#define PIQT_IODEVICE_EDIT_DIALOG_H #define PIQT_IODEVICE_EDIT_DIALOG_H
#include <QDialog>
#include "qad_types.h"
#include "propertystorage.h" #include "propertystorage.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include "qad_types.h"
#include <QDialog>
namespace Ui { namespace Ui {
class IODeviceEditDialog; class IODeviceEditDialog;
} }
class QAD_PIQT_UTILS_EXPORT IODeviceEditDialog: public QDialog { class QAD_PIQT_UTILS_EXPORT IODeviceEditDialog: public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit IODeviceEditDialog(QWidget * parent = 0); explicit IODeviceEditDialog(QWidget * parent = 0);
~IODeviceEditDialog(); ~IODeviceEditDialog();
@@ -48,7 +50,6 @@ private:
private slots: private slots:
void on_comboType_currentIndexChanged(int index); void on_comboType_currentIndexChanged(int index);
}; };
#endif // PIQT_IODEVICE_EDIT_DIALOG_H #endif // PIQT_IODEVICE_EDIT_DIALOG_H
+1 -1
View File
@@ -104,7 +104,7 @@ void PIValueTreeEdit::build() {
widget_array = new QWidget(); widget_array = new QWidget();
ui_array->setupUi(widget_array); ui_array->setupUi(widget_array);
ui_array->spinCount->setRange(source.attribute(PIValueTree::attributeArrayMinCount, 0).toInt(), ui_array->spinCount->setRange(source.attribute(PIValueTree::attributeArrayMinCount, 0).toInt(),
source.attribute(PIValueTree::attributeArrayMaxCount, 65536).toInt()); source.attribute(PIValueTree::attributeArrayMaxCount, 65536).toInt());
ui_array->spinCount->setValue(source.children().size_s()); ui_array->spinCount->setValue(source.children().size_s());
ui_array->widgetEdit->setVisible(source.attribute(PIValueTree::attributeArrayResize, false).toBool()); ui_array->widgetEdit->setVisible(source.attribute(PIValueTree::attributeArrayResize, false).toBool());
ui_array->layoutArray->addWidget(grid); ui_array->layoutArray->addWidget(grid);
+12 -12
View File
@@ -1,20 +1,20 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef pivaluetree_edit_H #ifndef pivaluetree_edit_H
+12 -12
View File
@@ -1,20 +1,20 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef pivariant_edit_H #ifndef pivariant_edit_H
+2 -2
View File
@@ -36,7 +36,7 @@ PIVariantMap PIVariantEditors::Int::defaultAttributes() const {
void PIVariantEditors::Int::applyAttributes(const PIVariantMap & a) { void PIVariantEditors::Int::applyAttributes(const PIVariantMap & a) {
widget->setRange(a.value(PIValueTree::attributeMinimum, widget->minimum()).toInt(), widget->setRange(a.value(PIValueTree::attributeMinimum, widget->minimum()).toInt(),
a.value(PIValueTree::attributeMaximum, widget->maximum()).toInt()); a.value(PIValueTree::attributeMaximum, widget->maximum()).toInt());
widget->setSingleStep(a.value(PIValueTree::attributeSingleStep, widget->singleStep()).toInt()); widget->setSingleStep(a.value(PIValueTree::attributeSingleStep, widget->singleStep()).toInt());
widget->setPrefix(PI2QString(a.value(PIValueTree::attributePrefix, Q2PIString(widget->prefix())).toString())); widget->setPrefix(PI2QString(a.value(PIValueTree::attributePrefix, Q2PIString(widget->prefix())).toString()));
widget->setSuffix(PI2QString(a.value(PIValueTree::attributeSuffix, Q2PIString(widget->suffix())).toString())); widget->setSuffix(PI2QString(a.value(PIValueTree::attributeSuffix, Q2PIString(widget->suffix())).toString()));
@@ -60,7 +60,7 @@ PIVariantMap PIVariantEditors::Double::defaultAttributes() const {
void PIVariantEditors::Double::applyAttributes(const PIVariantMap & a) { void PIVariantEditors::Double::applyAttributes(const PIVariantMap & a) {
widget->setRange(a.value(PIValueTree::attributeMinimum, widget->minimum()).toDouble(), widget->setRange(a.value(PIValueTree::attributeMinimum, widget->minimum()).toDouble(),
a.value(PIValueTree::attributeMaximum, widget->maximum()).toDouble()); a.value(PIValueTree::attributeMaximum, widget->maximum()).toDouble());
widget->setSingleStep(a.value(PIValueTree::attributeSingleStep, widget->singleStep()).toDouble()); widget->setSingleStep(a.value(PIValueTree::attributeSingleStep, widget->singleStep()).toDouble());
widget->setDecimals(a.value(PIValueTree::attributeDecimals, widget->decimals()).toInt()); widget->setDecimals(a.value(PIValueTree::attributeDecimals, widget->decimals()).toInt());
widget->setPrefix(PI2QString(a.value(PIValueTree::attributePrefix, Q2PIString(widget->prefix())).toString())); widget->setPrefix(PI2QString(a.value(PIValueTree::attributePrefix, Q2PIString(widget->prefix())).toString()));
+12 -12
View File
@@ -1,20 +1,20 @@
/* /*
PIQt Utils - Qt utilites for PIP PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef pivariant_edit_widgets_H #ifndef pivariant_edit_widgets_H
+75 -77
View File
@@ -1,6 +1,6 @@
/* /*
QGLView QGLView
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -21,20 +21,20 @@
Camera::Camera() { Camera::Camera() {
type_ = glCamera; type_ = glCamera;
fov_ = 60.; fov_ = 60.;
angle_limit_lower_xy = 0.f; angle_limit_lower_xy = 0.f;
angle_limit_upper_xy = 360.f; angle_limit_upper_xy = 360.f;
angles_.setY(270.f); angles_.setY(270.f);
depth_start = 0.1f; depth_start = 0.1f;
depth_end = 1000.f; depth_end = 1000.f;
mirror_x = mirror_y = false; mirror_x = mirror_y = false;
} }
void Camera::anglesFromPoints() { void Camera::anglesFromPoints() {
QVector3D dv = aim_ - pos_, tv; QVector3D dv = aim_ - pos_, tv;
tv = QVector3D(dv.x(), dv.y(), 0.); tv = QVector3D(dv.x(), dv.y(), 0.);
angles_.setZ(atan2f(tv.x(), tv.y()) * rad2deg); angles_.setZ(atan2f(tv.x(), tv.y()) * rad2deg);
angles_.setY(piClamp<GLfloat>(atan2f(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.f); angles_.setY(piClamp<GLfloat>(atan2f(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.f);
} }
@@ -42,12 +42,11 @@ void Camera::anglesFromPoints() {
void Camera::apply(const GLfloat & aspect) { void Camera::apply(const GLfloat & aspect) {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
if (aspect <= 1.f) if (aspect <= 1.f) glScalef(aspect, aspect, 1.f);
glScalef(aspect, aspect, 1.f);
QMatrix4x4 pm = glMatrixPerspective(fov_, aspect, depth_start, depth_end); QMatrix4x4 pm = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
//pm.perspective(fov_, aspect, depth_start, depth_end); // pm.perspective(fov_, aspect, depth_start, depth_end);
//qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end); // qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end);
//qDebug() << pm; // qDebug() << pm;
setGLMatrix(pm); setGLMatrix(pm);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
pm.setToIdentity(); pm.setToIdentity();
@@ -55,17 +54,17 @@ void Camera::apply(const GLfloat & aspect) {
pm.rotate(angles_.y(), 1., 0., 0.); pm.rotate(angles_.y(), 1., 0., 0.);
pm.rotate(angles_.x(), 0., 1., 0.); pm.rotate(angles_.x(), 0., 1., 0.);
pm.rotate(angles_.z(), 0., 0., 1.); pm.rotate(angles_.z(), 0., 0., 1.);
//pm.translate(-aim_); // pm.translate(-aim_);
if (parent_) { if (parent_) {
QMatrix4x4 pmat = parent_->worldTransform(); QMatrix4x4 pmat = parent_->worldTransform();
offset_ = pmat.column(3).toVector3D(); offset_ = pmat.column(3).toVector3D();
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.; pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
pmat.translate(aim_); pmat.translate(aim_);
pm *= pmat.inverted(); pm *= pmat.inverted();
//qDebug() << pmat; // qDebug() << pmat;
} }
setGLMatrix(pm); setGLMatrix(pm);
//qDebug() << angles_; // qDebug() << angles_;
} }
@@ -77,65 +76,65 @@ QMatrix4x4 Camera::offsetMatrix() const {
/* /*
void Camera::localTransform(QMatrix4x4 & m) { void Camera::localTransform(QMatrix4x4 & m) {
return; return;
if (parent_) if (parent_)
m *= parent_->worldTransform(); m *= parent_->worldTransform();
QMatrix4x4 ret; QMatrix4x4 ret;
//qDebug() << "local camera"; //qDebug() << "local camera";
ret.translate(0., 0., -distance()); ret.translate(0., 0., -distance());
ret.rotate(angles_.y(), 1., 0., 0.); ret.rotate(angles_.y(), 1., 0., 0.);
ret.rotate(angles_.x(), 0., 1., 0.); ret.rotate(angles_.x(), 0., 1., 0.);
ret.rotate(angles_.z(), 0., 0., 1.); ret.rotate(angles_.z(), 0., 0., 1.);
//m *= ret.inverted(); //m *= ret.inverted();
} }
*/ */
void Camera::assign(const Camera & c) { void Camera::assign(const Camera & c) {
pos_ = c.pos_; pos_ = c.pos_;
aim_ = c.aim_; aim_ = c.aim_;
fov_ = c.fov_; fov_ = c.fov_;
angles_ = c.angles_; angles_ = c.angles_;
angle_limit_lower_xy = c.angle_limit_lower_xy; angle_limit_lower_xy = c.angle_limit_lower_xy;
angle_limit_upper_xy = c.angle_limit_upper_xy; angle_limit_upper_xy = c.angle_limit_upper_xy;
mirror_x = c.mirror_x; mirror_x = c.mirror_x;
mirror_y = c.mirror_y; mirror_y = c.mirror_y;
depth_start = c.depth_start; depth_start = c.depth_start;
depth_end = c.depth_end; depth_end = c.depth_end;
buildTransform(); buildTransform();
} }
GLObjectBase * Camera::clone(bool withChildren) { GLObjectBase * Camera::clone(bool withChildren) {
Camera * o = new Camera(*this); Camera * o = new Camera(*this);
//GLObjectBase::clone(withChildren); // GLObjectBase::clone(withChildren);
o->is_init = false; o->is_init = false;
o->name_ = name_ + "_copy"; o->name_ = name_ + "_copy";
o->view_ = nullptr; o->view_ = nullptr;
o->children_.clear(); o->children_.clear();
if (withChildren) { if (withChildren) {
for (int i = 0; i < children_.size(); ++i) for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren)); o->addChild(children_[i]->clone(withChildren));
} }
o->pos_ = pos_; o->pos_ = pos_;
o->aim_ = aim_; o->aim_ = aim_;
o->fov_ = fov_; o->fov_ = fov_;
o->angles_ = angles_; o->angles_ = angles_;
o->angle_limit_lower_xy = angle_limit_lower_xy; o->angle_limit_lower_xy = angle_limit_lower_xy;
o->angle_limit_upper_xy = angle_limit_upper_xy; o->angle_limit_upper_xy = angle_limit_upper_xy;
o->mirror_x = mirror_x; o->mirror_x = mirror_x;
o->mirror_y = mirror_y; o->mirror_y = mirror_y;
o->depth_start = depth_start; o->depth_start = depth_start;
o->depth_end = depth_end; o->depth_end = depth_end;
o->meta = meta; o->meta = meta;
return o; return o;
} }
void Camera::panZ(const float & a) { void Camera::panZ(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length(); float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(angles_.z() + a); angles_.setZ(angles_.z() + a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z()); dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
aim_ = pos_ + dv; aim_ = pos_ + dv;
buildTransform(); buildTransform();
} }
@@ -143,11 +142,11 @@ void Camera::panZ(const float & a) {
void Camera::panXY(const float & a) { void Camera::panXY(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc; float tl = dv.length(), tc;
angles_.setY(angles_.y() + a); angles_.setY(angles_.y() + a);
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy)); angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
tc = -sinf(angles_.y() * deg2rad); tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
aim_ = pos_ + dv * tl; aim_ = pos_ + dv * tl;
buildTransform(); buildTransform();
} }
@@ -155,9 +154,9 @@ void Camera::panXY(const float & a) {
void Camera::rotateZ(const float & a) { void Camera::rotateZ(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length(); float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(angles_.z() + a); angles_.setZ(angles_.z() + a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z()); dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
aim_ = pos_ + dv; aim_ = pos_ + dv;
buildTransform(); buildTransform();
} }
@@ -165,11 +164,11 @@ void Camera::rotateZ(const float & a) {
void Camera::rotateXY(const float & a) { void Camera::rotateXY(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc; float tl = dv.length(), tc;
angles_.setY(angles_.y() + a); angles_.setY(angles_.y() + a);
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy)); angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
tc = -sinf(angles_.y() * deg2rad); tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
aim_ = pos_ + dv * tl; aim_ = pos_ + dv * tl;
buildTransform(); buildTransform();
} }
@@ -177,9 +176,9 @@ void Camera::rotateXY(const float & a) {
void Camera::orbitZ(const float & a) { void Camera::orbitZ(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length(); float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(angles_.z() + a); angles_.setZ(angles_.z() + a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z()); dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
pos_ = aim_ - dv; pos_ = aim_ - dv;
buildTransform(); buildTransform();
} }
@@ -187,11 +186,11 @@ void Camera::orbitZ(const float & a) {
void Camera::orbitXY(const float & a) { void Camera::orbitXY(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc; float tl = dv.length(), tc;
angles_.setY(angles_.y() + a); angles_.setY(angles_.y() + a);
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy)); angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
tc = -sinf(angles_.y() * deg2rad); tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
pos_ = aim_ - dv * tl; pos_ = aim_ - dv * tl;
buildTransform(); buildTransform();
} }
@@ -199,9 +198,9 @@ void Camera::orbitXY(const float & a) {
void Camera::setAngleZ(const float & a) { void Camera::setAngleZ(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = QVector2D(dv.x(), dv.y()).length(); float tl = QVector2D(dv.x(), dv.y()).length();
angles_.setZ(a); angles_.setZ(a);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z()); dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
aim_ = pos_ + dv; aim_ = pos_ + dv;
buildTransform(); buildTransform();
} }
@@ -209,21 +208,21 @@ void Camera::setAngleZ(const float & a) {
void Camera::setAngleXY(const float & a) { void Camera::setAngleXY(const float & a) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = dv.length(), tc; float tl = dv.length(), tc;
angles_.setY(a); angles_.setY(a);
tc = -sinf(angles_.y() * deg2rad); tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
//pos_ = aim_ - dv; // pos_ = aim_ - dv;
aim_ = pos_ + dv * tl; aim_ = pos_ + dv * tl;
buildTransform(); buildTransform();
//anglesFromPoints(); // anglesFromPoints();
} }
void Camera::moveForward(const float & x, bool withZ) { void Camera::moveForward(const float & x, bool withZ) {
QVector3D dv;// = aim_ - pos_; QVector3D dv; // = aim_ - pos_;
float tc = -sinf(angles_.y() * deg2rad); float tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, 0.); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, 0.);
if (withZ) dv.setZ(-cosf(angles_.y() * deg2rad)); if (withZ) dv.setZ(-cosf(angles_.y() * deg2rad));
dv.normalize(); dv.normalize();
dv *= x; dv *= x;
@@ -234,9 +233,9 @@ void Camera::moveForward(const float & x, bool withZ) {
void Camera::moveLeft(const float & x, bool withZ) { void Camera::moveLeft(const float & x, bool withZ) {
QVector3D dv;// = aim_ - pos_; QVector3D dv; // = aim_ - pos_;
float tc = -sinf(angles_.y() * deg2rad); float tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad - float(M_PI_2)) * tc, cosf(angles_.z() * deg2rad - float(M_PI_2)) * tc, 0.f); dv = QVector3D(sinf(angles_.z() * deg2rad - float(M_PI_2)) * tc, cosf(angles_.z() * deg2rad - float(M_PI_2)) * tc, 0.f);
if (withZ) dv.setZ(-sinf(angles_.x() * deg2rad)); if (withZ) dv.setZ(-sinf(angles_.x() * deg2rad));
dv.normalize(); dv.normalize();
dv *= x; dv *= x;
@@ -252,7 +251,7 @@ void Camera::moveUp(const float & x, bool onlyZ) {
dv = QVector3D(0., 0., x); dv = QVector3D(0., 0., x);
else { else {
float tc = cosf(angles_.y() * deg2rad); float tc = cosf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -sinf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -sinf(angles_.y() * deg2rad));
dv.normalize(); dv.normalize();
dv *= x; dv *= x;
} }
@@ -265,7 +264,7 @@ void Camera::moveUp(const float & x, bool onlyZ) {
void Camera::flyCloser(const float & s) { void Camera::flyCloser(const float & s) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = dv.length() / (1.f + s), tc = -sinf(angles_.y() * deg2rad); float tl = dv.length() / (1.f + s), tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
pos_ = aim_ - dv * tl; pos_ = aim_ - dv * tl;
buildTransform(); buildTransform();
} }
@@ -274,7 +273,7 @@ void Camera::flyCloser(const float & s) {
void Camera::flyFarer(const float & s) { void Camera::flyFarer(const float & s) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tl = dv.length() * (1.f + s), tc = -sinf(angles_.y() * deg2rad); float tl = dv.length() * (1.f + s), tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
pos_ = aim_ - dv * tl; pos_ = aim_ - dv * tl;
buildTransform(); buildTransform();
} }
@@ -282,9 +281,8 @@ void Camera::flyFarer(const float & s) {
void Camera::flyToDistance(const float & d) { void Camera::flyToDistance(const float & d) {
QVector3D dv = aim_ - pos_; QVector3D dv = aim_ - pos_;
float tc = -sinf(angles_.y() * deg2rad); float tc = -sinf(angles_.y() * deg2rad);
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad)); dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
pos_ = aim_ - dv * d; pos_ = aim_ - dv * d;
buildTransform(); buildTransform();
} }
+75 -41
View File
@@ -1,6 +1,6 @@
/* /*
QGLView QGLView
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -23,66 +23,101 @@
class Camera; class Camera;
//extern QMatrix4x4 globCameraMatrix; // extern QMatrix4x4 globCameraMatrix;
//extern Camera * currentCamera; // extern Camera * currentCamera;
class Camera: public GLObjectBase class Camera: public GLObjectBase {
{
friend class QGLView; friend class QGLView;
friend class GLParticlesSystem; friend class GLParticlesSystem;
friend QDataStream & operator <<(QDataStream & s, const GLObjectBase * p); friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
friend QDataStream & operator >>(QDataStream & s, GLObjectBase *& p); friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
public: public:
Camera(); Camera();
void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();} void setPos(const QVector3D & p) {
void setAim(const QVector3D & p) {aim_ = p; anglesFromPoints(); buildTransform();} pos_ = p;
void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();} anglesFromPoints();
void move(const float & x, const float & y = 0., const float & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();} buildTransform();
}
void setAim(const QVector3D & p) {
aim_ = p;
anglesFromPoints();
buildTransform();
}
void move(const QVector3D & p) {
pos_ += p;
aim_ += p;
buildTransform();
}
void move(const float & x, const float & y = 0., const float & z = 0.) {
pos_ += QVector3D(x, y, z);
aim_ += QVector3D(x, y, z);
buildTransform();
}
void moveForward(const float & x, bool withZ = true); void moveForward(const float & x, bool withZ = true);
void moveBackward(const float & x, bool withZ = true) {moveForward(-x, withZ);} void moveBackward(const float & x, bool withZ = true) { moveForward(-x, withZ); }
void moveLeft(const float & x, bool withZ = true); void moveLeft(const float & x, bool withZ = true);
void moveRight(const float & x, bool withZ = true) {moveLeft(-x, withZ);} void moveRight(const float & x, bool withZ = true) { moveLeft(-x, withZ); }
void moveUp(const float & x, bool onlyZ = false); void moveUp(const float & x, bool onlyZ = false);
void moveDown(const float & x, bool onlyZ = false) {moveUp(-x, onlyZ);} void moveDown(const float & x, bool onlyZ = false) { moveUp(-x, onlyZ); }
void rotateZ(const float & a); void rotateZ(const float & a);
void rotateXY(const float & a); void rotateXY(const float & a);
void rotateRoll(const float & a) {angles_.setX(angles_.x() + a); buildTransform();} void rotateRoll(const float & a) {
angles_.setX(angles_.x() + a);
buildTransform();
}
void orbitZ(const float & a); void orbitZ(const float & a);
void orbitXY(const float & a); void orbitXY(const float & a);
void panZ(const float & a); void panZ(const float & a);
void panXY(const float & a); void panXY(const float & a);
void setFOV(const float & f) {fov_ = f;} void setFOV(const float & f) { fov_ = f; }
void setAngles(const QVector3D & a) {setRotation(a);} void setAngles(const QVector3D & a) { setRotation(a); }
void setAngleZ(const float & a); void setAngleZ(const float & a);
void setAngleXY(const float & a); void setAngleXY(const float & a);
void setAngleRoll(const float & a) {angles_.setX(a); buildTransform();} void setAngleRoll(const float & a) {
void setAngleLowerLimitXY(const float & a) {angle_limit_lower_xy = a; buildTransform();} angles_.setX(a);
void setAngleUpperLimitXY(const float & a) {angle_limit_upper_xy = a; buildTransform();} buildTransform();
void setAngleLimitsXY(const float & lower, const float & upper) {angle_limit_lower_xy = lower; angle_limit_upper_xy = upper; buildTransform();} }
void setDepthStart(const float & d) {depth_start = d;} void setAngleLowerLimitXY(const float & a) {
void setDepthEnd(const float & d) {depth_end = d;} angle_limit_lower_xy = a;
void setMirrorX(bool yes) {mirror_x = yes;} buildTransform();
void setMirrorY(bool yes) {mirror_y = yes;} }
void setAngleUpperLimitXY(const float & a) {
angle_limit_upper_xy = a;
buildTransform();
}
void setAngleLimitsXY(const float & lower, const float & upper) {
angle_limit_lower_xy = lower;
angle_limit_upper_xy = upper;
buildTransform();
}
void setDepthStart(const float & d) { depth_start = d; }
void setDepthEnd(const float & d) { depth_end = d; }
void setMirrorX(bool yes) { mirror_x = yes; }
void setMirrorY(bool yes) { mirror_y = yes; }
void flyCloser(const float & s); void flyCloser(const float & s);
void flyFarer(const float & s); void flyFarer(const float & s);
void flyToDistance(const float & d); void flyToDistance(const float & d);
QVector3D aim() const {return aim_;} QVector3D aim() const { return aim_; }
QVector3D angles() const {return rotation();} QVector3D angles() const { return rotation(); }
QVector3D direction() const {return (aim_ - pos_).normalized();} QVector3D direction() const { return (aim_ - pos_).normalized(); }
QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();} QVector3D directionXY() const {
float FOV() const {return fov_;} QVector3D tv = aim_ - pos_;
float distance() const {return (pos_ - aim_).length();} return QVector3D(tv.x(), tv.y(), 0.).normalized();
float angleZ() const {return angles_.z();} }
float angleXY() const {return angles_.y();} float FOV() const { return fov_; }
float angleRoll() const {return angles_.x();} float distance() const { return (pos_ - aim_).length(); }
float angleLowerLimitXY() const {return angle_limit_lower_xy;} float angleZ() const { return angles_.z(); }
float angleUpperLimitXY() const {return angle_limit_upper_xy;} float angleXY() const { return angles_.y(); }
float depthStart() const {return depth_start;} float angleRoll() const { return angles_.x(); }
float depthEnd() const {return depth_end;} float angleLowerLimitXY() const { return angle_limit_lower_xy; }
bool isMirrorX() const {return mirror_x;} float angleUpperLimitXY() const { return angle_limit_upper_xy; }
bool isMirrorY() const {return mirror_y;} float depthStart() const { return depth_start; }
float depthEnd() const { return depth_end; }
bool isMirrorX() const { return mirror_x; }
bool isMirrorY() const { return mirror_y; }
void anglesFromPoints(); void anglesFromPoints();
void apply(const GLfloat & aspect = 1.); void apply(const GLfloat & aspect = 1.);
void assign(const Camera & c); void assign(const Camera & c);
@@ -100,7 +135,6 @@ private:
GLfloat angle_limit_upper_xy; GLfloat angle_limit_upper_xy;
bool mirror_x; bool mirror_x;
bool mirror_y; bool mirror_y;
}; };
#endif // GLCAMERA_H #endif // GLCAMERA_H
+13 -13
View File
@@ -20,13 +20,13 @@
GLFramebuffer::GLFramebuffer(int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum target__) { GLFramebuffer::GLFramebuffer(int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum target__) {
is_depth = withDepth; is_depth = withDepth;
color_format = colorFormat_; color_format = colorFormat_;
target_ = target__; target_ = target__;
colors.fill(0, colorAttachments_); colors.fill(0, colorAttachments_);
fbo = drbo = 0; fbo = drbo = 0;
tex_d = 0; tex_d = 0;
wid = hei = 0; wid = hei = 0;
is_changed = false; is_changed = false;
} }
@@ -80,8 +80,8 @@ void GLFramebuffer::resize(int width, int height, bool force) {
QImage GLFramebuffer::grab() const { QImage GLFramebuffer::grab() const {
//glReadPixels(0, 0, wid, hei, GL_RGBA, ); // glReadPixels(0, 0, wid, hei, GL_RGBA, );
//QImage ret(); // QImage ret();
return QImage(); return QImage();
} }
@@ -90,17 +90,17 @@ void GLFramebuffer::bind() {
if (is_changed) resize(wid, hei); if (is_changed) resize(wid, hei);
if (fbo == 0) return; if (fbo == 0) return;
initializeOpenGLFunctions(); initializeOpenGLFunctions();
//glFlush(); // glFlush();
glGetIntegerv(GL_VIEWPORT, prev_view); glGetIntegerv(GL_VIEWPORT, prev_view);
//glClearError(); // glClearError();
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
//qDebug() << QString::number(glGetError(), 16); // qDebug() << QString::number(glGetError(), 16);
QVector<GLenum> buffers; QVector<GLenum> buffers;
for (int i = 0; i < colors.size(); ++i) for (int i = 0; i < colors.size(); ++i)
buffers << GL_COLOR_ATTACHMENT0 + i; buffers << GL_COLOR_ATTACHMENT0 + i;
glDrawBuffers(buffers.size(), buffers.constData()); glDrawBuffers(buffers.size(), buffers.constData());
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
//glDrawBuffer(GL_COLOR_ATTACHMENT0); // glDrawBuffer(GL_COLOR_ATTACHMENT0);
glViewport(0, 0, wid, hei); glViewport(0, 0, wid, hei);
} }
@@ -108,17 +108,17 @@ void GLFramebuffer::bind() {
void GLFramebuffer::release() { void GLFramebuffer::release() {
is_changed = false; is_changed = false;
if (fbo == 0) return; if (fbo == 0) return;
//glFlush(); // glFlush();
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(prev_view[0], prev_view[1], prev_view[2], prev_view[3]); glViewport(prev_view[0], prev_view[1], prev_view[2], prev_view[3]);
} }
void GLFramebuffer::setWriteBuffer(int index) { void GLFramebuffer::setWriteBuffer(int index) {
//QVector<GLenum> buffers; buffers << GL_COLOR_ATTACHMENT0 + index; // QVector<GLenum> buffers; buffers << GL_COLOR_ATTACHMENT0 + index;
GLenum e = GL_COLOR_ATTACHMENT0 + index; GLenum e = GL_COLOR_ATTACHMENT0 + index;
glDrawBuffer(e); glDrawBuffer(e);
//glDrawBuffers(1, &e); // glDrawBuffers(1, &e);
} }
+25 -17
View File
@@ -19,48 +19,56 @@
#ifndef GLFRAMEBUFFER_H #ifndef GLFRAMEBUFFER_H
#define GLFRAMEBUFFER_H #define GLFRAMEBUFFER_H
#include <QOpenGLExtraFunctions>
#include "gltypes.h" #include "gltypes.h"
#include <QOpenGLExtraFunctions>
class GLFramebuffer : protected QOpenGLExtraFunctions
{ class GLFramebuffer: protected QOpenGLExtraFunctions {
public: public:
GLFramebuffer(int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum target = GL_TEXTURE_2D); GLFramebuffer(int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum target = GL_TEXTURE_2D);
virtual ~GLFramebuffer(); virtual ~GLFramebuffer();
GLuint id() const {return fbo;} GLuint id() const { return fbo; }
GLuint colorTexture(int index = 0) const {return colors[index];} GLuint colorTexture(int index = 0) const { return colors[index]; }
GLenum colorFormat() const {return color_format;} GLenum colorFormat() const { return color_format; }
GLuint depthTexture() const {return tex_d;} GLuint depthTexture() const { return tex_d; }
GLenum target() const {return target_;} GLenum target() const { return target_; }
int width() const {return wid;} int width() const { return wid; }
int height() const {return hei;} int height() const { return hei; }
QSize size() const {return QSize(wid, hei);} QSize size() const { return QSize(wid, hei); }
QImage grab() const; QImage grab() const;
void resize(int width, int height, bool force = false); void resize(int width, int height, bool force = false);
void bind(); void bind();
void release(); void release();
void setReadBuffer(int index) {glReadBuffer(GL_COLOR_ATTACHMENT0 + index);} void setReadBuffer(int index) { glReadBuffer(GL_COLOR_ATTACHMENT0 + index); }
void setWriteBuffer(int index); void setWriteBuffer(int index);
void setWriteBuffers(int * indeces, int count); void setWriteBuffers(int * indeces, int count);
void setColorFormat(GLenum format) {color_format = format; is_changed = true;} void setColorFormat(GLenum format) {
color_format = format;
is_changed = true;
}
void copyDepthFrom(GLuint tex) {;} void copyDepthFrom(GLuint tex) { ; }
void bindColorTextures(); void bindColorTextures();
void bindDepthTexture(int channel); void bindDepthTexture(int channel);
private: private:
void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;} void deleteGLRenderbuffer(GLuint & drbo) {
void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;} if (drbo != 0) glDeleteRenderbuffers(1, &drbo);
drbo = 0;
}
void deleteGLFramebuffer(GLuint & fbo) {
if (fbo != 0) glDeleteFramebuffers(1, &fbo);
fbo = 0;
}
bool is_depth, is_changed; bool is_depth, is_changed;
QVector<GLuint> colors; QVector<GLuint> colors;
GLenum color_format, target_; GLenum color_format, target_;
GLuint fbo, drbo, tex_d; GLuint fbo, drbo, tex_d;
GLint prev_view[4], wid, hei; GLint prev_view[4], wid, hei;
}; };
#endif // GLFRAMEBUFFER_H #endif // GLFRAMEBUFFER_H
+88 -70
View File
@@ -23,24 +23,24 @@ QStringList GLTextureManagerBase::search_pathes(".");
bool GLCubeTexture::create() { bool GLCubeTexture::create() {
//qDebug("create"); // qDebug("create");
destroy(); destroy();
glGenTextures(1, &id_); glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_CUBE_MAP, id_); glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR /*_MIPMAP_LINEAR*/);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); // glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
//glClearError(); // glClearError();
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
//qDebug() << glGetError(); // qDebug() << glGetError();
changed_ = false; changed_ = false;
return id_ > 0; return id_ > 0;
} }
@@ -59,28 +59,41 @@ void GLCubeTexture::load() {
void GLCubeTexture::loadFromDirectory(const QString & dir) { void GLCubeTexture::loadFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl; QDir d(dir);
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath()); QFileInfoList sl;
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath()); sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath()); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath()); sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath()); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath()); sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath());
} }
void GLCubeTexture::loadPathesFromDirectory(const QString & dir) { void GLCubeTexture::loadPathesFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl; QDir d(dir);
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath(); QFileInfoList sl;
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath(); sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath(); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath(); sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath(); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath(); sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath();
} }
QString GLTextureManagerBase::findFile(const QString & path) { QString GLTextureManagerBase::findFile(const QString & path) {
return ::findFile(path, search_pathes); return ::findFile(path, search_pathes);
} }
@@ -91,16 +104,16 @@ GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, b
if (p.isEmpty()) return 0; if (p.isEmpty()) return 0;
int tid = textureID(p, bump); int tid = textureID(p, bump);
if (tid > 0) { if (tid > 0) {
//qDebug() << "[TextureManager] Found" << path << "as" << tid; // qDebug() << "[TextureManager] Found" << path << "as" << tid;
return tid; return tid;
} }
QImage image(p); QImage image(p);
if (bump) convertToNormal(image); if (bump) convertToNormal(image);
//qDebug() << p << image.width() << image.height() << image.format() << bump; // qDebug() << p << image.width() << image.height() << image.format() << bump;
///tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, __GLContext__::MipmapBindOption*/); /// tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, __GLContext__::MipmapBindOption*/);
//GLuint tid = 0; // GLuint tid = 0;
GLuint _tid = tid; GLuint _tid = tid;
createGLTexture(_tid, image);///currentQGLView->bindTexture(image, GL_TEXTURE_2D); createGLTexture(_tid, image); /// currentQGLView->bindTexture(image, GL_TEXTURE_2D);
tid = _tid; tid = _tid;
if (tid == 0) { if (tid == 0) {
qDebug() << "[TextureManager] Can`t load" << p; qDebug() << "[TextureManager] Can`t load" << p;
@@ -117,12 +130,12 @@ GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool
QImage image(im); QImage image(im);
if (bump) convertToNormal(image); if (bump) convertToNormal(image);
GLuint tid = 0; GLuint tid = 0;
createGLTexture(tid, im);///currentQGLView->bindTexture(image, GL_TEXTURE_2D); createGLTexture(tid, im); /// currentQGLView->bindTexture(image, GL_TEXTURE_2D);
if (tid == 0) { if (tid == 0) {
qDebug() << "[TextureManager] Can`t load image"; qDebug() << "[TextureManager] Can`t load image";
return tid; return tid;
} }
//qDebug() << "[TextureManager] Loaded image as" << tid; // qDebug() << "[TextureManager] Loaded image as" << tid;
if (ownership) tex_ids[bump ? 1 : 0].insert(QString(), tid); if (ownership) tex_ids[bump ? 1 : 0].insert(QString(), tid);
return tid; return tid;
} }
@@ -150,21 +163,24 @@ void GLTextureManagerBase::reloadTexture(GLuint tid, const QImage & im) {
Vector3d colorVector(QRgb c) { Vector3d colorVector(QRgb c) {
return Vector3d(((uchar*)(&c))[0] / 255., ((uchar*)(&c))[1] / 255., ((uchar*)(&c))[2] / 255.); return Vector3d(((uchar *)(&c))[0] / 255., ((uchar *)(&c))[1] / 255., ((uchar *)(&c))[2] / 255.);
} }
void GLTextureManagerBase::convertToNormal(QImage & im) { void GLTextureManagerBase::convertToNormal(QImage & im) {
if (im.isNull()) return; if (im.isNull()) return;
QImage sim = im.convertToFormat(QImage::Format_ARGB32); QImage sim = im.convertToFormat(QImage::Format_ARGB32);
float sum[3] = {0., 0., 0.}; float sum[3] = {0., 0., 0.};
llong a = 0; llong a = 0;
const uchar * sd = sim.constBits(); const uchar * sd = sim.constBits();
for (int i = 0; i < sim.height(); i++) { for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) { for (int j = 0; j < sim.width(); j++) {
sum[2] += sd[a] / 255.f - 0.5f; ++a; sum[2] += sd[a] / 255.f - 0.5f;
sum[1] += sd[a] / 255.f - 0.5f; ++a; ++a;
sum[0] += sd[a] / 255.f - 0.5f; ++a; sum[1] += sd[a] / 255.f - 0.5f;
++a;
sum[0] += sd[a] / 255.f - 0.5f;
++a;
++a; ++a;
} }
} }
@@ -178,7 +194,7 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
qDebug() << "convert to bump"; qDebug() << "convert to bump";
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32); QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
int tx, ty, w = sim.width(), h = sim.height(); int tx, ty, w = sim.width(), h = sim.height();
a = 0; a = 0;
uchar * dd = dim.bits(); uchar * dd = dim.bits();
for (int i = 0; i < sim.height(); i++) { for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) { for (int j = 0; j < sim.width(); j++) {
@@ -187,40 +203,42 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
ty = i - 1; ty = i - 1;
ty = ty < 0 ? h + ty : ty % h; ty = ty < 0 ? h + ty : ty % h;
Vector3d p[3], res; Vector3d p[3], res;
p[0] = colorVector(sim.pixel(j, i)); p[0] = colorVector(sim.pixel(j, i));
p[1] = colorVector(sim.pixel(j, ty)); p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i)); p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f); res.y = piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f);
res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f); res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
tx = (j + 1) % w; tx = (j + 1) % w;
ty = (i + 1) % h; ty = (i + 1) % h;
p[1] = colorVector(sim.pixel(j, ty)); p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i)); p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f); res.y = piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f);
res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f); res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
res.z = 1.; res.z = 1.;
dd[a] = res.z * 255; ++a; dd[a] = res.z * 255;
dd[a] = res.x * 255; ++a; ++a;
dd[a] = res.y * 255; ++a; dd[a] = res.x * 255;
dd[a] = 255; ++a; ++a;
dd[a] = res.y * 255;
++a;
dd[a] = 255;
++a;
} }
} }
im = dim; im = dim;
//im.save("_bump.png"); // im.save("_bump.png");
} }
Material::Material(): map_reflection(512) { Material::Material(): map_reflection(512) {
color_diffuse = color_specular = Qt::white; color_diffuse = color_specular = Qt::white;
color_self_illumination = Qt::black; color_self_illumination = Qt::black;
glass = false; glass = false;
transparency = reflectivity = 0.f; transparency = reflectivity = 0.f;
map_specularity.color_amount = 0.5f; map_specularity.color_amount = 0.5f;
map_specular.color_amount = 1.f; map_specular.color_amount = 1.f;
iof = 1.f; iof = 1.f;
dispersion = 0.05f; dispersion = 0.05f;
} }
@@ -228,24 +246,24 @@ void Material::apply(QOpenGLShaderProgram * prog) {
if (prog) { if (prog) {
setUniformMaterial(prog, *this); setUniformMaterial(prog, *this);
} else { } else {
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f}; GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f};
GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f}; GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f};
mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF(); mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF();
mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF(); mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF();
mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF(); mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF();
mat_diffuse[3] = map_diffuse.color_amount * color_diffuse.alphaF() * (1.f - transparency); mat_diffuse[3] = map_diffuse.color_amount * color_diffuse.alphaF() * (1.f - transparency);
mat_specular[0] = map_specular.color_amount * color_specular.redF(); mat_specular[0] = map_specular.color_amount * color_specular.redF();
mat_specular[1] = map_specular.color_amount * color_specular.greenF(); mat_specular[1] = map_specular.color_amount * color_specular.greenF();
mat_specular[2] = map_specular.color_amount * color_specular.blueF(); mat_specular[2] = map_specular.color_amount * color_specular.blueF();
mat_emission[0] = map_self_illumination.color_amount * color_self_illumination.redF(); mat_emission[0] = map_self_illumination.color_amount * color_self_illumination.redF();
mat_emission[1] = map_self_illumination.color_amount * color_self_illumination.greenF(); mat_emission[1] = map_self_illumination.color_amount * color_self_illumination.greenF();
mat_emission[2] = map_self_illumination.color_amount * color_self_illumination.blueF(); mat_emission[2] = map_self_illumination.color_amount * color_self_illumination.blueF();
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]); glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
//qDebug() << (map_specularity.color_amount)*128.; // qDebug() << (map_specularity.color_amount)*128.;
glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount)*128.f); glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount) * 128.f);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
} }
@@ -253,7 +271,7 @@ void Material::apply(QOpenGLShaderProgram * prog) {
void Material::loadTextures(GLTextureManagerBase * tm) { void Material::loadTextures(GLTextureManagerBase * tm) {
//qDebug() << "load textures"; // qDebug() << "load textures";
if (!tm) return; if (!tm) return;
if (!map_diffuse.bitmap_path.isEmpty()) map_diffuse.bitmap_id = tm->loadTexture(map_diffuse.bitmap_path); if (!map_diffuse.bitmap_path.isEmpty()) map_diffuse.bitmap_id = tm->loadTexture(map_diffuse.bitmap_path);
if (!map_normal.bitmap_path.isEmpty()) map_normal.bitmap_id = tm->loadTexture(map_normal.bitmap_path, true, true); if (!map_normal.bitmap_path.isEmpty()) map_normal.bitmap_id = tm->loadTexture(map_normal.bitmap_path, true, true);
@@ -261,6 +279,6 @@ void Material::loadTextures(GLTextureManagerBase * tm) {
if (!map_specularity.bitmap_path.isEmpty()) map_specularity.bitmap_id = tm->loadTexture(map_specularity.bitmap_path); if (!map_specularity.bitmap_path.isEmpty()) map_specularity.bitmap_id = tm->loadTexture(map_specularity.bitmap_path);
if (!map_specular.bitmap_path.isEmpty()) map_specular.bitmap_id = tm->loadTexture(map_specular.bitmap_path); if (!map_specular.bitmap_path.isEmpty()) map_specular.bitmap_id = tm->loadTexture(map_specular.bitmap_path);
if (!map_self_illumination.bitmap_path.isEmpty()) map_self_illumination.bitmap_id = tm->loadTexture(map_self_illumination.bitmap_path); if (!map_self_illumination.bitmap_path.isEmpty()) map_self_illumination.bitmap_id = tm->loadTexture(map_self_illumination.bitmap_path);
//if (!map_diffuse_2.bitmap_path.isEmpty()) map_diffuse_2.bitmap_id = tm->loadTexture(map_diffuse_2.bitmap_path); // if (!map_diffuse_2.bitmap_path.isEmpty()) map_diffuse_2.bitmap_id = tm->loadTexture(map_diffuse_2.bitmap_path);
map_reflection.load(); map_reflection.load();
} }
+163 -57
View File
@@ -1,39 +1,55 @@
/* /*
QGLView QGLView
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLMATERIAL_H #ifndef GLMATERIAL_H
#define GLMATERIAL_H #define GLMATERIAL_H
#include "gltypes.h"
#include "chunkstream.h" #include "chunkstream.h"
#include "gltypes.h"
class GLTexture { class GLTexture {
public: public:
GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {wid = _width; hei = _height; format_ = _format; target_ = _target; id_ = 0;} GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {
bool create() {destroy(); createGLTexture(id_, wid, hei, format_, target_); return id_ > 0;} wid = _width;
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;} hei = _height;
void bind() {if (id_ > 0) glBindTexture(target_, id_);} format_ = _format;
void release() {glBindTexture(target_, 0);} target_ = _target;
int width() const {return wid;} id_ = 0;
int height() const {return hei;} }
GLenum format() const {return format_;} bool create() {
GLenum target() const {return target_;} destroy();
GLuint id() const {return id_;} createGLTexture(id_, wid, hei, format_, target_);
return id_ > 0;
}
void destroy() {
if (id_ > 0) glDeleteTextures(1, &id_);
id_ = 0;
}
void bind() {
if (id_ > 0) glBindTexture(target_, id_);
}
void release() { glBindTexture(target_, 0); }
int width() const { return wid; }
int height() const { return hei; }
GLenum format() const { return format_; }
GLenum target() const { return target_; }
GLuint id() const { return id_; }
private: private:
int wid, hei; int wid, hei;
GLenum format_, target_; GLenum format_, target_;
@@ -43,27 +59,95 @@ private:
class GLCubeTexture { class GLCubeTexture {
public: public:
GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);} GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {
size = _size;
format_ = _format;
id_ = 0;
changed_ = false;
pathes.resize(6);
}
bool create(); bool create();
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;} void destroy() {
void bind() {if (changed_) {changed_ = false; create();} if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);} if (id_ > 0) glDeleteTextures(1, &id_);
void release() {glBindTexture(GL_TEXTURE_CUBE_MAP, 0);} id_ = 0;
void resize(int _size) {size = _size; changed_ = true;} }
void bind() {
if (changed_) {
changed_ = false;
create();
}
if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
}
void release() { glBindTexture(GL_TEXTURE_CUBE_MAP, 0); }
void resize(int _size) {
size = _size;
changed_ = true;
}
void loadFromDirectory(const QString & dir); void loadFromDirectory(const QString & dir);
void loadFront(const QString & path) {bind(); pathes[0] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_X);} void loadFront(const QString & path) {
void loadBack(const QString & path) {bind(); pathes[1] = path; createGLTexture(id_, rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);} bind();
void loadLeft(const QString & path) {bind(); pathes[2] = path; createGLTexture(id_, QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);} pathes[0] = path;
void loadRight(const QString & path) {bind(); pathes[3] = path; createGLTexture(id_, rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);} createGLTexture(id_,
void loadTop(const QString & path) {bind(); pathes[4] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);} rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
void loadBottom(const QString & path) {bind(); pathes[5] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);} format_,
GL_TEXTURE_CUBE_MAP_POSITIVE_X);
}
void loadBack(const QString & path) {
bind();
pathes[1] = path;
createGLTexture(id_,
rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
}
void loadLeft(const QString & path) {
bind();
pathes[2] = path;
createGLTexture(id_,
QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
}
void loadRight(const QString & path) {
bind();
pathes[3] = path;
createGLTexture(id_,
rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
}
void loadTop(const QString & path) {
bind();
pathes[4] = path;
createGLTexture(id_,
rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
}
void loadBottom(const QString & path) {
bind();
pathes[5] = path;
createGLTexture(id_,
rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
}
void load(); void load();
bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;} bool isEmpty() const {
GLenum format() const {return format_;} foreach(const QString & i, pathes)
void setFormat(GLenum f) {format_ = f; changed_ = true;} if (!i.isEmpty()) return false;
GLuint id() const {return id_;} return true;
const QString & path(int side) const {return pathes[side];} }
void setPath(int side, const QString & p) {pathes[side] = p;} GLenum format() const { return format_; }
void setFormat(GLenum f) {
format_ = f;
changed_ = true;
}
GLuint id() const { return id_; }
const QString & path(int side) const { return pathes[side]; }
void setPath(int side, const QString & p) { pathes[side] = p; }
void loadPathesFromDirectory(const QString & dir); void loadPathesFromDirectory(const QString & dir);
private: private:
bool changed_; bool changed_;
int size; int size;
@@ -78,28 +162,33 @@ class GLTextureManagerBase {
public: public:
GLTextureManagerBase() {} GLTextureManagerBase() {}
virtual ~GLTextureManagerBase() {} virtual ~GLTextureManagerBase() {}
void addSearchPath(const QString & path) {search_pathes << path;} void addSearchPath(const QString & path) { search_pathes << path; }
static QStringList searchPathes() {return search_pathes;} static QStringList searchPathes() { return search_pathes; }
QString findFile(const QString & path); QString findFile(const QString & path);
GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false); GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false); GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
void reloadTexture(GLuint tid, const QString & path); void reloadTexture(GLuint tid, const QString & path);
void reloadTexture(GLuint tid, const QImage & image); void reloadTexture(GLuint tid, const QImage & image);
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];} int textureID(const QString & path, bool bump = false) { return tex_ids[bump ? 1 : 0][path]; }
virtual void addTexture(const QString & path) = 0; virtual void addTexture(const QString & path) = 0;
virtual void addAnimation(const QString & dir, const QString & name) = 0; virtual void addAnimation(const QString & dir, const QString & name) = 0;
virtual bool loadTextures() = 0; virtual bool loadTextures() = 0;
protected: protected:
static void convertToNormal(QImage & im); static void convertToNormal(QImage & im);
static QStringList search_pathes; static QStringList search_pathes;
QMap<QString, GLuint> tex_ids[2]; QMap<QString, GLuint> tex_ids[2];
}; };
class Map { class Map {
public: public:
Map() {bitmap_id = 0; color_amount = 1.f; color_offset = 0.f; animation_frame_rate = -1.f; bitmap_scale = QPointF(1., 1.);} Map() {
bitmap_id = 0;
color_amount = 1.f;
color_offset = 0.f;
animation_frame_rate = -1.f;
bitmap_scale = QPointF(1., 1.);
}
QString bitmap_path; QString bitmap_path;
GLuint bitmap_id; GLuint bitmap_id;
QPointF bitmap_offset; QPointF bitmap_offset;
@@ -137,12 +226,18 @@ public:
}; };
inline QDataStream & operator <<(QDataStream & s, const Map & m) { inline QDataStream & operator<<(QDataStream & s, const Map & m) {
ChunkStream cs; ChunkStream cs;
cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(4, m.animation).add(5, m.animation_frame_rate).add(6, m.bitmap_scale); cs.add(1, m.bitmap_path)
s << cs.data(); return s; .add(2, m.color_amount)
.add(3, m.color_offset)
.add(4, m.animation)
.add(5, m.animation_frame_rate)
.add(6, m.bitmap_scale);
s << cs.data();
return s;
} }
inline QDataStream & operator >>(QDataStream & s, Map & m) { inline QDataStream & operator>>(QDataStream & s, Map & m) {
ChunkStream cs(s); ChunkStream cs(s);
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
@@ -157,14 +252,25 @@ inline QDataStream & operator >>(QDataStream & s, Map & m) {
return s; return s;
} }
inline QDataStream & operator <<(QDataStream & s, const Material & m) { inline QDataStream & operator<<(QDataStream & s, const Material & m) {
ChunkStream cs; ChunkStream cs;
cs.add(1, m.name).add(2, m.color_diffuse).add(3, m.color_specular).add(4, m.color_self_illumination) cs.add(1, m.name)
.add(5, m.transparency).add(6, m.reflectivity).add(7, m.glass).add(8, m.map_diffuse).add(9, m.map_normal) .add(2, m.color_diffuse)
.add(10, m.map_relief).add(11, m.map_specular).add(12, m.map_specularity).add(13, m.map_self_illumination); .add(3, m.color_specular)
s << qCompress(cs.data()); return s; .add(4, m.color_self_illumination)
.add(5, m.transparency)
.add(6, m.reflectivity)
.add(7, m.glass)
.add(8, m.map_diffuse)
.add(9, m.map_normal)
.add(10, m.map_relief)
.add(11, m.map_specular)
.add(12, m.map_specularity)
.add(13, m.map_self_illumination);
s << qCompress(cs.data());
return s;
} }
inline QDataStream & operator >>(QDataStream & s, Material & m) { inline QDataStream & operator>>(QDataStream & s, Material & m) {
QByteArray ba; QByteArray ba;
s >> ba; s >> ba;
ba = qUncompress(ba); ba = qUncompress(ba);
+267 -191
View File
@@ -17,34 +17,35 @@
*/ */
#include "globject.h" #include "globject.h"
#include "glcamera.h" #include "glcamera.h"
#include "qglview.h" #include "qglview.h"
GLObjectBase::GLObjectBase() { GLObjectBase::GLObjectBase() {
type_ = glMesh; type_ = glMesh;
render_mode = View; render_mode = View;
pass_ = Solid; pass_ = Solid;
geom_prim = Triangles; geom_prim = Triangles;
scale_ = QVector3D(1., 1., 1.); scale_ = QVector3D(1., 1., 1.);
parent_ = nullptr; parent_ = nullptr;
is_root = is_init = is_tex_loaded = selected_ = false; is_root = is_init = is_tex_loaded = selected_ = false;
visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true; visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true;
line_width = -1.; line_width = -1.;
blend_src = GL_SRC_ALPHA; blend_src = GL_SRC_ALPHA;
blend_dest = GL_ONE_MINUS_SRC_ALPHA; blend_dest = GL_ONE_MINUS_SRC_ALPHA;
type_ = glMesh; type_ = glMesh;
raw_matrix = false; raw_matrix = false;
mat_.setToIdentity(); mat_.setToIdentity();
view_ = nullptr; view_ = nullptr;
} }
GLObjectBase::~GLObjectBase() { GLObjectBase::~GLObjectBase() {
//qDebug() << "del" << name() << view_; // qDebug() << "del" << name() << view_;
if (parent_) parent_->children_.removeAll(this); if (parent_) parent_->children_.removeAll(this);
if (view_) ((QGLView*)view_)->objectDeleted(this); if (view_) ((QGLView *)view_)->objectDeleted(this);
foreach (GLObjectBase * c, children_) { foreach(GLObjectBase * c, children_) {
c->parent_ = nullptr; c->parent_ = nullptr;
delete c; delete c;
} }
@@ -52,37 +53,37 @@ GLObjectBase::~GLObjectBase() {
GLObjectBase * GLObjectBase::clone(bool withChildren) { GLObjectBase * GLObjectBase::clone(bool withChildren) {
GLObjectBase * o = new GLObjectBase(); GLObjectBase * o = new GLObjectBase();
o->pass_ = pass_; o->pass_ = pass_;
o->is_init = false; o->is_init = false;
o->accept_light = accept_light; o->accept_light = accept_light;
o->accept_fog = accept_fog; o->accept_fog = accept_fog;
o->visible_ = visible_; o->visible_ = visible_;
o->type_ = type_; o->type_ = type_;
o->raw_matrix = raw_matrix; o->raw_matrix = raw_matrix;
o->mat_ = mat_; o->mat_ = mat_;
o->pos_ = pos_; o->pos_ = pos_;
o->angles_ = angles_; o->angles_ = angles_;
o->scale_ = scale_; o->scale_ = scale_;
o->itransform_ = itransform_; o->itransform_ = itransform_;
o->bound = bound; o->bound = bound;
o->name_ = name_ + "_copy"; o->name_ = name_ + "_copy";
o->blend_src = blend_src; o->blend_src = blend_src;
o->blend_dest = blend_dest; o->blend_dest = blend_dest;
o->material_ = material_; o->material_ = material_;
o->pos_h = pos_h; o->pos_h = pos_h;
o->points = points; o->points = points;
o->puvws = puvws; o->puvws = puvws;
o->faces = faces; o->faces = faces;
o->uvws = uvws; o->uvws = uvws;
o->norms = norms; o->norms = norms;
o->normals = normals; o->normals = normals;
o->vbo.vertices_ = vbo.vertices_; o->vbo.vertices_ = vbo.vertices_;
o->vbo.normals_ = vbo.normals_; o->vbo.normals_ = vbo.normals_;
o->vbo.texcoords_ = vbo.texcoords_; o->vbo.texcoords_ = vbo.texcoords_;
o->vbo.colors_ = vbo.colors_; o->vbo.colors_ = vbo.colors_;
o->meta = meta; o->meta = meta;
o->view_ = nullptr; o->view_ = nullptr;
o->children_.clear(); o->children_.clear();
if (withChildren) { if (withChildren) {
for (int i = 0; i < children_.size(); ++i) for (int i = 0; i < children_.size(); ++i)
@@ -96,8 +97,8 @@ void GLObjectBase::init() {
calculateBoundingBox(); calculateBoundingBox();
vbo.init(); vbo.init();
vbo.rebuffer(); vbo.rebuffer();
//material_.reflection.create(); // material_.reflection.create();
//qDebug() << "init" << vbo.buffer_; // qDebug() << "init" << vbo.buffer_;
is_init = true; is_init = true;
} }
@@ -105,42 +106,41 @@ void GLObjectBase::init() {
void GLObjectBase::draw(QOpenGLShaderProgram * prog, bool simplest) { void GLObjectBase::draw(QOpenGLShaderProgram * prog, bool simplest) {
vbo.draw(geom_prim, prog, simplest); vbo.draw(geom_prim, prog, simplest);
/*if (!d_vertices.isEmpty()) { /*if (!d_vertices.isEmpty()) {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData()); glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData()); glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData());
//glColorPointer(4, GL_FLOAT, 0, d_colors.constData()); //glColorPointer(4, GL_FLOAT, 0, d_colors.constData());
glNormalPointer(GL_FLOAT, 0, d_normals.constData()); glNormalPointer(GL_FLOAT, 0, d_normals.constData());
glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/ glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/
/*if (pass_ == Reflection) { /*if (pass_ == Reflection) {
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
}*/ }*/
//} //}
} }
void GLObjectBase::setView(QGLView * v) { void GLObjectBase::setView(QGLView * v) {
view_ = v; view_ = v;
foreach (GLObjectBase * c, children_) foreach(GLObjectBase * c, children_)
c->setView(v); c->setView(v);
} }
void GLObjectBase::addChild(GLObjectBase * o) { void GLObjectBase::addChild(GLObjectBase * o) {
if (o == this) return; if (o == this) return;
if (o->parent_) if (o->parent_) o->parent_->children_.removeAll(o);
o->parent_->children_.removeAll(o);
children_ << o; children_ << o;
o->parent_ = this; o->parent_ = this;
o->setView((QGLView*)view_); o->setView((QGLView *)view_);
o->buildTransform(); o->buildTransform();
if (view_) { if (view_) {
view_->collectLights(); view_->collectLights();
QList<GLObjectBase*> cl = o->children(true); QList<GLObjectBase *> cl = o->children(true);
cl << o; cl << o;
foreach (GLObjectBase * i, cl) { foreach(GLObjectBase * i, cl) {
emit ((QGLView*)view_)->objectAdded(i); emit((QGLView *)view_)->objectAdded(i);
} }
} }
} }
@@ -164,8 +164,8 @@ void GLObjectBase::removeChild(int index) {
void GLObjectBase::clearChildren(bool deleteAll) { void GLObjectBase::clearChildren(bool deleteAll) {
foreach (GLObjectBase * i, children_) { foreach(GLObjectBase * i, children_) {
i->view_ = nullptr; i->view_ = nullptr;
i->parent_ = nullptr; i->parent_ = nullptr;
i->clearChildren(deleteAll); i->clearChildren(deleteAll);
if (deleteAll) { if (deleteAll) {
@@ -186,7 +186,7 @@ GLObjectBase * GLObjectBase::child(int index) {
GLObjectBase * GLObjectBase::child(const QString & name) { GLObjectBase * GLObjectBase::child(const QString & name) {
foreach (GLObjectBase * i, children_) foreach(GLObjectBase * i, children_)
if (i->name_ == name) return i; if (i->name_ == name) return i;
return nullptr; return nullptr;
} }
@@ -199,15 +199,15 @@ const GLObjectBase * GLObjectBase::child(int index) const {
const GLObjectBase * GLObjectBase::child(const QString & name) const { const GLObjectBase * GLObjectBase::child(const QString & name) const {
foreach (GLObjectBase * i, children_) foreach(GLObjectBase * i, children_)
if (i->name_ == name) return i; if (i->name_ == name) return i;
return nullptr; return nullptr;
} }
QList<GLObjectBase * > GLObjectBase::children(bool all_) { QList<GLObjectBase *> GLObjectBase::children(bool all_) {
if (!all_) return children_; if (!all_) return children_;
QList<GLObjectBase * > cl; QList<GLObjectBase *> cl;
addChildren(cl, this); addChildren(cl, this);
return cl; return cl;
} }
@@ -230,8 +230,10 @@ void GLObjectBase::rotateY(GLfloat a) {
void GLObjectBase::rotateZ(GLfloat a) { void GLObjectBase::rotateZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
angles_.setZ(angles_.z() + a); angles_.setZ(angles_.z() + a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); while (angles_.z() < -360.f)
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f); angles_.setZ(angles_.z() + 360.f);
while (angles_.z() > 360.f)
angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
@@ -253,28 +255,30 @@ void GLObjectBase::setRotationY(GLfloat a) {
void GLObjectBase::setRotationZ(GLfloat a) { void GLObjectBase::setRotationZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
angles_.setZ(a); angles_.setZ(a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); while (angles_.z() < -360.f)
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f); angles_.setZ(angles_.z() + 360.f);
while (angles_.z() > 360.f)
angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
void GLObjectBase::setRotation(const QVector3D & a) { void GLObjectBase::setRotation(const QVector3D & a) {
raw_matrix = false; raw_matrix = false;
angles_= a; angles_ = a;
buildTransform(); buildTransform();
} }
void GLObjectBase::resetRotation() { void GLObjectBase::resetRotation() {
raw_matrix = false; raw_matrix = false;
angles_ = QVector3D(0., 0., 0.); angles_ = QVector3D(0., 0., 0.);
buildTransform(); buildTransform();
} }
void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * where) { void GLObjectBase::addChildren(QList<GLObjectBase *> & list, GLObjectBase * where) {
foreach (GLObjectBase * i, where->children_) { foreach(GLObjectBase * i, where->children_) {
list << i; list << i;
addChildren(list, i); addChildren(list, i);
} }
@@ -284,21 +288,22 @@ void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * whe
void GLObjectBase::loadTextures(bool with_children) { void GLObjectBase::loadTextures(bool with_children) {
material_.loadTextures(view_->textureManager()); material_.loadTextures(view_->textureManager());
if (with_children) if (with_children)
foreach (GLObjectBase * i, children_) i->loadTextures(); foreach(GLObjectBase * i, children_)
i->loadTextures();
is_tex_loaded = true; is_tex_loaded = true;
checkPass(); checkPass();
} }
void GLObjectBase::calculateBoundingBox() { void GLObjectBase::calculateBoundingBox() {
bound = vbo.boundingBox(); bound = vbo.boundingBox();
QVector<QVector3D> c = bound.corners(), tc; QVector<QVector3D> c = bound.corners(), tc;
//QMatrix4x4 mat = itransform_.inverted(); // QMatrix4x4 mat = itransform_.inverted();
//qDebug() << itransform_ << mat_ << mat; // qDebug() << itransform_ << mat_ << mat;
foreach (QVector3D p, c) foreach(QVector3D p, c)
tc << (itransform_ * QVector4D(p, 1)).toVector3D(); tc << (itransform_ * QVector4D(p, 1)).toVector3D();
bound = Box3D(tc); bound = Box3D(tc);
foreach (GLObjectBase * i, children_) { foreach(GLObjectBase * i, children_) {
i->calculateBoundingBox(); i->calculateBoundingBox();
bound |= i->boundingBox(); bound |= i->boundingBox();
} }
@@ -328,25 +333,25 @@ void GLObjectBase::removeProperty(const QString & pn) {
void GLObjectBase::setTransform(const QMatrix4x4 & t) { void GLObjectBase::setTransform(const QMatrix4x4 & t) {
raw_matrix = true; raw_matrix = true;
mat_ = t; mat_ = t;
pos_ = mat_.column(3).toVector3D(); pos_ = mat_.column(3).toVector3D();
mat_.setColumn(3, QVector4D(0., 0., 0., 1.)); mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
buildTransform(); buildTransform();
} }
void GLObjectBase::select() { void GLObjectBase::select() {
//qDebug() << "select" << name() << view_; // qDebug() << "select" << name() << view_;
selected_ = true; selected_ = true;
if (view_) if (view_) ((QGLView *)view_)->selectObject(this);
((QGLView*)view_)->selectObject(this);
} }
void GLObjectBase::setMaterial(const Material & m, bool with_children) { void GLObjectBase::setMaterial(const Material & m, bool with_children) {
material_ = m; material_ = m;
if (with_children) if (with_children)
foreach (GLObjectBase * i, children_) i->setMaterial(m, true); foreach(GLObjectBase * i, children_)
i->setMaterial(m, true);
checkPass(); checkPass();
is_tex_loaded = false; is_tex_loaded = false;
} }
@@ -355,16 +360,15 @@ void GLObjectBase::setMaterial(const Material & m, bool with_children) {
void GLObjectBase::buildTransform() { void GLObjectBase::buildTransform() {
itransform_.setToIdentity(); itransform_.setToIdentity();
GLObjectBase * p = parent_; GLObjectBase * p = parent_;
if (p) if (p) itransform_ = p->itransform_;
itransform_ = p->itransform_;
if (raw_matrix) { if (raw_matrix) {
itransform_.translate(pos_); itransform_.translate(pos_);
itransform_ *= mat_; itransform_ *= mat_;
//qDebug() << "raw_matrix" << itransform_; // qDebug() << "raw_matrix" << itransform_;
} else } else
localTransform(itransform_); localTransform(itransform_);
//qDebug() << name_ << itransform_; // qDebug() << name_ << itransform_;
foreach (GLObjectBase * i, children_) foreach(GLObjectBase * i, children_)
i->buildTransform(); i->buildTransform();
} }
@@ -372,7 +376,8 @@ void GLObjectBase::buildTransform() {
void GLObjectBase::initInternal() { void GLObjectBase::initInternal() {
init(); init();
loadTextures(); loadTextures();
foreach (GLObjectBase * i, children_) i->initInternal(); foreach(GLObjectBase * i, children_)
i->initInternal();
} }
@@ -386,8 +391,10 @@ void GLObjectBase::localTransform(QMatrix4x4 & m) {
void GLObjectBase::checkPass() { void GLObjectBase::checkPass() {
if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f) pass_ = Transparent; if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f)
else pass_ = Solid; pass_ = Transparent;
else
pass_ = Solid;
} }
@@ -406,30 +413,28 @@ QMatrix4x4 GLObjectBase::worldMatrix(QMatrix4x4 parent) const {
} }
void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_loc) { void GLObjectBase::render(int * id, QMap<int, GLObjectBase *> * ids, int sh_id_loc) {
if (!visible_) return; if (!visible_) return;
//glPushMatrix(); // glPushMatrix();
///qglMultMatrix TODO /// qglMultMatrix TODO
material_.apply(nullptr); material_.apply(nullptr);
if (id != nullptr) { if (id != nullptr) {
++(*id); ++(*id);
ids->insert(*id, this); ids->insert(*id, this);
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f); // glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f; // qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
} }
draw(nullptr); draw(nullptr);
foreach (GLObjectBase * i, children_) foreach(GLObjectBase * i, children_)
i->render(id, ids, sh_id_loc); i->render(id, ids, sh_id_loc);
//glPopMatrix(); // glPopMatrix();
} }
Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) { Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
intensity = 1.; intensity = 1.;
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.; decay_const = decay_end = 1.;
@@ -438,10 +443,10 @@ Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) {
Light::Light(const QVector3D & p, const QColor & c, float i): GLObjectBase(), shadow_map(0, true, GL_R16F) { Light::Light(const QVector3D & p, const QColor & c, float i): GLObjectBase(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
pos_ = p; pos_ = p;
intensity = i; intensity = i;
/*color_ = c;*/ /*color_ = c;*/
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
@@ -451,25 +456,25 @@ Light::Light(const QVector3D & p, const QColor & c, float i): GLObjectBase(), sh
GLObjectBase * Light::clone(bool withChildren) { GLObjectBase * Light::clone(bool withChildren) {
Light * o = new Light(*this); Light * o = new Light(*this);
//GLObjectBase::clone(withChildren); // GLObjectBase::clone(withChildren);
o->is_init = false; o->is_init = false;
o->name_ = name_ + "_copy"; o->name_ = name_ + "_copy";
o->view_ = nullptr; o->view_ = nullptr;
o->children_.clear(); o->children_.clear();
if (withChildren) { if (withChildren) {
for (int i = 0; i < children_.size(); ++i) for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren)); o->addChild(children_[i]->clone(withChildren));
} }
o->light_type = light_type; o->light_type = light_type;
o->direction = direction; o->direction = direction;
o->angle_start = angle_start; o->angle_start = angle_start;
o->angle_end = angle_end; o->angle_end = angle_end;
o->intensity = intensity; o->intensity = intensity;
o->decay_const = decay_const; o->decay_const = decay_const;
o->decay_linear = decay_linear; o->decay_linear = decay_linear;
o->decay_quadratic = decay_quadratic; o->decay_quadratic = decay_quadratic;
o->meta = meta; o->meta = meta;
return o; return o;
} }
@@ -486,8 +491,7 @@ void Light::draw(QOpenGLShaderProgram * prog, bool simplest) {
if (light_type != Omni) { if (light_type != Omni) {
glBegin(GL_LINES); glBegin(GL_LINES);
QVector4D dir = QVector4D(direction); QVector4D dir = QVector4D(direction);
if (raw_matrix) if (raw_matrix) dir = transform().inverted() * dir;
dir = transform().inverted() * dir;
glVertex3f(0., 0., 0.); glVertex3f(0., 0., 0.);
glVertex3f(dir.x() * s, dir.y() * s, dir.z() * s); glVertex3f(dir.x() * s, dir.y() * s, dir.z() * s);
glEnd(); glEnd();
@@ -496,102 +500,174 @@ void Light::draw(QOpenGLShaderProgram * prog, bool simplest) {
} }
QDataStream & operator <<(QDataStream & s, const GLObjectBase * p) { QDataStream & operator<<(QDataStream & s, const GLObjectBase * p) {
ChunkStream cs; ChunkStream cs;
//qDebug() << "place" << p->name() << "..."; // qDebug() << "place" << p->name() << "...";
cs << cs.chunk(1, int(p->type_)) << cs.chunk(2, p->accept_light) << cs.chunk(3, p->accept_fog) << cs.chunk(4, p->visible_) cs << cs.chunk(1, int(p->type_)) << cs.chunk(2, p->accept_light) << cs.chunk(3, p->accept_fog) << cs.chunk(4, p->visible_)
<< cs.chunk(5, p->cast_shadow) << cs.chunk(6, p->rec_shadow) << cs.chunk(7, p->raw_matrix) << cs.chunk(8, p->line_width) << cs.chunk(5, p->cast_shadow) << cs.chunk(6, p->rec_shadow) << cs.chunk(7, p->raw_matrix) << cs.chunk(8, p->line_width)
<< cs.chunk(9, int(p->render_mode)) << cs.chunk(10, p->material_) << cs.chunk(11, p->pos_) << cs.chunk(12, p->angles_) << cs.chunk(9, int(p->render_mode)) << cs.chunk(10, p->material_) << cs.chunk(11, p->pos_) << cs.chunk(12, p->angles_)
<< cs.chunk(13, p->scale_) << cs.chunk(14, p->mat_) << cs.chunk(15, p->vbo) << cs.chunk(16, p->children_.size()) << cs.chunk(13, p->scale_) << cs.chunk(14, p->mat_) << cs.chunk(15, p->vbo) << cs.chunk(16, p->children_.size())
<< cs.chunk(17, p->name_) << cs.chunk(18, p->meta); << cs.chunk(17, p->name_) << cs.chunk(18, p->meta);
//qDebug() << "place self done"; // qDebug() << "place self done";
if (p->type_ == GLObjectBase::glLight) { if (p->type_ == GLObjectBase::glLight) {
//qDebug() << "place light ..."; // qDebug() << "place light ...";
const Light * l = (const Light*)p; const Light * l = (const Light *)p;
cs << cs.chunk(100, l->direction) << cs.chunk(101, l->angle_start) << cs.chunk(102, l->angle_end) << cs.chunk(103, l->intensity) cs << cs.chunk(100, l->direction) << cs.chunk(101, l->angle_start) << cs.chunk(102, l->angle_end) << cs.chunk(103, l->intensity)
<< cs.chunk(104, l->decay_const) << cs.chunk(105, l->decay_linear) << cs.chunk(106, l->decay_quadratic) << cs.chunk(104, l->decay_const) << cs.chunk(105, l->decay_linear) << cs.chunk(106, l->decay_quadratic)
<< cs.chunk(107, l->decay_start) << cs.chunk(108, l->decay_end) << cs.chunk(109, int(l->light_type)); << cs.chunk(107, l->decay_start) << cs.chunk(108, l->decay_end) << cs.chunk(109, int(l->light_type));
} }
if (p->type_ == GLObjectBase::glCamera) { if (p->type_ == GLObjectBase::glCamera) {
//qDebug() << "place camera ..."; // qDebug() << "place camera ...";
const Camera * c = (const Camera*)p; const Camera * c = (const Camera *)p;
cs << cs.chunk(200, c->aim_) << cs.chunk(201, c->fov_) << cs.chunk(202, c->depth_start) << cs.chunk(203, c->depth_end) cs << cs.chunk(200, c->aim_) << cs.chunk(201, c->fov_) << cs.chunk(202, c->depth_start) << cs.chunk(203, c->depth_end)
<< cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy) << cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy) << cs.chunk(206, c->mirror_x)
<< cs.chunk(206, c->mirror_x) << cs.chunk(207, c->mirror_y); << cs.chunk(207, c->mirror_y);
} }
//qDebug() << "place" << p->name() << cs.data().size() << s.device()->size(); // qDebug() << "place" << p->name() << cs.data().size() << s.device()->size();
s << cs.data(); s << cs.data();
foreach (const GLObjectBase * c, p->children_) foreach(const GLObjectBase * c, p->children_)
s << c; s << c;
return s; return s;
} }
QDataStream & operator >>(QDataStream & s, GLObjectBase *& p) { QDataStream & operator>>(QDataStream & s, GLObjectBase *& p) {
ChunkStream cs(s); ChunkStream cs(s);
p = nullptr; p = nullptr;
int ccnt = 0; int ccnt = 0;
Light * l = nullptr; Light * l = nullptr;
Camera * c = nullptr; Camera * c = nullptr;
QVector3D cam_angles; QVector3D cam_angles;
//qDebug() << "read obj ..."; // qDebug() << "read obj ...";
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1: case 1: {
{
GLObjectBase::Type type = (GLObjectBase::Type)cs.getData<int>(); GLObjectBase::Type type = (GLObjectBase::Type)cs.getData<int>();
switch (type) { switch (type) {
case GLObjectBase::glMesh: p = new GLObjectBase(); break; case GLObjectBase::glMesh: p = new GLObjectBase(); break;
case GLObjectBase::glLight: p = new Light(); l = (Light*)p; break; case GLObjectBase::glLight:
case GLObjectBase::glCamera: p = new Camera(); c = (Camera*)p; break; p = new Light();
default : break; l = (Light *)p;
break;
case GLObjectBase::glCamera:
p = new Camera();
c = (Camera *)p;
break;
default: break;
} }
if (p) p->type_ = type; if (p) p->type_ = type;
} } break;
case 2:
if (p) p->accept_light = cs.getData<bool>();
break;
case 3:
if (p) p->accept_fog = cs.getData<bool>();
break;
case 4:
if (p) p->visible_ = cs.getData<bool>();
break;
case 5:
if (p) p->cast_shadow = cs.getData<bool>();
break;
case 6:
if (p) p->rec_shadow = cs.getData<bool>();
break;
case 7:
if (p) p->raw_matrix = cs.getData<bool>();
break;
case 8:
if (p) p->line_width = cs.getData<float>();
break;
case 9:
if (p) p->render_mode = (GLObjectBase::RenderMode)cs.getData<int>();
break;
case 10:
if (p) p->material_ = cs.getData<Material>();
break;
case 11:
if (p) p->pos_ = cs.getData<QVector3D>();
break; break;
case 2: if (p) p->accept_light = cs.getData<bool>(); break;
case 3: if (p) p->accept_fog = cs.getData<bool>(); break;
case 4: if (p) p->visible_ = cs.getData<bool>(); break;
case 5: if (p) p->cast_shadow = cs.getData<bool>(); break;
case 6: if (p) p->rec_shadow = cs.getData<bool>(); break;
case 7: if (p) p->raw_matrix = cs.getData<bool>(); break;
case 8: if (p) p->line_width = cs.getData<float>(); break;
case 9: if (p) p->render_mode = (GLObjectBase::RenderMode)cs.getData<int>(); break;
case 10: if (p) p->material_ = cs.getData<Material>(); break;
case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break;
case 12: case 12:
if (p) p->angles_ = cs.getData<QVector3D>(); if (p) p->angles_ = cs.getData<QVector3D>();
if (c) { if (c) {
c->setAngles(cs.getData<QVector3D>()); c->setAngles(cs.getData<QVector3D>());
cam_angles = c->angles(); cam_angles = c->angles();
} }
break; break;
case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break; case 13:
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break; if (p) p->scale_ = cs.getData<QVector3D>();
case 15: if (p) p->vbo = cs.getData<GLVBO>(); break; break;
case 16: if (p) ccnt = cs.getData<int>(); break; case 14:
case 17: if (p) p->name_ = cs.getData<QString>(); break; if (p) p->mat_ = cs.getData<QMatrix4x4>();
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break; break;
case 100: if (l) l->direction = cs.getData<QVector3D>(); break; case 15:
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break; if (p) p->vbo = cs.getData<GLVBO>();
case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break; break;
case 103: if (l) l->intensity = cs.getData<GLfloat>(); break; case 16:
case 104: if (l) l->decay_const = cs.getData<GLfloat>(); break; if (p) ccnt = cs.getData<int>();
case 105: if (l) l->decay_linear = cs.getData<GLfloat>(); break; break;
case 106: if (l) l->decay_quadratic = cs.getData<GLfloat>(); break; case 17:
case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break; if (p) p->name_ = cs.getData<QString>();
case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break; break;
case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break; case 18:
case 200: if (c) c->setAim(cs.getData<QVector3D>()); break; if (p) p->meta = cs.getData<QVariantMap>();
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break; break;
case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break; case 100:
case 203: if (c) c->setDepthEnd(cs.getData<GLfloat>()); break; if (l) l->direction = cs.getData<QVector3D>();
case 204: if (c) c->setAngleLowerLimitXY(cs.getData<GLfloat>()); break; break;
case 205: if (c) c->setAngleUpperLimitXY(cs.getData<GLfloat>()); break; case 101:
case 206: if (c) c->mirror_x = cs.getData<bool>(); break; if (l) l->angle_start = cs.getData<GLfloat>();
case 207: if (c) c->mirror_y = cs.getData<bool>(); break; break;
case 102:
if (l) l->angle_end = cs.getData<GLfloat>();
break;
case 103:
if (l) l->intensity = cs.getData<GLfloat>();
break;
case 104:
if (l) l->decay_const = cs.getData<GLfloat>();
break;
case 105:
if (l) l->decay_linear = cs.getData<GLfloat>();
break;
case 106:
if (l) l->decay_quadratic = cs.getData<GLfloat>();
break;
case 107:
if (l) l->decay_start = cs.getData<GLfloat>();
break;
case 108:
if (l) l->decay_end = cs.getData<GLfloat>();
break;
case 109:
if (l) l->light_type = (Light::Type)cs.getData<int>();
break;
case 200:
if (c) c->setAim(cs.getData<QVector3D>());
break;
case 201:
if (c) c->setFOV(cs.getData<GLfloat>());
break;
case 202:
if (c) c->setDepthStart(cs.getData<GLfloat>());
break;
case 203:
if (c) c->setDepthEnd(cs.getData<GLfloat>());
break;
case 204:
if (c) c->setAngleLowerLimitXY(cs.getData<GLfloat>());
break;
case 205:
if (c) c->setAngleUpperLimitXY(cs.getData<GLfloat>());
break;
case 206:
if (c) c->mirror_x = cs.getData<bool>();
break;
case 207:
if (c) c->mirror_y = cs.getData<bool>();
break;
} }
} }
if (c) c->setAngles(cam_angles); if (c) c->setAngles(cam_angles);
//qDebug() << p->name() << ccnt; // qDebug() << p->name() << ccnt;
for (int i = 0; i < ccnt; ++i) { for (int i = 0; i < ccnt; ++i) {
GLObjectBase * c = nullptr; GLObjectBase * c = nullptr;
s >> c; s >> c;
+238 -113
View File
@@ -19,101 +19,158 @@
#ifndef GLOBJECT_H #ifndef GLOBJECT_H
#define GLOBJECT_H #define GLOBJECT_H
#include "glvbo.h"
#include "glframebuffer.h" #include "glframebuffer.h"
#include "glmaterial.h" #include "glmaterial.h"
#include "glvbo.h"
class Camera; class Camera;
class QGLView; class QGLView;
class GLObjectBase class GLObjectBase {
{
friend class QGLView; friend class QGLView;
friend class GLRendererBase; friend class GLRendererBase;
friend QDataStream & operator <<(QDataStream & s, const GLObjectBase * p); friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
friend QDataStream & operator >>(QDataStream & s, GLObjectBase *& p); friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
friend GLObjectBase * loadFromQGLFile(const QString & filepath); friend GLObjectBase * loadFromQGLFile(const QString & filepath);
public: public:
enum Type {glMesh, glLight, glCamera, glParticlesSystem}; enum Type {
enum Pass {Solid, Transparent, Reflection, User}; glMesh,
enum GeomPrimitives {Triangles = GL_TRIANGLES, Quads = GL_QUADS}; glLight,
enum RenderMode {View = 0, Point = GL_POINT, Line = GL_LINE, Fill = GL_FILL}; glCamera,
glParticlesSystem
};
enum Pass {
Solid,
Transparent,
Reflection,
User
};
enum GeomPrimitives {
Triangles = GL_TRIANGLES,
Quads = GL_QUADS
};
enum RenderMode {
View = 0,
Point = GL_POINT,
Line = GL_LINE,
Fill = GL_FILL
};
explicit GLObjectBase(); explicit GLObjectBase();
virtual ~GLObjectBase(); virtual ~GLObjectBase();
virtual GLObjectBase * clone(bool withChildren = true); virtual GLObjectBase * clone(bool withChildren = true);
QString name() const {return name_;} QString name() const { return name_; }
void setName(const QString & name) {name_ = name;} void setName(const QString & name) { name_ = name; }
//virtual GLuint hList() {return list;} // virtual GLuint hList() {return list;}
virtual void init(); virtual void init();
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
virtual void update() {} virtual void update() {}
bool isInit() const {return is_init;} bool isInit() const { return is_init; }
bool isTexturesLoaded() const {return is_tex_loaded;} bool isTexturesLoaded() const { return is_tex_loaded; }
Type type() const {return type_;} Type type() const { return type_; }
RenderMode renderMode() const {return render_mode;} RenderMode renderMode() const { return render_mode; }
void setRenderMode(RenderMode mode) {render_mode = mode;} void setRenderMode(RenderMode mode) { render_mode = mode; }
float lineWidth() const {return line_width;} float lineWidth() const { return line_width; }
void setLineWidth(const float & width) {line_width = width;} void setLineWidth(const float & width) { line_width = width; }
GLObjectBase * parent() {return parent_;} GLObjectBase * parent() { return parent_; }
void setParent(GLObjectBase * o) {parent_ = o;} void setParent(GLObjectBase * o) { parent_ = o; }
bool hasParent() const {return parent_ != nullptr;} bool hasParent() const { return parent_ != nullptr; }
bool hasChildren() const {return children_.size() != 0;} bool hasChildren() const { return children_.size() != 0; }
void setView(QGLView * v); void setView(QGLView * v);
void addChild(GLObjectBase * o); void addChild(GLObjectBase * o);
void removeChild(GLObjectBase * o); void removeChild(GLObjectBase * o);
void removeChild(int index); void removeChild(int index);
void clearChildren(bool deleteAll = false); void clearChildren(bool deleteAll = false);
int childCount() const {return children_.size();} int childCount() const { return children_.size(); }
GLObjectBase * child(int index); GLObjectBase * child(int index);
GLObjectBase * child(const QString & name); GLObjectBase * child(const QString & name);
const GLObjectBase * child(int index) const; const GLObjectBase * child(int index) const;
const GLObjectBase * child(const QString & name) const; const GLObjectBase * child(const QString & name) const;
QList<GLObjectBase * > children(bool all_ = false); QList<GLObjectBase *> children(bool all_ = false);
bool isVisible() const {return visible_;} bool isVisible() const { return visible_; }
bool isHidden() const {return !visible_;} bool isHidden() const { return !visible_; }
void setVisible(bool v) {visible_ = v;} void setVisible(bool v) { visible_ = v; }
void setHidden(bool v) {visible_ = !v;} void setHidden(bool v) { visible_ = !v; }
void show() {visible_ = true;} void show() { visible_ = true; }
void hide() {visible_ = false;} void hide() { visible_ = false; }
bool isReceiveShadows() const {return rec_shadow;} bool isReceiveShadows() const { return rec_shadow; }
bool isCastShadows() const {return cast_shadow;} bool isCastShadows() const { return cast_shadow; }
void setReceiveShadows(bool on) {rec_shadow = on;} void setReceiveShadows(bool on) { rec_shadow = on; }
void setCastShadows(bool on) {cast_shadow = on;} void setCastShadows(bool on) { cast_shadow = on; }
void move(const QVector3D & dv) {pos_ += dv; buildTransform();} void move(const QVector3D & dv) {
void moveTo(const QVector3D & dv) {pos_ = dv; buildTransform();} pos_ += dv;
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); buildTransform();} buildTransform();
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {moveTo(QVector3D(dx, dy, dz)); buildTransform();} }
void moveX(GLfloat o) {pos_.setX(pos_.x() + o); buildTransform();} void moveTo(const QVector3D & dv) {
void moveY(GLfloat o) {pos_.setY(pos_.y() + o); buildTransform();} pos_ = dv;
void moveZ(GLfloat o) {pos_.setZ(pos_.z() + o); buildTransform();} buildTransform();
void setPosX(GLfloat o) {pos_.setX(o); buildTransform();} }
void setPosY(GLfloat o) {pos_.setY(o); buildTransform();} void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
void setPosZ(GLfloat o) {pos_.setZ(o); buildTransform();} move(QVector3D(dx, dy, dz));
void setPos(GLfloat x, GLfloat y, GLfloat z) {pos_ = QVector3D(x, y, z); buildTransform();} buildTransform();
void setPos(const QVector3D & p) {pos_ = p; buildTransform();} }
void resetPos() {pos_ = QVector3D(0., 0., 0.); buildTransform();} void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
moveTo(QVector3D(dx, dy, dz));
buildTransform();
}
void moveX(GLfloat o) {
pos_.setX(pos_.x() + o);
buildTransform();
}
void moveY(GLfloat o) {
pos_.setY(pos_.y() + o);
buildTransform();
}
void moveZ(GLfloat o) {
pos_.setZ(pos_.z() + o);
buildTransform();
}
void setPosX(GLfloat o) {
pos_.setX(o);
buildTransform();
}
void setPosY(GLfloat o) {
pos_.setY(o);
buildTransform();
}
void setPosZ(GLfloat o) {
pos_.setZ(o);
buildTransform();
}
void setPos(GLfloat x, GLfloat y, GLfloat z) {
pos_ = QVector3D(x, y, z);
buildTransform();
}
void setPos(const QVector3D & p) {
pos_ = p;
buildTransform();
}
void resetPos() {
pos_ = QVector3D(0., 0., 0.);
buildTransform();
}
QVector3D pos() const {return pos_;} QVector3D pos() const { return pos_; }
float posX() const {return pos_.x();} float posX() const { return pos_.x(); }
float posY() const {return pos_.y();} float posY() const { return pos_.y(); }
float posZ() const {return pos_.z();} float posZ() const { return pos_.z(); }
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();} QVector3D worldPos() const { return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D(); }
QMatrix4x4 worldTransform() const {return itransform_;} QMatrix4x4 worldTransform() const { return itransform_; }
QVector3D rotation() const {return angles_;} QVector3D rotation() const { return angles_; }
float rotationX() const {return angles_.x();} float rotationX() const { return angles_.x(); }
float rotationY() const {return angles_.y();} float rotationY() const { return angles_.y(); }
float rotationZ() const {return angles_.z();} float rotationZ() const { return angles_.z(); }
void rotateX(GLfloat a); void rotateX(GLfloat a);
void rotateY(GLfloat a); void rotateY(GLfloat a);
void rotateZ(GLfloat a); void rotateZ(GLfloat a);
@@ -123,58 +180,113 @@ public:
void setRotation(const QVector3D & a); void setRotation(const QVector3D & a);
void resetRotation(); void resetRotation();
QVector3D scale() {return scale_;} QVector3D scale() { return scale_; }
float scaleX() {return scale_.x();} float scaleX() { return scale_.x(); }
float scaleY() {return scale_.y();} float scaleY() { return scale_.y(); }
float scaleZ() {return scale_.z();} float scaleZ() { return scale_.z(); }
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();} void scale(const QVector3D & sv) {
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();} raw_matrix = false;
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();} scale_ *= sv;
void scale(GLfloat sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();} buildTransform();
void scaleX(GLfloat a) {raw_matrix = false; scale_.setX(scale_.x() + a); buildTransform();} }
void scaleY(GLfloat a) {raw_matrix = false; scale_.setY(scale_.y() + a); buildTransform();} void scale(GLfloat sx, GLfloat sy, GLfloat sz) {
void scaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(scale_.z() + a); buildTransform();} raw_matrix = false;
void setScale(const QVector3D & a) {raw_matrix = false; scale_ = a; buildTransform();} scale(QVector3D(sx, sy, sz));
void setScale(GLfloat a) {raw_matrix = false; scale_ = QVector3D(a, a, a); buildTransform();} buildTransform();
void setScaleX(GLfloat a) {raw_matrix = false; scale_.setX(a); buildTransform();} }
void setScaleY(GLfloat a) {raw_matrix = false; scale_.setY(a); buildTransform();} void scale(GLfloat sx, GLfloat sy) {
void setScaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(a); buildTransform();} raw_matrix = false;
void resetScale() {raw_matrix = false; scale_ = QVector3D(1., 1., 1.); buildTransform();} scale(QVector3D(sx, sy, sy));
buildTransform();
}
void scale(GLfloat sx) {
raw_matrix = false;
scale(QVector3D(sx, sx, sx));
buildTransform();
}
void scaleX(GLfloat a) {
raw_matrix = false;
scale_.setX(scale_.x() + a);
buildTransform();
}
void scaleY(GLfloat a) {
raw_matrix = false;
scale_.setY(scale_.y() + a);
buildTransform();
}
void scaleZ(GLfloat a) {
raw_matrix = false;
scale_.setZ(scale_.z() + a);
buildTransform();
}
void setScale(const QVector3D & a) {
raw_matrix = false;
scale_ = a;
buildTransform();
}
void setScale(GLfloat a) {
raw_matrix = false;
scale_ = QVector3D(a, a, a);
buildTransform();
}
void setScaleX(GLfloat a) {
raw_matrix = false;
scale_.setX(a);
buildTransform();
}
void setScaleY(GLfloat a) {
raw_matrix = false;
scale_.setY(a);
buildTransform();
}
void setScaleZ(GLfloat a) {
raw_matrix = false;
scale_.setZ(a);
buildTransform();
}
void resetScale() {
raw_matrix = false;
scale_ = QVector3D(1., 1., 1.);
buildTransform();
}
QMatrix4x4 transform() {return mat_;} QMatrix4x4 transform() { return mat_; }
void setTransform(const QMatrix4x4 & t); void setTransform(const QMatrix4x4 & t);
bool isRawMatrix() {return raw_matrix;} bool isRawMatrix() { return raw_matrix; }
bool isAcceptLight() const {return accept_light;} bool isAcceptLight() const { return accept_light; }
void setAcceptLight(bool yes) {accept_light = yes;} void setAcceptLight(bool yes) { accept_light = yes; }
bool isAcceptFog() const {return accept_fog;} bool isAcceptFog() const { return accept_fog; }
void setAcceptFog(bool yes) {accept_fog = yes;} void setAcceptFog(bool yes) { accept_fog = yes; }
bool isSelected() const {return selected_;} bool isSelected() const { return selected_; }
void setSelected(bool yes) {selected_ = yes;} void setSelected(bool yes) { selected_ = yes; }
void select(); void select();
void deselect() {selected_ = false;} void deselect() { selected_ = false; }
bool isSelectable() const {return select_;} bool isSelectable() const { return select_; }
void setSelectable(bool yes) {select_ = yes;} void setSelectable(bool yes) { select_ = yes; }
/* /*
bool isWriteDepth() const {return write_depth_;} bool isWriteDepth() const {return write_depth_;}
void setWriteDepth(bool yes) {write_depth_ = yes;}*/ void setWriteDepth(bool yes) {write_depth_ = yes;}*/
QColor color() const {return material_.color_diffuse;} QColor color() const { return material_.color_diffuse; }
void setColor(const QColor & c) {material_.color_diffuse = c; checkPass();} void setColor(const QColor & c) {
material_.color_diffuse = c;
checkPass();
}
GLenum srcAlpha() const {return blend_src;} GLenum srcAlpha() const { return blend_src; }
GLenum destAlpha() const {return blend_dest;} GLenum destAlpha() const { return blend_dest; }
void setSrcAlpha(GLenum mode) {blend_src = mode;} void setSrcAlpha(GLenum mode) { blend_src = mode; }
void setDestAlpha(GLenum mode) {blend_dest = mode;} void setDestAlpha(GLenum mode) { blend_dest = mode; }
void setMaterial(const Material & m, bool with_children = false); void setMaterial(const Material & m, bool with_children = false);
Material & material() {return material_;} Material & material() { return material_; }
const Box3D & boundingBox(bool withChildren = true) const {return bound;} const Box3D & boundingBox(bool withChildren = true) const { return bound; }
GLVBO & VBO() {return vbo;} GLVBO & VBO() { return vbo; }
void calculateBoundingBox(); void calculateBoundingBox();
@@ -188,21 +300,22 @@ public:
QVector<Vector3i> faces, uvws, norms; QVector<Vector3i> faces, uvws, norms;
QVector<Vector3d> normals; QVector<Vector3d> normals;
//QVector<GLfloat> d_vertices, d_normals, d_uvs; // QVector<GLfloat> d_vertices, d_normals, d_uvs;
protected: protected:
void addChildren(QList<GLObjectBase * > & list, GLObjectBase * where); void addChildren(QList<GLObjectBase *> & list, GLObjectBase * where);
void loadTextures(bool with_children = false); void loadTextures(bool with_children = false);
//void deleteTextures() {foreach (GLuint i, textures) currentQGLView->deleteTexture(i); textures.clear();} // void deleteTextures() {foreach (GLuint i, textures) currentQGLView->deleteTexture(i); textures.clear();}
void buildTransform(); void buildTransform();
void initInternal(); void initInternal();
void render(int * id = nullptr, QMap<int, GLObjectBase * > * ids = nullptr, int sh_id_loc = 0); void render(int * id = nullptr, QMap<int, GLObjectBase *> * ids = nullptr, int sh_id_loc = 0);
void checkPass(); void checkPass();
virtual void localTransform(QMatrix4x4 & m); virtual void localTransform(QMatrix4x4 & m);
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const; QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
int pass_; // Pass int pass_; // Pass
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_,
raw_matrix;
bool is_root; bool is_root;
float line_width; float line_width;
Type type_; Type type_;
@@ -211,31 +324,40 @@ protected:
Material material_; Material material_;
Box3D bound; Box3D bound;
QVector3D pos_, angles_, scale_; QVector3D pos_, angles_, scale_;
QList<GLObjectBase * > children_; QList<GLObjectBase *> children_;
QList<GLuint> textures; QList<GLuint> textures;
QMatrix4x4 itransform_, mat_; QMatrix4x4 itransform_, mat_;
//QColor color_; // QColor color_;
QString name_; QString name_;
GLenum blend_src, blend_dest; GLenum blend_src, blend_dest;
GLObjectBase * parent_; GLObjectBase * parent_;
QGLViewBase * view_; QGLViewBase * view_;
GLVBO vbo; GLVBO vbo;
QVariantMap meta; QVariantMap meta;
}; };
inline bool operator <(const GLObjectBase & f, const GLObjectBase & s) {return f.pos_h.z() < s.pos_h.z();} inline bool operator<(const GLObjectBase & f, const GLObjectBase & s) {
return f.pos_h.z() < s.pos_h.z();
}
class Light: public GLObjectBase { class Light: public GLObjectBase {
friend class QGLView; friend class QGLView;
friend class GLRendererBase; friend class GLRendererBase;
public: public:
enum Type {Omni, Directional, Cone}; enum Type {
Omni,
Directional,
Cone
};
Light(); Light();
Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.); Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.);
virtual GLObjectBase * clone(bool withChildren = true); virtual GLObjectBase * clone(bool withChildren = true);
virtual void init() {shadow_map.resize(512, 512); is_init = true;} virtual void init() {
shadow_map.resize(512, 512);
is_init = true;
}
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
QVector3D direction, dir0, dir1; QVector3D direction, dir0, dir1;
@@ -252,17 +374,20 @@ public:
QMatrix4x4 shadow_matrix; QMatrix4x4 shadow_matrix;
protected: protected:
}; };
template <class T> template<class T>
inline T globject_cast(GLObjectBase * object) {return reinterpret_cast<T>(object);} inline T globject_cast(GLObjectBase * object) {
return reinterpret_cast<T>(object);
}
template <class T> template<class T>
inline T globject_cast(const GLObjectBase * object) {return reinterpret_cast<T>(object);} inline T globject_cast(const GLObjectBase * object) {
return reinterpret_cast<T>(object);
}
QDataStream & operator <<(QDataStream & s, const GLObjectBase * p); QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
QDataStream & operator >>(QDataStream & s, GLObjectBase *& p); QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
#endif // GLOBJECT_H #endif // GLOBJECT_H
+20 -23
View File
@@ -17,8 +17,9 @@
*/ */
#include "globject_editor.h" #include "globject_editor.h"
#include "ui_globject_editor.h"
#include "glcamera.h" #include "glcamera.h"
#include "ui_globject_editor.h"
GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) { GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
@@ -37,11 +38,8 @@ GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
void GLObjectEditor::changeEvent(QEvent * e) { void GLObjectEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
@@ -76,8 +74,8 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
ui->groupLight->setEnabled(object->type() == GLObjectBase::glLight); ui->groupLight->setEnabled(object->type() == GLObjectBase::glLight);
ui->groupLight->setVisible(object->type() == GLObjectBase::glLight); ui->groupLight->setVisible(object->type() == GLObjectBase::glLight);
if (object->type() == GLObjectBase::glLight) { if (object->type() == GLObjectBase::glLight) {
Light * l = globject_cast<Light * >(object); Light * l = globject_cast<Light *>(object);
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone; // bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
ui->buttonLightColor->setColor(l->color()); ui->buttonLightColor->setColor(l->color());
ui->comboLightType->setCurrentIndex(l->light_type); ui->comboLightType->setCurrentIndex(l->light_type);
ui->spinLightIntensity->setValue(l->intensity); ui->spinLightIntensity->setValue(l->intensity);
@@ -93,7 +91,7 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
ui->groupCamera->setEnabled(object->type() == GLObjectBase::glCamera); ui->groupCamera->setEnabled(object->type() == GLObjectBase::glCamera);
ui->groupCamera->setVisible(object->type() == GLObjectBase::glCamera); ui->groupCamera->setVisible(object->type() == GLObjectBase::glCamera);
if (object->type() == GLObjectBase::glCamera) { if (object->type() == GLObjectBase::glCamera) {
Camera * c = globject_cast<Camera * >(object); Camera * c = globject_cast<Camera *>(object);
ui->checkCameraMirrorX->setChecked(c->isMirrorX()); ui->checkCameraMirrorX->setChecked(c->isMirrorX());
ui->checkCameraMirrorY->setChecked(c->isMirrorY()); ui->checkCameraMirrorY->setChecked(c->isMirrorY());
ui->spinCameraFOV->setValue(c->FOV()); ui->spinCameraFOV->setValue(c->FOV());
@@ -125,20 +123,21 @@ void GLObjectEditor::objectChanged() {
object->setReceiveShadows(ui->checkReceiveShadows->isChecked()); object->setReceiveShadows(ui->checkReceiveShadows->isChecked());
object->setRenderMode((GLObjectBase::RenderMode)rmodes[ui->comboRenderMode->currentIndex()]); object->setRenderMode((GLObjectBase::RenderMode)rmodes[ui->comboRenderMode->currentIndex()]);
if (object->type() == GLObjectBase::glLight) { if (object->type() == GLObjectBase::glLight) {
Light * l = globject_cast<Light * >(object); Light * l = globject_cast<Light *>(object);
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone; // bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
l->setColor(ui->buttonLightColor->color()); l->setColor(ui->buttonLightColor->color());
l->light_type = (Light::Type)ui->comboLightType->currentIndex(); l->light_type = (Light::Type)ui->comboLightType->currentIndex();
l->intensity = ui->spinLightIntensity->value(); l->intensity = ui->spinLightIntensity->value();
l->decay_const = ui->spinLightDecayConst->value(); l->decay_const = ui->spinLightDecayConst->value();
l->decay_linear = ui->spinLightDecayLinear->value(); l->decay_linear = ui->spinLightDecayLinear->value();
l->decay_quadratic = ui->spinLightDecayQuadratic->value(); l->decay_quadratic = ui->spinLightDecayQuadratic->value();
l->angle_start = ui->spinLightAngleStart->value(); l->angle_start = ui->spinLightAngleStart->value();
l->angle_end = ui->spinLightAngleEnd->value(); l->angle_end = ui->spinLightAngleEnd->value();
l->direction = QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized(); l->direction =
QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
} }
if (object->type() == GLObjectBase::glCamera) { if (object->type() == GLObjectBase::glCamera) {
Camera * c = globject_cast<Camera * >(object); Camera * c = globject_cast<Camera *>(object);
c->setMirrorX(ui->checkCameraMirrorX->isChecked()); c->setMirrorX(ui->checkCameraMirrorX->isChecked());
c->setMirrorY(ui->checkCameraMirrorY->isChecked()); c->setMirrorY(ui->checkCameraMirrorY->isChecked());
c->setFOV(ui->spinCameraFOV->value()); c->setFOV(ui->spinCameraFOV->value());
@@ -150,14 +149,12 @@ void GLObjectEditor::objectChanged() {
void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) { void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
if (ui->spinLightAngleEnd->value() < v) if (ui->spinLightAngleEnd->value() < v) ui->spinLightAngleEnd->setValue(v);
ui->spinLightAngleEnd->setValue(v);
} }
void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) { void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
if (ui->spinLightAngleStart->value() > v) if (ui->spinLightAngleStart->value() > v) ui->spinLightAngleStart->setValue(v);
ui->spinLightAngleStart->setValue(v);
} }
+4 -5
View File
@@ -22,17 +22,17 @@
#include "globject.h" #include "globject.h"
namespace Ui { namespace Ui {
class GLObjectEditor; class GLObjectEditor;
}; };
class GLObjectEditor: public QWidget class GLObjectEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit GLObjectEditor(QWidget * parent = 0); explicit GLObjectEditor(QWidget * parent = 0);
void setObject(GLObjectBase * o); void setObject(GLObjectBase * o);
GLObjectBase * getObject() {return object;} GLObjectBase * getObject() { return object; }
protected: protected:
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
@@ -50,7 +50,6 @@ private slots:
signals: signals:
void changed(); void changed();
}; };
#endif // GLOBJECT_EDITOR_H #endif // GLOBJECT_EDITOR_H
+63 -64
View File
@@ -20,17 +20,17 @@
GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() { GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() {
pass_ = GLObjectBase::Transparent; pass_ = GLObjectBase::Transparent;
freq = 40.f; freq = 40.f;
birthRate_ = 10.f; birthRate_ = 10.f;
lifeDuration_ = 2.f; lifeDuration_ = 2.f;
fade_time = 0.5f; fade_time = 0.5f;
size_ = 1.f; size_ = 1.f;
additionalSpeed = 0.f; additionalSpeed = 0.f;
initialSpeed_ = 1.f; initialSpeed_ = 1.f;
need_birth = -1.f; need_birth = -1.f;
tex_rect.setRect(0., 0., 1., 1.); tex_rect.setRect(0., 0., 1., 1.);
tex_scale = QSizeF(); tex_scale = QSizeF();
emitterPosition_ = pos; emitterPosition_ = pos;
emitterDirection_.setZ(1.); emitterDirection_.setZ(1.);
speedDirection_.setZ(1.); speedDirection_.setZ(1.);
@@ -38,64 +38,65 @@ GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() {
lifeDurationJitter_ = speedJitter_ = speedDirectionJitter_ = sizeJitter_ = angleJitter_ = 0.f; lifeDurationJitter_ = speedJitter_ = speedDirectionJitter_ = sizeJitter_ = angleJitter_ = 0.f;
active_ = birthEnabled_ = true; active_ = birthEnabled_ = true;
is_diffuse_anim = add_vert_face = false; is_diffuse_anim = add_vert_face = false;
emitterType_ = Cone; emitterType_ = Cone;
tick_life = 1.f / freq; tick_life = 1.f / freq;
tick_birth = birthRate_ / freq; tick_birth = birthRate_ / freq;
} }
void GLParticlesSystem::update() { void GLParticlesSystem::update() {
//qDebug() << "update" << need_birth << tick_birth; // qDebug() << "update" << need_birth << tick_birth;
if (!active_) return; if (!active_) return;
//QMutexLocker locker(&mutex); // QMutexLocker locker(&mutex);
Particle cp(lifeDuration_); Particle cp(lifeDuration_);
if (birthEnabled_) need_birth += tick_birth; if (birthEnabled_) need_birth += tick_birth;
qDebug() << "update" << particles.size(); qDebug() << "update" << particles.size();
if (need_birth >= 1.f) { if (need_birth >= 1.f) {
cp.pos = emitterPosition_; cp.pos = emitterPosition_;
//qDebug() << "speed" << cp.speed; // qDebug() << "speed" << cp.speed;
cp.speedDecay = 1.f + speedDecay_; cp.speedDecay = 1.f + speedDecay_;
for (int i = 0; i < floor(need_birth); ++i) { for (int i = 0; i < floor(need_birth); ++i) {
cp.lifeDuration = lifeDuration_ + urand(lifeDurationJitter_); cp.lifeDuration = lifeDuration_ + urand(lifeDurationJitter_);
switch (emitterType_) { switch (emitterType_) {
case Omni: case Omni: cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_)); break;
cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_)); case Cone:
break; case Box:
case Cone: case Box:
cp.speed = emitterDirection_ * initialSpeed_ * (1.f + urand(speedJitter_)); cp.speed = emitterDirection_ * initialSpeed_ * (1.f + urand(speedJitter_));
cp.speed += orthToVector(cp.speed, speedDirectionJitter_); cp.speed += orthToVector(cp.speed, speedDirectionJitter_);
break; break;
} }
if (emitterType_ == Box) if (emitterType_ == Box) cp.pos = emitterRect_.randomPoint();
cp.pos = emitterRect_.randomPoint(); // qDebug() << "before" << cp.speed.length();
//qDebug() << "before" << cp.speed.length();
lengthenVector(cp.speed, additionalSpeed); lengthenVector(cp.speed, additionalSpeed);
//qDebug() << "after" << cp.speed.length(); // qDebug() << "after" << cp.speed.length();
cp.size = size_ + urand(sizeJitter_); cp.size = size_ + urand(sizeJitter_);
cp.angle = initialAngle_ + urand(angleJitter_); cp.angle = initialAngle_ + urand(angleJitter_);
cp.enlargeSpeed = (enlargeSpeed_ + urand(enlargeSpeedJitter_)) * tick_life; cp.enlargeSpeed = (enlargeSpeed_ + urand(enlargeSpeedJitter_)) * tick_life;
/*if (is_diffuse_anim) { /*if (is_diffuse_anim) {
if (material_.diffuse.animation_frame_rate < 0 && animation->bitmaps.size() > 0) if (material_.diffuse.animation_frame_rate < 0 && animation->bitmaps.size() > 0)
cp.animationFrameRate = animation->bitmaps.size() / cp.lifeDuration; cp.animationFrameRate = animation->bitmaps.size() / cp.lifeDuration;
else else
cp.animationFrameRate = material_.diffuse.animation_frame_rate; cp.animationFrameRate = material_.diffuse.animation_frame_rate;
}*/ }*/
if (tex_scale.isEmpty()) cp.tex_rect.setSize(tex_rect.size()); if (tex_scale.isEmpty())
else cp.tex_rect.setSize(tex_rect.size() * tex_scale); cp.tex_rect.setSize(tex_rect.size());
cp.tex_rect.moveTopLeft(tex_rect.topLeft() + QPointF(uprand(tex_rect.width() - cp.tex_rect.width()), uprand(tex_rect.height() - cp.tex_rect.height()))); else
//cp.tex_rect = tex_rect; cp.tex_rect.setSize(tex_rect.size() * tex_scale);
cp.tex_rect.moveTopLeft(tex_rect.topLeft() + QPointF(uprand(tex_rect.width() - cp.tex_rect.width()),
uprand(tex_rect.height() - cp.tex_rect.height())));
// cp.tex_rect = tex_rect;
particles.push_back(cp); particles.push_back(cp);
} }
need_birth -= floor(need_birth); need_birth -= floor(need_birth);
} }
for (int i = 0; i < particles.size(); ++i) { for (int i = 0; i < particles.size(); ++i) {
Particle & c(particles[i]); Particle & c(particles[i]);
foreach (const QVector3D & f, forces) foreach(const QVector3D & f, forces)
c.speed += f; c.speed += f;
c.lifeCurrent += tick_life; c.lifeCurrent += tick_life;
//qDebug() << "life" << c.lifeCurrent << c.lifeDuration; // qDebug() << "life" << c.lifeCurrent << c.lifeDuration;
if (c.lifeCurrent > c.lifeDuration) { if (c.lifeCurrent > c.lifeDuration) {
//qDebug() << "remove" << i; // qDebug() << "remove" << i;
particles.remove(i); particles.remove(i);
i--; i--;
continue; continue;
@@ -103,7 +104,7 @@ void GLParticlesSystem::update() {
c.pos += c.speed * tick_life; c.pos += c.speed * tick_life;
c.speed /= c.speedDecay; c.speed /= c.speedDecay;
c.size += c.enlargeSpeed; c.size += c.enlargeSpeed;
//if (c.lifeCurrent > 1.) c.angle += urand(5.); // if (c.lifeCurrent > 1.) c.angle += urand(5.);
} }
} }
@@ -114,31 +115,30 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
pass_ = GLObjectBase::Transparent; pass_ = GLObjectBase::Transparent;
Camera * camera(view_->camera()); Camera * camera(view_->camera());
QVector3D apos = camera->pos(), dir = camera->direction(); QVector3D apos = camera->pos(), dir = camera->direction();
//qDebug() << dir; // qDebug() << dir;
//qDebug() << camera.angles(); // qDebug() << camera.angles();
//qDebug() << camera.angle_xy; // qDebug() << camera.angle_xy;
GLfloat cxyc, czs, czc; GLfloat cxyc, czs, czc;
GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(), GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(), tr_g = material_.color_diffuse.greenF(),
tr_g = material_.color_diffuse.greenF(),
tr_b = material_.color_diffuse.blueF(), tr_b = material_.color_diffuse.blueF(),
tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency); tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency);
//cxys = sin(camera.angle_xy * deg2rad); // cxys = sin(camera.angle_xy * deg2rad);
cxyc = cosf(camera->angles_.y() * deg2rad); cxyc = cosf(camera->angles_.y() * deg2rad);
czs = sinf(camera->angles_.z() * deg2rad); czs = sinf(camera->angles_.z() * deg2rad);
czc = cosf(camera->angles_.z() * deg2rad); czc = cosf(camera->angles_.z() * deg2rad);
dx = -czc; dx = -czc;
dy = czs; dy = czs;
vertices.clear(); vertices.clear();
texcoords.clear(); texcoords.clear();
colors.clear(); colors.clear();
for (int i = 0; i < particles.size(); ++i) for (int i = 0; i < particles.size(); ++i)
//particles[i].pos_h.setZ((particles[i].pos - apos).lengthSquared()); // particles[i].pos_h.setZ((particles[i].pos - apos).lengthSquared());
particles[i].pos_h.setZ(particles[i].pos.distanceToPlane(apos, dir)); particles[i].pos_h.setZ(particles[i].pos.distanceToPlane(apos, dir));
std::sort(particles.begin(), particles.end()); std::sort(particles.begin(), particles.end());
glBegin(GL_POINTS); glBegin(GL_POINTS);
foreach (const Particle & i, particles) { foreach(const Particle & i, particles) {
//glVertex3f(i.pos.x(), i.pos.y(), i.pos.z()); // glVertex3f(i.pos.x(), i.pos.y(), i.pos.z());
a = (i.lifeDuration - i.lifeCurrent) / fade_time; a = (i.lifeDuration - i.lifeCurrent) / fade_time;
if (a > 1.f) a = 1.f; if (a > 1.f) a = 1.f;
a *= tr_a; a *= tr_a;
@@ -182,12 +182,12 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
} }
} }
glEnd(); glEnd();
//bool cae = glIsEnabled(GL_COLOR_ARRAY), nae = glIsEnabled(GL_NORMAL_ARRAY); // bool cae = glIsEnabled(GL_COLOR_ARRAY), nae = glIsEnabled(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
//glNormal3f(vn.x(), vn.y(), vn.z()); // glNormal3f(vn.x(), vn.y(), vn.z());
glNormal3f(0., 0., 1.); glNormal3f(0., 0., 1.);
glDepthMask(false); glDepthMask(false);
glEnable(GL_COLOR_ARRAY); glEnable(GL_COLOR_ARRAY);
@@ -195,21 +195,20 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
glTexCoordPointer(2, GL_FLOAT, 0, texcoords.constData()); glTexCoordPointer(2, GL_FLOAT, 0, texcoords.constData());
glColorPointer(4, GL_FLOAT, 0, colors.constData()); glColorPointer(4, GL_FLOAT, 0, colors.constData());
//glEnable(GL_ALPHA_TEST); // glEnable(GL_ALPHA_TEST);
//glAlphaFunc(); // glAlphaFunc();
glDrawArrays(GL_QUADS, 0, vertices.size() / 3); glDrawArrays(GL_QUADS, 0, vertices.size() / 3);
glDepthMask(true); glDepthMask(true);
//glDisable(GL_ALPHA_TEST); // glDisable(GL_ALPHA_TEST);
//if (!cae) glDisable(GL_COLOR_ARRAY); // if (!cae) glDisable(GL_COLOR_ARRAY);
//if (nae) glEnable(GL_NORMAL_ARRAY); // if (nae) glEnable(GL_NORMAL_ARRAY);
} }
GLParticlesSystem::Particle::Particle(float life_dur) { GLParticlesSystem::Particle::Particle(float life_dur) {
size = 1.; size = 1.;
angle = lifeCurrent = 0.; angle = lifeCurrent = 0.;
speedDecay = 0.; speedDecay = 0.;
lifeDuration = life_dur; lifeDuration = life_dur;
tex_rect = QRectF(0, 0, 1, 1); tex_rect = QRectF(0, 0, 1, 1);
} }
+74 -62
View File
@@ -19,13 +19,16 @@
#ifndef GLPARTICLES_SYSTEM_H #ifndef GLPARTICLES_SYSTEM_H
#define GLPARTICLES_SYSTEM_H #define GLPARTICLES_SYSTEM_H
#include <QMutex>
#include "gltexture_manager.h"
#include "globject.h"
#include "glcamera.h" #include "glcamera.h"
#include "globject.h"
#include "gltexture_manager.h"
class GLParticlesSystem: public QObject, public GLObjectBase, protected QOpenGLFunctions #include <QMutex>
{
class GLParticlesSystem
: public QObject
, public GLObjectBase
, protected QOpenGLFunctions {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float birthRate READ birthRate WRITE setBirthRate) Q_PROPERTY(float birthRate READ birthRate WRITE setBirthRate)
Q_PROPERTY(float lifeDuration READ lifeDuration WRITE setLifeDuration) Q_PROPERTY(float lifeDuration READ lifeDuration WRITE setLifeDuration)
@@ -47,11 +50,16 @@ class GLParticlesSystem: public QObject, public GLObjectBase, protected QOpenGLF
Q_PROPERTY(bool active READ isActive WRITE setActive) Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(bool birthEnabled READ isBirthEnabled WRITE setBirthEnabled) Q_PROPERTY(bool birthEnabled READ isBirthEnabled WRITE setBirthEnabled)
Q_PROPERTY(float fadeTime READ fadeTime WRITE setFadeTime) Q_PROPERTY(float fadeTime READ fadeTime WRITE setFadeTime)
public: public:
GLParticlesSystem(const QVector3D & pos = QVector3D()); GLParticlesSystem(const QVector3D & pos = QVector3D());
~GLParticlesSystem() {;} ~GLParticlesSystem() { ; }
enum Type {Cone, Omni, Box}; enum Type {
Cone,
Omni,
Box
};
struct Particle { struct Particle {
Particle(float life_dur = 40.); Particle(float life_dur = 40.);
@@ -71,62 +79,65 @@ public:
void update(); void update();
void draw(QOpenGLShaderProgram * prog, bool); void draw(QOpenGLShaderProgram * prog, bool);
float birthRate() const {return birthRate_;} float birthRate() const { return birthRate_; }
float lifeDuration() const {return lifeDuration_;} float lifeDuration() const { return lifeDuration_; }
float size() const {return size_;} float size() const { return size_; }
float enlargeSpeed() const {return enlargeSpeed_;} float enlargeSpeed() const { return enlargeSpeed_; }
float initialAngle() const {return initialAngle_;} float initialAngle() const { return initialAngle_; }
float initialSpeed() const {return initialSpeed_;} float initialSpeed() const { return initialSpeed_; }
float speedDecay() const {return speedDecay_;} float speedDecay() const { return speedDecay_; }
float baseAngle() const {return baseAngle_;} float baseAngle() const { return baseAngle_; }
QVector3D speedDirection() const {return speedDirection_;} QVector3D speedDirection() const { return speedDirection_; }
QVector3D emitterPosition() const {return emitterPosition_;} QVector3D emitterPosition() const { return emitterPosition_; }
QVector3D emitterDirection() const {return emitterDirection_;} QVector3D emitterDirection() const { return emitterDirection_; }
Box3D emitterRect() const {return emitterRect_;} Box3D emitterRect() const { return emitterRect_; }
float lifeDurationJitter() const {return lifeDurationJitter_;} float lifeDurationJitter() const { return lifeDurationJitter_; }
float speedJitter() const {return speedJitter_;} float speedJitter() const { return speedJitter_; }
float speedDirectionJitter() const {return speedDirectionJitter_;} float speedDirectionJitter() const { return speedDirectionJitter_; }
float sizeJitter() const {return sizeJitter_;} float sizeJitter() const { return sizeJitter_; }
float enlargeSpeedJitter() const {return enlargeSpeedJitter_;} float enlargeSpeedJitter() const { return enlargeSpeedJitter_; }
float angleJitter() const {return angleJitter_;} float angleJitter() const { return angleJitter_; }
bool isActive() const {return active_;} bool isActive() const { return active_; }
bool isBirthEnabled() const {return birthEnabled_;} bool isBirthEnabled() const { return birthEnabled_; }
GLParticlesSystem::Type emitterType() const {return emitterType_;} GLParticlesSystem::Type emitterType() const { return emitterType_; }
float fadeTime() const {return fade_time;} float fadeTime() const { return fade_time; }
bool isAddVerticalFaceEnabled() const {return add_vert_face;} bool isAddVerticalFaceEnabled() const { return add_vert_face; }
void setBirthRate(const float & arg) {birthRate_ = arg; tick_birth = birthRate_ / freq;} void setBirthRate(const float & arg) {
void setLifeDuration(const float & arg) {lifeDuration_ = arg;} birthRate_ = arg;
void setSize(const float & arg) {size_ = arg;} tick_birth = birthRate_ / freq;
void setEnlargeSpeed(const float & arg) {enlargeSpeed_ = arg;} }
void setInitialAngle(const float & arg) {initialAngle_ = arg;} void setLifeDuration(const float & arg) { lifeDuration_ = arg; }
void setInitialSpeed(const float & arg) {initialSpeed_ = arg;} void setSize(const float & arg) { size_ = arg; }
void setBaseAngle(const float & arg) {baseAngle_ = arg;} void setEnlargeSpeed(const float & arg) { enlargeSpeed_ = arg; }
void setSpeedDecay(const float & arg) {speedDecay_ = arg;} void setInitialAngle(const float & arg) { initialAngle_ = arg; }
void setSpeedDirection(const QVector3D & arg) {speedDirection_ = arg;} void setInitialSpeed(const float & arg) { initialSpeed_ = arg; }
void setEmitterPosition(const QVector3D & arg) {emitterPosition_ = arg;} void setBaseAngle(const float & arg) { baseAngle_ = arg; }
void setEmitterDirection(const QVector3D & arg) {emitterDirection_ = arg.normalized();} void setSpeedDecay(const float & arg) { speedDecay_ = arg; }
void setEmitterRect(const Box3D & arg) {emitterRect_ = arg;} void setSpeedDirection(const QVector3D & arg) { speedDirection_ = arg; }
void setLifeDurationJitter(const float & arg) {lifeDurationJitter_ = arg;} void setEmitterPosition(const QVector3D & arg) { emitterPosition_ = arg; }
void setSpeedJitter(const float & arg) {speedJitter_ = arg;} void setEmitterDirection(const QVector3D & arg) { emitterDirection_ = arg.normalized(); }
void setSpeedDirectionJitter(const float & arg) {speedDirectionJitter_ = arg;} void setEmitterRect(const Box3D & arg) { emitterRect_ = arg; }
void setSizeJitter(const float & arg) {sizeJitter_ = arg;} void setLifeDurationJitter(const float & arg) { lifeDurationJitter_ = arg; }
void setEnlargeSpeedJitter(const float & arg) {enlargeSpeedJitter_ = arg;} void setSpeedJitter(const float & arg) { speedJitter_ = arg; }
void setActive(const bool & arg) {active_ = arg;} void setSpeedDirectionJitter(const float & arg) { speedDirectionJitter_ = arg; }
void setAngleJitter(const float & arg) {angleJitter_ = arg;} void setSizeJitter(const float & arg) { sizeJitter_ = arg; }
void setBirthEnabled(const bool & arg) {birthEnabled_ = arg;} void setEnlargeSpeedJitter(const float & arg) { enlargeSpeedJitter_ = arg; }
void setEmitterType(const GLParticlesSystem::Type & arg) {emitterType_ = arg;} void setActive(const bool & arg) { active_ = arg; }
void setFadeTime(const float & arg) {fade_time = arg;} void setAngleJitter(const float & arg) { angleJitter_ = arg; }
void setAddVerticalFaceEnabled(const bool & arg) {add_vert_face = arg;} void setBirthEnabled(const bool & arg) { birthEnabled_ = arg; }
void setTextureRect(const QRectF & arg) {tex_rect = arg;} void setEmitterType(const GLParticlesSystem::Type & arg) { emitterType_ = arg; }
void setTextureScale(const float & x, const float & y) {tex_scale = QSizeF(x, y);} void setFadeTime(const float & arg) { fade_time = arg; }
void setTextureScale(const QSizeF & arg) {tex_scale = arg;} void setAddVerticalFaceEnabled(const bool & arg) { add_vert_face = arg; }
void setTextureRect(const QRectF & arg) { tex_rect = arg; }
void setTextureScale(const float & x, const float & y) { tex_scale = QSizeF(x, y); }
void setTextureScale(const QSizeF & arg) { tex_scale = arg; }
void addForce(const QVector3D & f) {forces << f;} void addForce(const QVector3D & f) { forces << f; }
void birthParticles(int count) {need_birth += count;} void birthParticles(int count) { need_birth += count; }
float frequency() const {return freq;} float frequency() const { return freq; }
void setFrequency(const float & f) {freq = f;} void setFrequency(const float & f) { freq = f; }
float additionalSpeed; float additionalSpeed;
@@ -145,9 +156,10 @@ private:
float lifeDurationJitter_, speedJitter_, speedDirectionJitter_, sizeJitter_, angleJitter_, initialAngle_; float lifeDurationJitter_, speedJitter_, speedDirectionJitter_, sizeJitter_, angleJitter_, initialAngle_;
float enlargeSpeed_, enlargeSpeedJitter_, baseAngle_; float enlargeSpeed_, enlargeSpeedJitter_, baseAngle_;
bool active_, birthEnabled_, is_diffuse_anim, add_vert_face; bool active_, birthEnabled_, is_diffuse_anim, add_vert_face;
}; };
inline bool operator <(const GLParticlesSystem::Particle & f, const GLParticlesSystem::Particle & s) {return f.pos_h.z() > s.pos_h.z();} inline bool operator<(const GLParticlesSystem::Particle & f, const GLParticlesSystem::Particle & s) {
return f.pos_h.z() > s.pos_h.z();
}
#endif // GLPARTICLES_SYSTEM_H #endif // GLPARTICLES_SYSTEM_H
+39 -36
View File
@@ -28,7 +28,6 @@ void GLPrimitivePoint::draw(QOpenGLShaderProgram * prog, bool simplest) {
} }
void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) { void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) {
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF()); glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
glBegin(GL_LINES); glBegin(GL_LINES);
@@ -38,24 +37,24 @@ void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) {
} }
GLPrimitiveCube::GLPrimitiveCube(float width, float length, float height, QVector3D pos): GLObjectBase() { GLPrimitiveCube::GLPrimitiveCube(float width, float length, float height, QVector3D pos): GLObjectBase() {
geom_prim = Quads; geom_prim = Quads;
w = width; w = width;
l = length; l = length;
h = height; h = height;
moveTo(pos); moveTo(pos);
//init(); // init();
} }
void GLPrimitiveCube::init() { void GLPrimitiveCube::init() {
float hw = w / 2.f, hl = l / 2.f, hh = h / 2.f; float hw = w / 2.f, hl = l / 2.f, hh = h / 2.f;
//list = glGenLists(1); // list = glGenLists(1);
//glNewList(list, GL_COMPILE); // glNewList(list, GL_COMPILE);
//glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(), material_.color_diffuse.alphaF()); // glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(),
// material_.color_diffuse.alphaF());
vbo.init(); vbo.init();
QVector<GLfloat> & d_vertices(vbo.vertices()), & d_normals(vbo.normals()), & d_uvs(vbo.texcoords()); QVector<GLfloat> &d_vertices(vbo.vertices()), &d_normals(vbo.normals()), &d_uvs(vbo.texcoords());
d_vertices.clear(); d_vertices.clear();
d_normals.clear(); d_normals.clear();
d_uvs.clear(); d_uvs.clear();
@@ -108,13 +107,13 @@ void GLPrimitiveCube::init() {
GLPrimitiveEllipsoid::GLPrimitiveEllipsoid(float width, float length, float height, int seg_wl, int seg_h, QVector3D pos) { GLPrimitiveEllipsoid::GLPrimitiveEllipsoid(float width, float length, float height, int seg_wl, int seg_h, QVector3D pos) {
geom_prim = GLObjectBase::Triangles; geom_prim = GLObjectBase::Triangles;
w = width; w = width;
l = length; l = length;
h = height; h = height;
swl = seg_wl; swl = seg_wl;
sh = seg_h; sh = seg_h;
moveTo(pos); moveTo(pos);
//init(); // init();
} }
@@ -125,9 +124,12 @@ void GLPrimitiveEllipsoid::putTriangle(const QVector3D & v0, const QVector3D & v
vbo.normals() << n.x() << n.y() << n.z(); vbo.normals() << n.x() << n.y() << n.z();
return; return;
QVector3D s(w, l, h); QVector3D s(w, l, h);
n = (v0 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z(); n = (v0 * s).normalized();
n = (v1 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z(); vbo.normals() << n.x() << n.y() << n.z();
n = (v2 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z(); n = (v1 * s).normalized();
vbo.normals() << n.x() << n.y() << n.z();
n = (v2 * s).normalized();
vbo.normals() << n.x() << n.y() << n.z();
} }
@@ -135,7 +137,7 @@ void GLPrimitiveEllipsoid::init() {
QVector<QVector3D> points; QVector<QVector3D> points;
vbo.clear(); vbo.clear();
vbo.init(); vbo.init();
int ret = 0; int ret = 0;
int hseg = sh + 1, wlseg = swl + 1; int hseg = sh + 1, wlseg = swl + 1;
float crw, crl, a, ch, twl; float crw, crl, a, ch, twl;
QVector3D cp(0., 0., -h / 2.f); QVector3D cp(0., 0., -h / 2.f);
@@ -161,7 +163,8 @@ void GLPrimitiveEllipsoid::init() {
} }
} }
} }
if (i == 1) putTriangle(points[0], points[ret - wlseg * 2 + 1], points[ret]); if (i == 1)
putTriangle(points[0], points[ret - wlseg * 2 + 1], points[ret]);
else { else {
putTriangle(points[ret - wlseg * 2 + 1], points[ret], points[ret - wlseg * 2]); putTriangle(points[ret - wlseg * 2 + 1], points[ret], points[ret - wlseg * 2]);
putTriangle(points[ret - wlseg * 2 + 1], points[ret - wlseg * 2], points[ret - wlseg * 4 + 1]); putTriangle(points[ret - wlseg * 2 + 1], points[ret - wlseg * 2], points[ret - wlseg * 4 + 1]);
@@ -178,43 +181,43 @@ void GLPrimitiveEllipsoid::init() {
void GLPrimitiveAxis::draw(QOpenGLShaderProgram * prog, bool simplest) { void GLPrimitiveAxis::draw(QOpenGLShaderProgram * prog, bool simplest) {
float bs = 1.f; float bs = 1.f;
float as = 0.1f; float as = 0.1f;
float aw = 0.07f; float aw = 0.07f;
float cr_x = 0.8f, cg_y = 0.75f, cb_z = 0.8f; float cr_x = 0.8f, cg_y = 0.75f, cb_z = 0.8f;
glBegin(GL_LINES); glBegin(GL_LINES);
glColor3f(cr_x, 0, 0); glColor3f(cr_x, 0, 0);
glVertex3f(-bs, 0, 0); glVertex3f(-bs, 0, 0);
glVertex3f(bs, 0, 0); glVertex3f(bs, 0, 0);
glVertex3f(bs, 0, 0); glVertex3f(bs, 0, 0);
glVertex3f(bs-as, aw, 0); glVertex3f(bs - as, aw, 0);
glVertex3f(bs, 0, 0); glVertex3f(bs, 0, 0);
glVertex3f(bs-as, -aw, 0); glVertex3f(bs - as, -aw, 0);
glVertex3f(bs, 0, 0); glVertex3f(bs, 0, 0);
glVertex3f(bs-as, 0, aw); glVertex3f(bs - as, 0, aw);
glVertex3f(bs, 0, 0); glVertex3f(bs, 0, 0);
glVertex3f(bs-as, 0, -aw); glVertex3f(bs - as, 0, -aw);
glColor3f(0, cg_y, 0); glColor3f(0, cg_y, 0);
glVertex3f(0, -bs, 0); glVertex3f(0, -bs, 0);
glVertex3f(0, bs, 0); glVertex3f(0, bs, 0);
glVertex3f(0, bs, 0); glVertex3f(0, bs, 0);
glVertex3f(0, bs-as, aw); glVertex3f(0, bs - as, aw);
glVertex3f(0, bs, 0); glVertex3f(0, bs, 0);
glVertex3f(0, bs-as, -aw); glVertex3f(0, bs - as, -aw);
glVertex3f(0, bs, 0); glVertex3f(0, bs, 0);
glVertex3f(aw, bs-as, 0); glVertex3f(aw, bs - as, 0);
glVertex3f(0, bs, 0); glVertex3f(0, bs, 0);
glVertex3f(-aw, bs-as, 0); glVertex3f(-aw, bs - as, 0);
glColor3f(0, 0, cb_z); glColor3f(0, 0, cb_z);
glVertex3f(0, 0, -bs); glVertex3f(0, 0, -bs);
glVertex3f(0, 0, bs); glVertex3f(0, 0, bs);
glVertex3f(0, 0, bs); glVertex3f(0, 0, bs);
glVertex3f(aw, 0, bs-as); glVertex3f(aw, 0, bs - as);
glVertex3f(0, 0, bs); glVertex3f(0, 0, bs);
glVertex3f(-aw, 0, bs-as); glVertex3f(-aw, 0, bs - as);
glVertex3f(0, 0, bs); glVertex3f(0, 0, bs);
glVertex3f(0, aw, bs-as); glVertex3f(0, aw, bs - as);
glVertex3f(0, 0, bs); glVertex3f(0, 0, bs);
glVertex3f(0, -aw, bs-as); glVertex3f(0, -aw, bs - as);
glEnd(); glEnd();
} }
+25 -24
View File
@@ -22,51 +22,53 @@
#include "globject.h" #include "globject.h"
class GLPrimitivePoint: public GLObjectBase class GLPrimitivePoint: public GLObjectBase {
{
public: public:
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;} GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) { sz = 8.; }
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
private: private:
double sz; double sz;
}; };
class GLPrimitiveLine: public GLObjectBase {
class GLPrimitiveLine: public GLObjectBase
{
public: public:
GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {p0 = p0_; p1 = p1_;} GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {
p0 = p0_;
p1 = p1_;
}
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
QVector3D point0() const {return p0;} QVector3D point0() const { return p0; }
QVector3D point1() const {return p1;} QVector3D point1() const { return p1; }
void setPoint0(const QVector3D & p) {p0 = p;} void setPoint0(const QVector3D & p) { p0 = p; }
void setPoint1(const QVector3D & p) {p1 = p;} void setPoint1(const QVector3D & p) { p1 = p; }
private: private:
QVector3D p0, p1; QVector3D p0, p1;
}; };
class GLPrimitiveCube: public GLObjectBase {
class GLPrimitiveCube: public GLObjectBase
{
public: public:
GLPrimitiveCube(float width = 1., float length = 1., float height = 1., QVector3D pos = QVector3D()); GLPrimitiveCube(float width = 1., float length = 1., float height = 1., QVector3D pos = QVector3D());
virtual void init(); virtual void init();
private: private:
float w, l, h; float w, l, h;
}; };
class GLPrimitiveEllipsoid: public GLObjectBase {
class GLPrimitiveEllipsoid: public GLObjectBase
{
public: public:
GLPrimitiveEllipsoid(float width = 1., float length = 1., float height = 1., int seg_wl = 10, int seg_h = 10, QVector3D pos = QVector3D()); GLPrimitiveEllipsoid(float width = 1.,
float length = 1.,
float height = 1.,
int seg_wl = 10,
int seg_h = 10,
QVector3D pos = QVector3D());
virtual void init(); virtual void init();
private: private:
void putTriangle(const QVector3D & v0, const QVector3D & v1, const QVector3D & v2); void putTriangle(const QVector3D & v0, const QVector3D & v1, const QVector3D & v2);
float w, l, h; float w, l, h;
@@ -74,10 +76,9 @@ private:
}; };
class GLPrimitiveAxis: public GLObjectBase class GLPrimitiveAxis: public GLObjectBase {
{
public: public:
GLPrimitiveAxis() {accept_fog = accept_light = cast_shadow = rec_shadow = select_ = false;} GLPrimitiveAxis() { accept_fog = accept_light = cast_shadow = rec_shadow = select_ = false; }
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
}; };
+101 -77
View File
@@ -17,6 +17,7 @@
*/ */
#include "glrendererbase.h" #include "glrendererbase.h"
#include "globject.h" #include "globject.h"
#include "qglview.h" #include "qglview.h"
@@ -25,7 +26,7 @@ GLRendererBase::GLRendererBase(QGLView * view_): view(*view_) {
white_image = QImage(1, 1, QImage::Format_ARGB32); white_image = QImage(1, 1, QImage::Format_ARGB32);
white_image.fill(0xFFFFFFFF); white_image.fill(0xFFFFFFFF);
white_image_id = 0; white_image_id = 0;
violent_image = QImage(1, 1, QImage::Format_ARGB32); violent_image = QImage(1, 1, QImage::Format_ARGB32);
violent_image.fill(QColor(127, 127, 255)); violent_image.fill(QColor(127, 127, 255));
violent_image_id = 0; violent_image_id = 0;
} }
@@ -36,18 +37,18 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
GLfloat pos[] = {0.f, 0.f, 0.f, 0.f}; GLfloat pos[] = {0.f, 0.f, 0.f, 0.f};
GLfloat dir[] = {0.f, 0.f, 0.f}; GLfloat dir[] = {0.f, 0.f, 0.f};
GLfloat col[] = {0.f, 0.f, 0.f}; GLfloat col[] = {0.f, 0.f, 0.f};
pos[0] = l.light_type == Light::Directional ? -l.direction.x() : lp.x(); pos[0] = l.light_type == Light::Directional ? -l.direction.x() : lp.x();
pos[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y(); pos[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y();
pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z(); pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z();
pos[3] = l.light_type == Light::Directional ? 0. : 1.; pos[3] = l.light_type == Light::Directional ? 0. : 1.;
dir[0] = ld.x(); dir[0] = ld.x();
dir[1] = ld.y(); dir[1] = ld.y();
dir[2] = ld.z(); dir[2] = ld.z();
col[0] = l.visible_ ? l.color().redF() * l.intensity : 0.f; col[0] = l.visible_ ? l.color().redF() * l.intensity : 0.f;
col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.f; col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.f;
col[2] = l.visible_ ? l.color().blueF() * l.intensity : 0.f; col[2] = l.visible_ ? l.color().blueF() * l.intensity : 0.f;
glEnable(gl_index); glEnable(gl_index);
//glLightfv(gl_index, GL_AMBIENT, ambient); // glLightfv(gl_index, GL_AMBIENT, ambient);
glLightfv(gl_index, GL_DIFFUSE, col); glLightfv(gl_index, GL_DIFFUSE, col);
glLightfv(gl_index, GL_SPECULAR, col); glLightfv(gl_index, GL_SPECULAR, col);
glLightfv(gl_index, GL_POSITION, pos); glLightfv(gl_index, GL_POSITION, pos);
@@ -57,11 +58,12 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
if (l.light_type == Light::Cone) { if (l.light_type == Light::Cone) {
glLightfv(gl_index, GL_SPOT_DIRECTION, dir); glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_end / 2.f); glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_end / 2.f);
glLightf(gl_index, GL_SPOT_EXPONENT, (1.f - piClamp<float>((l.angle_end - l.angle_start) / (l.angle_end + 0.001f), 0., 1.f)) * 128.f); glLightf(gl_index,
GL_SPOT_EXPONENT,
(1.f - piClamp<float>((l.angle_end - l.angle_start) / (l.angle_end + 0.001f), 0., 1.f)) * 128.f);
} else { } else {
glLightf(gl_index, GL_SPOT_CUTOFF, 180.); glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
} }
} }
@@ -78,18 +80,21 @@ void GLRendererBase::setupAmbientLight(const QColor & a, bool first_pass) {
void GLRendererBase::setupShadersLights(int lights_count) { void GLRendererBase::setupShadersLights(int lights_count) {
/*foreach (QOpenGLShaderProgram * i, view.shaders_ppl) { /*foreach (QOpenGLShaderProgram * i, view.shaders_ppl) {
i->bind(); i->bind();
i->setUniformValue("lightsCount", lights_count); i->setUniformValue("lightsCount", lights_count);
i->setUniformValue("acc_light", lights_count > 0); i->setUniformValue("acc_light", lights_count > 0);
//i->setUniformValue("mat", mvm); //i->setUniformValue("mat", mvm);
}*/ }*/
} }
#define BIND_TEXTURE(ch, map) if (rp.prev_tex[ch] != mat.map.bitmap_id) { \ #define BIND_TEXTURE(ch, map) \
rp.prev_tex[ch] = mat.map.bitmap_id; \ if (rp.prev_tex[ch] != mat.map.bitmap_id) { \
glActiveTexture(GL_TEXTURE0 + ch); glBindTexture(GL_TEXTURE_2D, mat.map.bitmap_id); \ rp.prev_tex[ch] = mat.map.bitmap_id; \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.feature(QGLView::qglAnisotropicLevel).toInt());} glActiveTexture(GL_TEXTURE0 + ch); \
glBindTexture(GL_TEXTURE_2D, mat.map.bitmap_id); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.feature(QGLView::qglAnisotropicLevel).toInt()); \
}
void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) { void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) {
if (first_object) { if (first_object) {
@@ -99,12 +104,30 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
setupShadersTextures(o, rp); setupShadersTextures(o, rp);
Material & mat(o.material_); Material & mat(o.material_);
if (rp.light) { if (rp.light) {
if (o.accept_light) {if (!rp.prev_light) {glSetLightEnabled(true); rp.prev_light = true;}} if (o.accept_light) {
else {if (rp.prev_light) {glSetLightEnabled(false); rp.prev_light = false;}} if (!rp.prev_light) {
glSetLightEnabled(true);
rp.prev_light = true;
}
} else {
if (rp.prev_light) {
glSetLightEnabled(false);
rp.prev_light = false;
}
}
} }
if (rp.fog) { if (rp.fog) {
if (o.accept_fog) {if (!rp.prev_fog) {glSetFogEnabled(true); rp.prev_fog = true;}} if (o.accept_fog) {
else {if (rp.prev_fog) {glSetFogEnabled(false); rp.prev_fog = false;}} if (!rp.prev_fog) {
glSetFogEnabled(true);
rp.prev_fog = true;
}
} else {
if (rp.prev_fog) {
glSetFogEnabled(false);
rp.prev_fog = false;
}
}
} }
if (rp.textures) { if (rp.textures) {
BIND_TEXTURE(0, map_diffuse) BIND_TEXTURE(0, map_diffuse)
@@ -123,7 +146,7 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
void GLRendererBase::setupLights(int pass, int lights_per_pass) { void GLRendererBase::setupLights(int pass, int lights_per_pass) {
int light_start, light_end, lmax; int light_start, light_end, lmax;
light_start = pass * lights_per_pass; light_start = pass * lights_per_pass;
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights_.size()); light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights_.size());
setupAmbientLight(view.ambientColor_, pass == 0); setupAmbientLight(view.ambientColor_, pass == 0);
if (!view.lights_.isEmpty()) { if (!view.lights_.isEmpty()) {
setupShadersLights(light_end - light_start); setupShadersLights(light_end - light_start);
@@ -154,19 +177,20 @@ void GLRendererBase::applyFilteringParameters() {
void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) { void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) {
RenderingParameters rpl; RenderingParameters rpl;
rpl.pass = pass; rpl.pass = pass;
rpl.light_pass = light_pass; rpl.light_pass = light_pass;
rpl.shaders = shaders; rpl.shaders = shaders;
rpl.textures = textures; rpl.textures = textures;
rpl.light = rpl.prev_light = light; rpl.light = rpl.prev_light = light;
rpl.fog = rpl.prev_fog = fog; rpl.fog = rpl.prev_fog = fog;
rpl.view_matrix = rp.view_matrix; rpl.view_matrix = rp.view_matrix;
rpl.prev_view_matrix = rp.prev_view_matrix; rpl.prev_view_matrix = rp.prev_view_matrix;
rpl.proj_matrix = rp.proj_matrix; rpl.proj_matrix = rp.proj_matrix;
rpl.prev_proj_matrix = rp.prev_proj_matrix; rpl.prev_proj_matrix = rp.prev_proj_matrix;
rpl.cam_offset_matrix = view.camera()->offsetMatrix(); rpl.cam_offset_matrix = view.camera()->offsetMatrix();
//qDebug() << "view:" << rp.view_matrix; // qDebug() << "view:" << rp.view_matrix;
for (int i = 0; i < 32; ++i) rpl.prev_tex[i] = 0; for (int i = 0; i < 32; ++i)
rpl.prev_tex[i] = 0;
setupTextures(view.objects_, rpl, true); setupTextures(view.objects_, rpl, true);
glSetLightEnabled(rpl.prev_light); glSetLightEnabled(rpl.prev_light);
glSetFogEnabled(rpl.prev_fog); glSetFogEnabled(rpl.prev_fog);
@@ -181,16 +205,15 @@ void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, boo
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) { void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) {
if (!o.isInit()) if (!o.isInit()) o.init();
o.init(); if (!o.isTexturesLoaded()) o.loadTextures();
if (!o.isTexturesLoaded())
o.loadTextures();
if (!o.visible_) return; if (!o.visible_) return;
if (rpl.pass == o.pass_) { if (rpl.pass == o.pass_) {
Material & mat(o.material_); Material & mat(o.material_);
QMatrix4x4 curview = rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_, prevview = rpl.prev_view_matrix * rpl.cam_offset_matrix * o.itransform_; QMatrix4x4 curview = rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_,
prevview = rpl.prev_view_matrix * rpl.cam_offset_matrix * o.itransform_;
setupTextures(o, rpl, false); setupTextures(o, rpl, false);
mat.apply((QOpenGLShaderProgram*)rpl.shaders); mat.apply((QOpenGLShaderProgram *)rpl.shaders);
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL)); glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_); glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_);
glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_); glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_);
@@ -199,9 +222,12 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
glActiveTexture(GL_TEXTURE0 + 3); glActiveTexture(GL_TEXTURE0 + 3);
if (mat.reflectivity > 0.f) { if (mat.reflectivity > 0.f) {
glEnable(GL_TEXTURE_CUBE_MAP); glEnable(GL_TEXTURE_CUBE_MAP);
if (!mat.map_reflection.isEmpty()) mat.map_reflection.bind(); if (!mat.map_reflection.isEmpty())
else glDisable(GL_TEXTURE_CUBE_MAP); mat.map_reflection.bind();
} else glDisable(GL_TEXTURE_CUBE_MAP); else
glDisable(GL_TEXTURE_CUBE_MAP);
} else
glDisable(GL_TEXTURE_CUBE_MAP);
if (rpl.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP); if (rpl.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity}; GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -211,21 +237,21 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bc); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bc);
glGetFloatv(GL_MODELVIEW_MATRIX, gm); glGetFloatv(GL_MODELVIEW_MATRIX, gm);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
///glLoadTransposeMatrixf(gm); /// glLoadTransposeMatrixf(gm);
glScalef(-1., -1., -1.); glScalef(-1., -1., -1.);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
} }
if (rpl.shaders) { if (rpl.shaders) {
//qDebug() << o.name() << curview << curview.determinant(); // qDebug() << o.name() << curview << curview.determinant();
setUniformMatrices((QOpenGLShaderProgram*)rpl.shaders, rpl.proj_matrix, curview, rpl.prev_proj_matrix, prevview); setUniformMatrices((QOpenGLShaderProgram *)rpl.shaders, rpl.proj_matrix, curview, rpl.prev_proj_matrix, prevview);
} else { } else {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
setGLMatrix(curview); setGLMatrix(curview);
} }
o.draw((QOpenGLShaderProgram*)rpl.shaders); o.draw((QOpenGLShaderProgram *)rpl.shaders);
} }
foreach (GLObjectBase * i, o.children_) foreach(GLObjectBase * i, o.children_)
renderSingleObject(*i, rpl); renderSingleObject(*i, rpl);
} }
@@ -245,60 +271,58 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri
cam.rotateXY(-l->angle_end); cam.rotateXY(-l->angle_end);
cam.rotateZ(l->angle_end); cam.rotateZ(l->angle_end);
l->dir1 = cam.direction() - rdir;*/ l->dir1 = cam.direction() - rdir;*/
//qDebug() << rdir << l->dir0 << l->dir1; // qDebug() << rdir << l->dir0 << l->dir1;
RenderingParameters rpl; RenderingParameters rpl;
rpl.pass = GLObjectBase::Solid; rpl.pass = GLObjectBase::Solid;
rpl.shaders = prog; rpl.shaders = prog;
rpl.textures = rpl.light = rpl.fog = false; rpl.textures = rpl.light = rpl.fog = false;
rpl.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); rpl.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
rpl.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); rpl.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
rpl.cam_offset_matrix = cam.offsetMatrix(); rpl.cam_offset_matrix = cam.offsetMatrix();
QMatrix4x4 mbias; QMatrix4x4 mbias;
mbias.scale(0.5, 0.5, 0.5); mbias.scale(0.5, 0.5, 0.5);
mbias.translate(1., 1., 1.); mbias.translate(1., 1., 1.);
l->shadow_matrix = mbias*rpl.proj_matrix*rpl.view_matrix*rpl.cam_offset_matrix*mat;//;// * mbias; l->shadow_matrix = mbias * rpl.proj_matrix * rpl.view_matrix * rpl.cam_offset_matrix * mat; //;// * mbias;
//qDebug() << mbias; // qDebug() << mbias;
//glPushMatrix(); // glPushMatrix();
renderSingleShadow(view.objects_, rpl); renderSingleShadow(view.objects_, rpl);
//glPopMatrix(); // glPopMatrix();
} }
void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters & rpl) { void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters & rpl) {
if (!o.isInit()) if (!o.isInit()) o.init();
o.init();
if (!o.visible_) return; if (!o.visible_) return;
if (rpl.shaders) { if (rpl.shaders) {
//qDebug() << o.name() << curview << curview.determinant(); // qDebug() << o.name() << curview << curview.determinant();
setUniformMatrices((QOpenGLShaderProgram*)rpl.shaders, rpl.proj_matrix, rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_); setUniformMatrices((QOpenGLShaderProgram *)rpl.shaders, rpl.proj_matrix, rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
} else { } else {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
setGLMatrix(rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_); setGLMatrix(rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
} }
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL)); glPolygonMode(GL_FRONT_AND_BACK,
o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_); glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_);
glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_); glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_);
o.draw((QOpenGLShaderProgram*)rpl.shaders, true); o.draw((QOpenGLShaderProgram *)rpl.shaders, true);
foreach (GLObjectBase * i, o.children_) foreach(GLObjectBase * i, o.children_)
renderSingleShadow(*i, rpl); renderSingleShadow(*i, rpl);
} }
GLRendererBase::RenderingParameters::RenderingParameters() { GLRendererBase::RenderingParameters::RenderingParameters() {
shaders = nullptr; shaders = nullptr;
cur_shader = nullptr; cur_shader = nullptr;
} }
void GLRendererBase::RenderingParameters::prepare() { void GLRendererBase::RenderingParameters::prepare() {
proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
viewproj_matrix = proj_matrix * view_matrix; viewproj_matrix = proj_matrix * view_matrix;
normal_matrix = view_matrix.normalMatrix(); normal_matrix = view_matrix.normalMatrix();
proj_matrix_i = proj_matrix.inverted(); proj_matrix_i = proj_matrix.inverted();
view_matrix_i = view_matrix.inverted(); view_matrix_i = view_matrix.inverted();
viewproj_matrix_i = viewproj_matrix.inverted(); viewproj_matrix_i = viewproj_matrix.inverted();
} }
+17 -16
View File
@@ -1,19 +1,19 @@
/* /*
QGLView QGLView
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLRENDERERBASE_H #ifndef GLRENDERERBASE_H
@@ -22,13 +22,15 @@
#include "glcamera.h" #include "glcamera.h"
#include "glshaders.h" #include "glshaders.h"
class GLRendererBase: public QObject , protected QOpenGLExtraFunctions class GLRendererBase
{ : public QObject
, protected QOpenGLExtraFunctions {
friend class QGLView; friend class QGLView;
Q_OBJECT Q_OBJECT
public: public:
GLRendererBase(QGLView * view_); GLRendererBase(QGLView * view_);
virtual void prepareScene() {;} virtual void prepareScene() { ; }
virtual void renderScene() = 0; virtual void renderScene() = 0;
struct RenderingParameters { struct RenderingParameters {
@@ -74,7 +76,6 @@ protected:
QGLView & view; QGLView & view;
QImage white_image, violent_image; QImage white_image, violent_image;
GLuint white_image_id, violent_image_id; GLuint white_image_id, violent_image_id;
}; };
#endif // GLRENDERERBASE_H #endif // GLRENDERERBASE_H
+89 -94
View File
@@ -32,77 +32,74 @@ const char qgl_vertex_head[] =
"in vec3 qgl_Vertex;\n" "in vec3 qgl_Vertex;\n"
"vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * vec4(qgl_Vertex, 1);}\n"; "vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * vec4(qgl_Vertex, 1);}\n";
const char qgl_fragment_head[] = const char qgl_fragment_head[] = "in vec2 qgl_FragTexture;\n"
"in vec2 qgl_FragTexture;\n" "in vec4 qgl_FragColor;\n"
"in vec4 qgl_FragColor;\n" "out vec4 qgl_FragData[gl_MaxDrawBuffers];\n";
"out vec4 qgl_FragData[gl_MaxDrawBuffers];\n";
const char qgl_uniform[] = const char qgl_uniform[] = "uniform mat4 qgl_ModelViewMatrix;\n"
"uniform mat4 qgl_ModelViewMatrix;\n" "uniform mat4 qgl_ProjectionMatrix;\n"
"uniform mat4 qgl_ProjectionMatrix;\n" "uniform mat4 qgl_ModelViewProjectionMatrix;\n"
"uniform mat4 qgl_ModelViewProjectionMatrix;\n" "uniform mat3 qgl_NormalMatrix;\n"
"uniform mat3 qgl_NormalMatrix;\n" "uniform mat4 qgl_ModelViewMatrixInverse;\n"
"uniform mat4 qgl_ModelViewMatrixInverse;\n" "uniform mat4 qgl_ProjectionMatrixInverse;\n"
"uniform mat4 qgl_ProjectionMatrixInverse;\n" "uniform mat4 qgl_ModelViewProjectionMatrixInverse;\n"
"uniform mat4 qgl_ModelViewProjectionMatrixInverse;\n" "uniform mat4 qgl_ModelViewMatrixTranspose;\n"
"uniform mat4 qgl_ModelViewMatrixTranspose;\n" "uniform mat4 qgl_ProjectionMatrixTranspose;\n"
"uniform mat4 qgl_ProjectionMatrixTranspose;\n" "uniform mat4 qgl_ModelViewProjectionMatrixTranspose;\n"
"uniform mat4 qgl_ModelViewProjectionMatrixTranspose;\n" "uniform mat4 qgl_ModelViewMatrixInverseTranspose;\n"
"uniform mat4 qgl_ModelViewMatrixInverseTranspose;\n" "uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n"
"uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n" "uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n";
"uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n";
const char qgl_structs[] = const char qgl_structs[] = "const int qgl_MaxLights = 8;\n"
"const int qgl_MaxLights = 8;\n" "struct QGLLight {\n"
"struct QGLLight {\n" " vec4 color;\n"
" vec4 color;\n" " vec4 position;\n"
" vec4 position;\n" " vec4 direction;\n"
" vec4 direction;\n" " float intensity;\n"
" float intensity;\n" " float startAngle;\n"
" float startAngle;\n" " float startAngleCos;\n"
" float startAngleCos;\n" " float endAngle;\n"
" float endAngle;\n" " float endAngleCos;\n"
" float endAngleCos;\n" " float constantAttenuation;\n"
" float constantAttenuation;\n" " float linearAttenuation;\n"
" float linearAttenuation;\n" " float quadraticAttenuation;\n"
" float quadraticAttenuation;\n" " sampler2DShadow shadow;\n"
" sampler2DShadow shadow;\n" //" sampler2D shadowColor\n"
//" sampler2D shadowColor\n" " mat4 shadowMatrix;\n"
" mat4 shadowMatrix;\n" //" vec4 shadowDir0;\n"
//" vec4 shadowDir0;\n" //" vec4 shadowDir1;\n"
//" vec4 shadowDir1;\n" "};\n"
"};\n" "struct QGLMap {\n"
"struct QGLMap {\n" " float offset;\n"
" float offset;\n" " float amount;\n"
" float amount;\n" " vec2 scale;\n"
" vec2 scale;\n" " sampler2D map;\n"
" sampler2D map;\n" "};\n"
"};\n" "struct QGLMaterial {\n"
"struct QGLMaterial {\n" " float transparency;\n"
" float transparency;\n" " float reflectivity;\n"
" float reflectivity;\n" " float iof;\n"
" float iof;\n" " float dispersion;\n"
" float dispersion;\n" " vec4 color_diffuse;\n"
" vec4 color_diffuse;\n" " vec4 color_specular;\n"
" vec4 color_specular;\n" " vec4 color_self_illumination;\n"
" vec4 color_self_illumination;\n" " QGLMap map_diffuse;\n"
" QGLMap map_diffuse;\n" " QGLMap map_normal;\n"
" QGLMap map_normal;\n" " QGLMap map_relief;\n"
" QGLMap map_relief;\n" " QGLMap map_self_illumination;\n"
" QGLMap map_self_illumination;\n" " QGLMap map_specularity;\n"
" QGLMap map_specularity;\n" " QGLMap map_specular;\n"
" QGLMap map_specular;\n" "};\n"
"};\n" "uniform QGLLight qgl_AmbientLight;\n"
"uniform QGLLight qgl_AmbientLight;\n" "uniform QGLLight qgl_Light[qgl_MaxLights];\n"
"uniform QGLLight qgl_Light[qgl_MaxLights];\n" "uniform QGLMaterial qgl_Material;\n";
"uniform QGLMaterial qgl_Material;\n";
QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file) { QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file) {
QFile f(file); QFile f(file);
if (!f.open(QIODevice::ReadOnly)) return ""; if (!f.open(QIODevice::ReadOnly)) return "";
QString all = QString::fromUtf8(f.readAll()); QString all = QString::fromUtf8(f.readAll());
int i = all.indexOf("#version"); int i = all.indexOf("#version");
QString version = all.mid(i + 8, all.indexOf("\n", i) - i - 8).trimmed(); QString version = all.mid(i + 8, all.indexOf("\n", i) - i - 8).trimmed();
if (version.toInt() >= 150) { if (version.toInt() >= 150) {
int ip = all.indexOf("\n", i); int ip = all.indexOf("\n", i);
@@ -117,7 +114,7 @@ QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType ty
all.insert(ip + 1, qgl_uniform); all.insert(ip + 1, qgl_uniform);
} }
prog->addShaderFromSourceCode(type, all); prog->addShaderFromSourceCode(type, all);
//qDebug() << "********" << all; // qDebug() << "********" << all;
return all; return all;
} }
@@ -126,20 +123,20 @@ bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QStrin
prog->removeAllShaders(); prog->removeAllShaders();
QDir d(dir); QDir d(dir);
QFileInfoList sl; QFileInfoList sl;
//qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath(); // qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath();
sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot); sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) { foreach(const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName(); // qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
loadShaderFile(prog, QOpenGLShader::Geometry, i.absoluteFilePath()); loadShaderFile(prog, QOpenGLShader::Geometry, i.absoluteFilePath());
} }
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot); sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) { foreach(const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName(); // qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
loadShaderFile(prog, QOpenGLShader::Vertex, i.absoluteFilePath()); loadShaderFile(prog, QOpenGLShader::Vertex, i.absoluteFilePath());
} }
sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot); sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) { foreach(const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName(); // qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
loadShaderFile(prog, QOpenGLShader::Fragment, i.absoluteFilePath()); loadShaderFile(prog, QOpenGLShader::Fragment, i.absoluteFilePath());
} }
if (!prog->link()) { if (!prog->link()) {
@@ -153,17 +150,17 @@ bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QStrin
void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj, QMatrix4x4 prevview) { void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj, QMatrix4x4 prevview) {
if (!prog) return; if (!prog) return;
if (!prog->isLinked()) return; if (!prog->isLinked()) return;
QMatrix4x4 mvpm = proj * view; QMatrix4x4 mvpm = proj * view;
QMatrix4x4 pmvpm = prevproj * prevview; QMatrix4x4 pmvpm = prevproj * prevview;
QMatrix3x3 nm = view.normalMatrix(); QMatrix3x3 nm = view.normalMatrix();
//nm.in; // nm.in;
prog->setUniformValue("qgl_ModelViewMatrix", view); prog->setUniformValue("qgl_ModelViewMatrix", view);
prog->setUniformValue("qgl_ProjectionMatrix", proj); prog->setUniformValue("qgl_ProjectionMatrix", proj);
prog->setUniformValue("prev_ModelViewProjectioMatrix", pmvpm); prog->setUniformValue("prev_ModelViewProjectioMatrix", pmvpm);
prog->setUniformValue("prev_ModelViewMatrix", prevview); prog->setUniformValue("prev_ModelViewMatrix", prevview);
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm); prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
prog->setUniformValue("qgl_NormalMatrix", nm); prog->setUniformValue("qgl_NormalMatrix", nm);
//prog->setUniformValue("qgl_BumpMatrix", nm.); // prog->setUniformValue("qgl_BumpMatrix", nm.);
prog->setUniformValue("qgl_ModelViewMatrixTranspose", view.transposed()); prog->setUniformValue("qgl_ModelViewMatrixTranspose", view.transposed());
prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj.transposed()); prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed()); prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
@@ -183,12 +180,12 @@ void setUniformMap(QOpenGLShaderProgram * prog, QString map_name, const Map & ma
void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat) { void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat) {
if (!prog) return; if (!prog) return;
if (!prog->isLinked()) return; if (!prog->isLinked()) return;
QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions();
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
mat_diffuse[0] = mat.color_diffuse.redF(); mat_diffuse[0] = mat.color_diffuse.redF();
mat_diffuse[1] = mat.color_diffuse.greenF(); mat_diffuse[1] = mat.color_diffuse.greenF();
mat_diffuse[2] = mat.color_diffuse.blueF(); mat_diffuse[2] = mat.color_diffuse.blueF();
mat_diffuse[3] = mat.color_diffuse.alphaF() * (1.f - mat.transparency); mat_diffuse[3] = mat.color_diffuse.alphaF() * (1.f - mat.transparency);
glFuncs->glVertexAttrib4f(prog->attributeLocation("qgl_Color"), mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]); glFuncs->glVertexAttrib4f(prog->attributeLocation("qgl_Color"), mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
prog->setUniformValue("qgl_Material.transparency", mat.transparency); prog->setUniformValue("qgl_Material.transparency", mat.transparency);
prog->setUniformValue("qgl_Material.reflectivity", mat.reflectivity); prog->setUniformValue("qgl_Material.reflectivity", mat.reflectivity);
@@ -203,11 +200,10 @@ void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat) {
setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3, 6); setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3, 6);
setUniformMap(prog, "map_specularity", mat.map_specularity, 4, 6); setUniformMap(prog, "map_specularity", mat.map_specularity, 4, 6);
setUniformMap(prog, "map_specular", mat.map_specular, 5, 6); setUniformMap(prog, "map_specular", mat.map_specular, 5, 6);
} }
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat, int shadow_start) { void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light *> & lights, const QMatrix4x4 & mat, int shadow_start) {
for (int i = 0; i < lights.size(); ++i) for (int i = 0; i < lights.size(); ++i)
setUniformLight(prog, lights[i], QString("qgl_Light[%1]").arg(i), mat, shadow_start + i); setUniformLight(prog, lights[i], QString("qgl_Light[%1]").arg(i), mat, shadow_start + i);
} }
@@ -228,13 +224,12 @@ void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn
if (!prog) return; if (!prog) return;
if (!prog->isLinked()) return; if (!prog->isLinked()) return;
QMatrix4x4 m = mat * light->worldTransform(); QMatrix4x4 m = mat * light->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1);//, dir0(light->dir0), dir1(light->dir1); QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1); //, dir0(light->dir0), dir1(light->dir1);
pos = m * pos; pos = m * pos;
dir = ((m * dir) - pos).normalized(); dir = ((m * dir) - pos).normalized();
float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f; float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f;
if (light->light_type == Light::Omni) if (light->light_type == Light::Omni) ang_start = ang_end = 180.;
ang_start = ang_end = 180.; // qDebug() << "light" << light->name() << ulightn << pos;
//qDebug() << "light" << light->name() << ulightn << pos;
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos); prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir); prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir);
prog->setUniformValue((ulightn + ".intensity").toLatin1().constData(), GLfloat(light->intensity)); prog->setUniformValue((ulightn + ".intensity").toLatin1().constData(), GLfloat(light->intensity));
@@ -249,8 +244,8 @@ void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn
prog->setUniformValue((ulightn + ".shadow").toLatin1().constData(), shadow); prog->setUniformValue((ulightn + ".shadow").toLatin1().constData(), shadow);
prog->setUniformValue((ulightn + ".shadowColor").toLatin1().constData(), shadow); prog->setUniformValue((ulightn + ".shadowColor").toLatin1().constData(), shadow);
prog->setUniformValue((ulightn + ".shadowMatrix").toLatin1().constData(), light->shadow_matrix); prog->setUniformValue((ulightn + ".shadowMatrix").toLatin1().constData(), light->shadow_matrix);
//qDebug() << light->shadow_matrix; // qDebug() << light->shadow_matrix;
//prog->setUniformValue((ulightn + ".shadowDir0").toLatin1().constData(), (mat * dir0)); // prog->setUniformValue((ulightn + ".shadowDir0").toLatin1().constData(), (mat * dir0));
//prog->setUniformValue((ulightn + ".shadowDir1").toLatin1().constData(), (mat * dir1)); // prog->setUniformValue((ulightn + ".shadowDir1").toLatin1().constData(), (mat * dir1));
//qDebug() << light->direction << light->dir0 << light->dir1; // qDebug() << light->direction << light->dir0 << light->dir1;
} }
+6 -2
View File
@@ -27,9 +27,13 @@ class Light;
QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file); QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file);
bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QString & dir = QString()); bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QString & dir = QString());
void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj = QMatrix4x4(), QMatrix4x4 prevview = QMatrix4x4()); void setUniformMatrices(QOpenGLShaderProgram * prog,
QMatrix4x4 proj,
QMatrix4x4 view,
QMatrix4x4 prevproj = QMatrix4x4(),
QMatrix4x4 prevview = QMatrix4x4());
void setUniformMap(QOpenGLShaderProgram * prog, const Map & map, int channel, int def_channel); void setUniformMap(QOpenGLShaderProgram * prog, const Map & map, int channel, int def_channel);
void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat); void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat);
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat, int shadow_start); void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light *> & lights, const QMatrix4x4 & mat, int shadow_start);
void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat = QMatrix4x4(), int shadow = 0); void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat = QMatrix4x4(), int shadow = 0);
#endif // GLSHADERS_H #endif // GLSHADERS_H
+3 -3
View File
@@ -20,14 +20,14 @@
bool GLTextureManager::loadTextures() { bool GLTextureManager::loadTextures() {
//glGenTextures(); // glGenTextures();
QFileInfoList fil; QFileInfoList fil;
Animation anim; Animation anim;
for (int i = 0; i < anim_pathes.size(); ++i) { for (int i = 0; i < anim_pathes.size(); ++i) {
anim.path = anim_pathes[i].second; anim.path = anim_pathes[i].second;
anim.bitmaps.clear(); anim.bitmaps.clear();
fil = QDir(anim_pathes[i].first).entryInfoList(QDir::Files, QDir::Name); fil = QDir(anim_pathes[i].first).entryInfoList(QDir::Files, QDir::Name);
foreach (const QFileInfo & fi, fil) { foreach(const QFileInfo & fi, fil) {
if (fi.baseName().indexOf(anim_pathes[i].second) < 0) continue; if (fi.baseName().indexOf(anim_pathes[i].second) < 0) continue;
anim.bitmaps << loadTexture(fi.filePath(), false); anim.bitmaps << loadTexture(fi.filePath(), false);
} }
@@ -35,7 +35,7 @@ bool GLTextureManager::loadTextures() {
anim_ids << QPair<QString, Animation>(anim_pathes[i].second, anim); anim_ids << QPair<QString, Animation>(anim_pathes[i].second, anim);
} }
anim_pathes.clear(); anim_pathes.clear();
foreach (const QString & i, tex_pathes) foreach(const QString & i, tex_pathes)
loadTexture(i, true); loadTexture(i, true);
tex_pathes.clear(); tex_pathes.clear();
return true; return true;

Some files were not shown because too many files have changed in this diff Show More