code format
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
#include "aboutwindow.h"
|
||||
#include "ui_aboutwindow.h"
|
||||
|
||||
#include "qad_types.h"
|
||||
#include "qpiconfig.h"
|
||||
#include "ui_aboutwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#if QT_VERSION < 0x050000
|
||||
@@ -23,44 +25,41 @@ AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWin
|
||||
#ifdef ANDROID
|
||||
QDialog::setStyleSheet("font: 12pt \"DejaVu Sans\";");
|
||||
#endif
|
||||
if (!stylesheet.isEmpty())
|
||||
QDialog::setStyleSheet(stylesheet);
|
||||
if (!stylesheet.isEmpty()) QDialog::setStyleSheet(stylesheet);
|
||||
ui->setupUi(this);
|
||||
ui->labelAuthors->setOpenExternalLinks(true);
|
||||
QImage logo_im = logo;
|
||||
if (logo_im.isNull())
|
||||
logo_im.load(":/icons/splash.png");
|
||||
if (logo_im.isNull()) logo_im.load(":/icons/splash.png");
|
||||
setWindowTitle(QApplication::applicationName() + " - " + tr("About"));
|
||||
QIcon ic = QApplication::windowIcon();
|
||||
if (ic.isNull()) {
|
||||
QWidgetList tlw = QApplication::topLevelWidgets();
|
||||
foreach (QWidget * w, tlw)
|
||||
foreach(QWidget * w, tlw)
|
||||
if (!w->windowIcon().isNull()) {
|
||||
ic = w->windowIcon();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ic.isNull())
|
||||
ic = QIcon(QPixmap::fromImage(logo_im));
|
||||
if (ic.isNull()) ic = QIcon(QPixmap::fromImage(logo_im));
|
||||
setWindowIcon(ic);
|
||||
QFormLayout * lay = (QFormLayout*)(ui->groupVersions->layout());
|
||||
foreach (SSPair p, versions) {
|
||||
QFormLayout * lay = (QFormLayout *)(ui->groupVersions->layout());
|
||||
foreach(SSPair p, versions) {
|
||||
lay->addRow(p.first, new QLabel(p.second));
|
||||
}
|
||||
lay = (QFormLayout*)(ui->groupBuild->layout());
|
||||
foreach (SSPair p, builds) {
|
||||
lay = (QFormLayout *)(ui->groupBuild->layout());
|
||||
foreach(SSPair p, builds) {
|
||||
lay->addRow(p.first, new QLabel(p.second));
|
||||
}
|
||||
ui->imageView->setPixmap(QPixmap::fromImage(logo_im));
|
||||
ui->labelComment->setText(comment);
|
||||
ui->labelComment->setOpenExternalLinks(true);
|
||||
ui->labelComment->setHidden(comment.isEmpty());
|
||||
//ui->labelArch->setText(QSysInfo::currentCpuArchitecture());
|
||||
// ui->labelArch->setText(QSysInfo::currentCpuArchitecture());
|
||||
ui->labelAuthors->setText(authors());
|
||||
connect(ui->buttonQt, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
|
||||
#ifdef MOBILE_VIEW
|
||||
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
|
||||
#ifdef MOBILE_VIEW
|
||||
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();
|
||||
# else
|
||||
QScreen * scr =
|
||||
# if QT_VERSION >= 0x050A00
|
||||
QApplication::screenAt(QCursor::pos());
|
||||
# else
|
||||
QApplication::screens()[0];
|
||||
# endif
|
||||
# if QT_VERSION >= 0x050A00
|
||||
QApplication::screenAt(QCursor::pos());
|
||||
# else
|
||||
QApplication::screens()[0];
|
||||
# endif
|
||||
if (scr) {
|
||||
r.setSize(scr->availableSize() / 2);
|
||||
r.moveCenter(scr->availableGeometry().center());
|
||||
}
|
||||
# endif
|
||||
if (r.isValid())
|
||||
setGeometry(r);
|
||||
if (r.isValid()) setGeometry(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -103,7 +101,7 @@ void AboutWindow::setLogo(QString path) {
|
||||
|
||||
void AboutWindow::addVersion(QString name, QString version) {
|
||||
if (!name.endsWith(":")) name.append(":");
|
||||
foreach (const SSPair & p, versions) {
|
||||
foreach(const SSPair & p, versions) {
|
||||
if (p.first == name) return;
|
||||
}
|
||||
version.prepend("<b>");
|
||||
@@ -117,7 +115,7 @@ void AboutWindow::addVersion(QString name, QString version) {
|
||||
|
||||
void AboutWindow::addBuildInfo(QString name, QString value) {
|
||||
if (!name.endsWith(":")) name.append(":");
|
||||
foreach (const SSPair & p, builds) {
|
||||
foreach(const SSPair & p, builds) {
|
||||
if (p.first == name) return;
|
||||
}
|
||||
builds << SSPair(name, value);
|
||||
@@ -143,13 +141,13 @@ void AboutWindow::show() {
|
||||
int AboutWindow::exec() {
|
||||
#ifdef MOBILE_VIEW
|
||||
showFullScreen();
|
||||
//setWindowState(Qt::WindowFullScreen);
|
||||
// setWindowState(Qt::WindowFullScreen);
|
||||
#endif
|
||||
return QDialog::exec();
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::changeEvent(QEvent *e) {
|
||||
void AboutWindow::changeEvent(QEvent * e) {
|
||||
QDialog::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
@@ -202,14 +200,13 @@ QString AboutWindow::authors() {
|
||||
} else {
|
||||
QPIConfig conf(&fc);
|
||||
QPIConfig::Branch br = conf.allLeaves();
|
||||
foreach (QPIConfig::Entry * e, br) {
|
||||
foreach(QPIConfig::Entry * e, br) {
|
||||
l = e->toString().trimmed();
|
||||
if (!l.contains("<")) continue;
|
||||
QString name, mail;
|
||||
name = l.left(l.indexOf("<"));
|
||||
mail = l.mid(name.size() + 1);
|
||||
if (mail.endsWith(">"))
|
||||
mail.chop(1);
|
||||
if (mail.endsWith(">")) mail.chop(1);
|
||||
name = name.trimmed();
|
||||
mail = mail.trimmed();
|
||||
addAuthor(ret, name, mail);
|
||||
@@ -217,4 +214,3 @@ QString AboutWindow::authors() {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ABOUTWINDOW_H
|
||||
#define ABOUTWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "qad_application_export.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#define ADD_ABOUT_VERSION(lib) \
|
||||
{ \
|
||||
if (lib##_VERSION_BUILD > 0) \
|
||||
|
||||
#define ADD_ABOUT_VERSION(lib) \
|
||||
{ \
|
||||
if (lib##_VERSION_BUILD > 0) \
|
||||
AboutWindow::addVersion(#lib, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \
|
||||
else \
|
||||
AboutWindow::addVersion(#lib, lib##_VERSION_NAME); \
|
||||
else \
|
||||
AboutWindow::addVersion(#lib, lib##_VERSION_NAME); \
|
||||
}
|
||||
#define ADD_ABOUT_VERSION_NAMED(lib, label) \
|
||||
{ \
|
||||
if (lib##_VERSION_BUILD > 0) \
|
||||
#define ADD_ABOUT_VERSION_NAMED(lib, label) \
|
||||
{ \
|
||||
if (lib##_VERSION_BUILD > 0) \
|
||||
AboutWindow::addVersion(label, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \
|
||||
else \
|
||||
AboutWindow::addVersion(label, lib##_VERSION_NAME); \
|
||||
else \
|
||||
AboutWindow::addVersion(label, lib##_VERSION_NAME); \
|
||||
}
|
||||
#define ADD_ABOUT_BUILD_INFO(lib) \
|
||||
AboutWindow::addBuildInfo("Arch", lib##_ARCH); \
|
||||
#define ADD_ABOUT_BUILD_INFO(lib) \
|
||||
AboutWindow::addBuildInfo("Arch", lib##_ARCH); \
|
||||
AboutWindow::addBuildInfo("Compiler", lib##_CXX_COMPILER); \
|
||||
AboutWindow::addBuildInfo("CMake", lib##_CMAKE_VERSION); \
|
||||
AboutWindow::addBuildInfo("CMake", lib##_CMAKE_VERSION); \
|
||||
AboutWindow::addBuildInfo("Date", lib##_BUILD_DATE);
|
||||
|
||||
namespace Ui {
|
||||
class AboutWindow;
|
||||
class AboutWindow;
|
||||
}
|
||||
|
||||
class QAD_APPLICATION_EXPORT AboutWindow: public QDialog
|
||||
{
|
||||
class QAD_APPLICATION_EXPORT AboutWindow: public QDialog {
|
||||
Q_OBJECT
|
||||
typedef QPair<QString, QString> SSPair;
|
||||
explicit AboutWindow(QWidget * parent = 0);
|
||||
~AboutWindow();
|
||||
public:
|
||||
|
||||
public:
|
||||
static void setLogo(QImage im);
|
||||
static void setLogo(QString path);
|
||||
static void addVersion(QString name, QString version);
|
||||
@@ -77,7 +77,6 @@ private:
|
||||
static QImage logo;
|
||||
static QVector<SSPair> versions, builds;
|
||||
static QString stylesheet, comment;
|
||||
|
||||
};
|
||||
|
||||
#endif // ABOUTWINDOW_H
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "edockwidget.h"
|
||||
|
||||
#include "qad_types.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QStyle>
|
||||
|
||||
@@ -18,14 +20,14 @@ void EDockWidget::setWindowTitle(const QString & title) {
|
||||
|
||||
|
||||
void EDockWidget::setWindowIcon(const QIcon & icon) {
|
||||
//#ifndef Q_OS_MACOS
|
||||
// #ifndef Q_OS_MACOS
|
||||
lbl_icon->setPixmap(icon.pixmap(QSize(256, 256)));
|
||||
QDockWidget::setWindowIcon(icon);
|
||||
if (!icon.isNull()) {
|
||||
lbl_icon->setScaledContents(true);
|
||||
lbl_icon->setFixedSize(preferredIconSize(1.5, this));
|
||||
}
|
||||
//#endif
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
||||
@@ -40,32 +42,33 @@ bool EDockWidget::event(QEvent * e) {
|
||||
void EDockWidget::init() {
|
||||
header = new QFrame();
|
||||
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->setSpacing(2);
|
||||
lbl_icon = new QLabel();
|
||||
//#ifndef Q_OS_MACOS
|
||||
// #ifndef Q_OS_MACOS
|
||||
QIcon wi = windowIcon();
|
||||
if (!wi.isNull()) {
|
||||
lbl_icon->setPixmap(wi.pixmap(QSize(256,256)));
|
||||
/*#if QT_VERSION >= 0x500000
|
||||
if (lbl_icon->pixmap())
|
||||
const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.);
|
||||
#endif*/
|
||||
//qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size();
|
||||
lbl_icon->setPixmap(wi.pixmap(QSize(256, 256)));
|
||||
/*#if QT_VERSION >= 0x500000
|
||||
if (lbl_icon->pixmap())
|
||||
const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.);
|
||||
#endif*/
|
||||
// qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size();
|
||||
lbl_icon->setScaledContents(true);
|
||||
}
|
||||
lbl_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
//#endif
|
||||
// #endif
|
||||
lbl_title = new QLabel(windowTitle());
|
||||
lbl_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
btn_dock = new QToolButton();
|
||||
//btn_dock->setIconSize(QSize(16, 16));
|
||||
// btn_dock->setIconSize(QSize(16, 16));
|
||||
btn_dock->setAutoRaise(true);
|
||||
btn_dock->setFocusPolicy(Qt::NoFocus);
|
||||
btn_dock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
btn_hide = new QToolButton();
|
||||
//btn_hide->setIconSize(QSize(16, 16));
|
||||
// btn_hide->setIconSize(QSize(16, 16));
|
||||
btn_hide->setAutoRaise(true);
|
||||
btn_hide->setFocusPolicy(Qt::NoFocus);
|
||||
btn_hide->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
@@ -83,8 +86,8 @@ void EDockWidget::init() {
|
||||
|
||||
void EDockWidget::updateStyle() {
|
||||
QSize icon_size = preferredIconSize(0.75, this);
|
||||
int bm = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
|
||||
QSize btn_size = icon_size;
|
||||
int bm = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
|
||||
QSize btn_size = icon_size;
|
||||
btn_size += QSize(bm, bm);
|
||||
btn_dock->setIcon(style()->standardIcon(QStyle::SP_TitleBarNormalButton));
|
||||
btn_dock->setIconSize(icon_size);
|
||||
|
||||
@@ -1,59 +1,68 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef 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 <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
|
||||
|
||||
public:
|
||||
explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(title, parent, flags) {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;}
|
||||
|
||||
explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags())
|
||||
: QDockWidget(title, parent, flags) {
|
||||
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 setWindowTitle(const QString & title);
|
||||
void setWindowIcon(const QIcon & icon);
|
||||
|
||||
|
||||
private:
|
||||
bool event(QEvent * e);
|
||||
void init();
|
||||
void updateStyle();
|
||||
|
||||
|
||||
QFrame * header;
|
||||
QLabel * lbl_title, * lbl_icon;
|
||||
QToolButton * btn_hide, * btn_dock;
|
||||
|
||||
QLabel *lbl_title, *lbl_icon;
|
||||
QToolButton *btn_hide, *btn_dock;
|
||||
|
||||
private slots:
|
||||
void dockClicked() {setFloating(!isFloating());}
|
||||
|
||||
void dockClicked() { setFloating(!isFloating()); }
|
||||
};
|
||||
|
||||
#endif // EDOCKWIDGET_H
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
#include "emainwindow.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
EMainWindow::EMainWindow(QWidget * parent): QMainWindow(parent), 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;
|
||||
EMainWindow::EMainWindow(QWidget * parent)
|
||||
: QMainWindow(parent)
|
||||
, 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);
|
||||
connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent()));
|
||||
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) {
|
||||
@@ -39,7 +44,7 @@ void EMainWindow::setRecentFiles(const QStringList & rl) {
|
||||
|
||||
QStringList EMainWindow::recentFiles() const {
|
||||
QStringList ret;
|
||||
foreach (QAction * a, actions_recent)
|
||||
foreach(QAction * a, actions_recent)
|
||||
ret << a->data().toString();
|
||||
return ret;
|
||||
}
|
||||
@@ -56,7 +61,7 @@ void EMainWindow::showEvent(QShowEvent * e) {
|
||||
initMenus();
|
||||
if (!first_show) return;
|
||||
first_show = false;
|
||||
QList<QDockWidget * > docks(findChildren<QDockWidget * >());
|
||||
QList<QDockWidget *> docks(findChildren<QDockWidget *>());
|
||||
for (QDockWidget * d: docks) {
|
||||
connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), 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) {
|
||||
if (!checkSave()) e->ignore();
|
||||
else saveSession();
|
||||
if (!checkSave())
|
||||
e->ignore();
|
||||
else
|
||||
saveSession();
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::eventFilter(QObject * o, QEvent * e) {
|
||||
if (tbars.contains((QTabBar*)o) && e->type() == QEvent::MouseButtonDblClick) {
|
||||
int tab = ((QTabBar*)o)->tabAt(((QMouseEvent * )e)->pos());
|
||||
if (tbars.contains((QTabBar *)o) && e->type() == QEvent::MouseButtonDblClick) {
|
||||
int tab = ((QTabBar *)o)->tabAt(((QMouseEvent *)e)->pos());
|
||||
if (tab >= 0) {
|
||||
QDockWidget * dock = (QDockWidget * )(((QTabBar*)o)->tabData(tab).toULongLong());
|
||||
QDockWidget * dock = (QDockWidget *)(((QTabBar *)o)->tabData(tab).toULongLong());
|
||||
if (dock) {
|
||||
dock->setFloating(true);
|
||||
return true;
|
||||
@@ -84,25 +91,25 @@ bool EMainWindow::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
}
|
||||
/*if (e->type() == QEvent::Show || e->type() == QEvent::Hide) {
|
||||
if (tdocks.contains((QDockWidget*)o)) {
|
||||
changedDock();
|
||||
}
|
||||
if (tdocks.contains((QDockWidget*)o)) {
|
||||
changedDock();
|
||||
}
|
||||
}*/
|
||||
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 (((QMouseEvent*)e)->button() == Qt::RightButton) {
|
||||
bool popup = tbars.contains((QTabBar*)o);
|
||||
if (tdocks.contains((QDockWidget*)o))
|
||||
popup = popup || ((QDockWidget*)o)->titleBarWidget()->geometry().contains(((QMouseEvent*)e)->pos());
|
||||
if (((QMouseEvent *)e)->button() == Qt::RightButton) {
|
||||
bool popup = tbars.contains((QTabBar *)o);
|
||||
if (tdocks.contains((QDockWidget *)o))
|
||||
popup = popup || ((QDockWidget *)o)->titleBarWidget()->geometry().contains(((QMouseEvent *)e)->pos());
|
||||
if (popup) {
|
||||
createPopupMenu()->popup(
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
((QMouseEvent*)e)->globalPos()
|
||||
((QMouseEvent *)e)->globalPos()
|
||||
#else
|
||||
((QMouseEvent*)e)->globalPosition().toPoint()
|
||||
((QMouseEvent *)e)->globalPosition().toPoint()
|
||||
#endif
|
||||
);
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -123,8 +130,7 @@ void EMainWindow::changeEvent(QEvent * e) {
|
||||
action_hide_all_docks.setText(tr("Hide all"));
|
||||
action_clear_recent->setText(tr("Clear recent list"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +143,9 @@ QMenu * EMainWindow::createPopupMenu() {
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
// Toolbars
|
||||
QList<QToolBar * > tools = findChildren<QToolBar * >();
|
||||
QList<QToolBar *> tools = findChildren<QToolBar *>();
|
||||
if (!tools.isEmpty()) {
|
||||
wa = new QWidgetAction(menuPopup);
|
||||
wa = new QWidgetAction(menuPopup);
|
||||
lbl = new QLabel();
|
||||
lbl->setFrameShape(QFrame::StyledPanel);
|
||||
lbl->setFrameShadow(QFrame::Sunken);
|
||||
@@ -162,9 +168,9 @@ QMenu * EMainWindow::createPopupMenu() {
|
||||
menuPopup->addAction(&action_hide_all_tools);
|
||||
}
|
||||
// Docks
|
||||
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
|
||||
QList<QDockWidget *> docks = findChildren<QDockWidget *>();
|
||||
if (!docks.isEmpty()) {
|
||||
wa = new QWidgetAction(menuPopup);
|
||||
wa = new QWidgetAction(menuPopup);
|
||||
lbl = new QLabel();
|
||||
lbl->setFrameShape(QFrame::StyledPanel);
|
||||
lbl->setFrameShadow(QFrame::Sunken);
|
||||
@@ -193,7 +199,7 @@ QMenu * EMainWindow::createPopupMenu() {
|
||||
void EMainWindow::addToRecent(const QString & path) {
|
||||
if (path.isEmpty()) return;
|
||||
QFileInfo fi(path);
|
||||
QString fp = fi.absoluteFilePath();
|
||||
QString fp = fi.absoluteFilePath();
|
||||
bool insert = true;
|
||||
for (int i = 0; i < actions_recent.size(); ++i)
|
||||
if (actions_recent[i]->data().toString() == fp) {
|
||||
@@ -232,7 +238,7 @@ void EMainWindow::initMenus() {
|
||||
action_show_all_docks.disconnect();
|
||||
action_hide_all_docks.disconnect();
|
||||
|
||||
QList<QToolBar * > tools = findChildren<QToolBar * >();
|
||||
QList<QToolBar *> tools = findChildren<QToolBar *>();
|
||||
for (QToolBar * i: tools) {
|
||||
if (i->property("ribbon").toBool()) continue;
|
||||
i->toggleViewAction()->setIcon(i->windowIcon());
|
||||
@@ -240,7 +246,7 @@ void EMainWindow::initMenus() {
|
||||
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) {
|
||||
if (i->property("ribbon").toBool()) continue;
|
||||
i->toggleViewAction()->setIcon(i->windowIcon());
|
||||
@@ -248,7 +254,7 @@ void EMainWindow::initMenus() {
|
||||
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)
|
||||
i->setIconVisibleInMenu(true);
|
||||
addActions(actions);
|
||||
@@ -256,8 +262,8 @@ void EMainWindow::initMenus() {
|
||||
|
||||
|
||||
void EMainWindow::initSession() {
|
||||
connect(&session, SIGNAL(loading(QPIConfig & )), this, SLOT(sessionLoading(QPIConfig & )));
|
||||
connect(&session, SIGNAL(saving(QPIConfig & )), this, SLOT(sessionSaving(QPIConfig & )));
|
||||
connect(&session, SIGNAL(loading(QPIConfig &)), this, SLOT(sessionLoading(QPIConfig &)));
|
||||
connect(&session, SIGNAL(saving(QPIConfig &)), this, SLOT(sessionSaving(QPIConfig &)));
|
||||
}
|
||||
|
||||
|
||||
@@ -279,18 +285,18 @@ bool EMainWindow::checkSave() {
|
||||
|
||||
void EMainWindow::changedDock() {
|
||||
if (isHidden()) return;
|
||||
QSet<QDockWidget * > invalid_tab_docks;
|
||||
QList<QTabBar * > tabs(findChildren<QTabBar * >());
|
||||
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
|
||||
QRect geom = geometry();
|
||||
//qDebug() << "### change" << docks.size() << tabs.size();
|
||||
QSet<QDockWidget *> invalid_tab_docks;
|
||||
QList<QTabBar *> tabs(findChildren<QTabBar *>());
|
||||
QList<QDockWidget *> docks = findChildren<QDockWidget *>();
|
||||
QRect geom = geometry();
|
||||
// qDebug() << "### change" << docks.size() << tabs.size();
|
||||
for (QTabBar * t: tabs) {
|
||||
if (!t->objectName().isEmpty() || t->isHidden()) continue;
|
||||
if (!tbars.contains(t)) {
|
||||
//qDebug() << "add tab" << t;
|
||||
// qDebug() << "add tab" << t;
|
||||
tbars << t;
|
||||
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);
|
||||
#ifndef Q_OS_MACOS
|
||||
t->setIconSize(dockTabsIconSize());
|
||||
@@ -298,12 +304,11 @@ void EMainWindow::changedDock() {
|
||||
t->setTabsClosable(true);
|
||||
}
|
||||
for (int i = 0; i < t->count(); ++i) {
|
||||
QDockWidget * dock = (QDockWidget * )t->tabData(i).toULongLong();
|
||||
//qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock;
|
||||
QDockWidget * dock = (QDockWidget *)t->tabData(i).toULongLong();
|
||||
// qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock;
|
||||
if (!dock) continue;
|
||||
if (!docks.contains(dock)) continue;
|
||||
if (!geom.intersects(t->geometry()))
|
||||
invalid_tab_docks << dock;
|
||||
if (!geom.intersects(t->geometry())) invalid_tab_docks << dock;
|
||||
#ifndef Q_OS_MACOS
|
||||
QSize is = dockTabsIconSize();
|
||||
if (t->iconSize() != is) t->setIconSize(is);
|
||||
@@ -318,24 +323,24 @@ void EMainWindow::changedDock() {
|
||||
if (!d->property("__titleWidget").isValid()) {
|
||||
d->setProperty("__titleWidget", qulonglong(ctb));
|
||||
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->layout()->setContentsMargins(m, m, 0, 0);
|
||||
d->setProperty("__titleEmptyWidget", qulonglong(ntb));
|
||||
}
|
||||
if (!tdocks.contains(d)) {
|
||||
//qDebug() << "add dock" << d;
|
||||
// qDebug() << "add dock" << 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);
|
||||
}
|
||||
//qDebug() << d->windowTitle() << tabifiedDockWidgets(d);
|
||||
// qDebug() << d->windowTitle() << tabifiedDockWidgets(d);
|
||||
if (tabifiedDockWidgets(d).isEmpty() || invalid_tab_docks.contains(d)) {
|
||||
if (d->titleBarWidget() != (QWidget * )(d->property("__titleWidget").toULongLong()))
|
||||
d->setTitleBarWidget((QWidget * )(d->property("__titleWidget").toULongLong()));
|
||||
if (d->titleBarWidget() != (QWidget *)(d->property("__titleWidget").toULongLong()))
|
||||
d->setTitleBarWidget((QWidget *)(d->property("__titleWidget").toULongLong()));
|
||||
} else {
|
||||
if (d->titleBarWidget() != (QWidget * )(d->property("__titleEmptyWidget").toULongLong())) {
|
||||
d->setTitleBarWidget((QWidget * )(d->property("__titleEmptyWidget").toULongLong()));
|
||||
if (d->titleBarWidget() != (QWidget *)(d->property("__titleEmptyWidget").toULongLong())) {
|
||||
d->setTitleBarWidget((QWidget *)(d->property("__titleEmptyWidget").toULongLong()));
|
||||
d->layout()->setContentsMargins(0, 20, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -344,20 +349,19 @@ void EMainWindow::changedDock() {
|
||||
|
||||
|
||||
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;
|
||||
dock->close();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::recentTriggered() {
|
||||
QAction * a = qobject_cast<QAction * >(sender());
|
||||
QAction * a = qobject_cast<QAction *>(sender());
|
||||
if (!a) return;
|
||||
QString path = a->data().toString();
|
||||
if (path.isEmpty()) return;
|
||||
if (!checkSave()) return;
|
||||
if (load(path))
|
||||
addToRecent(path);
|
||||
if (load(path)) addToRecent(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -379,31 +383,32 @@ void EMainWindow::openFile() {
|
||||
if (!checkSave()) return;
|
||||
QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter());
|
||||
if (ret.isEmpty()) return;
|
||||
if (load(ret))
|
||||
addToRecent(ret);
|
||||
if (load(ret)) addToRecent(ret);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::openFiles() {
|
||||
if (!checkSave()) return;
|
||||
QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter());
|
||||
foreach (QString s, ret) {
|
||||
if (load(s))
|
||||
addToRecent(s);
|
||||
foreach(QString s, ret) {
|
||||
if (load(s)) addToRecent(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::saveFile(bool 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::Save) return saveFile();
|
||||
return true;
|
||||
}
|
||||
if (file_name.isEmpty()) return saveAsFile();
|
||||
if (save(file_name))
|
||||
addToRecent(file_name);
|
||||
if (save(file_name)) addToRecent(file_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -411,8 +416,7 @@ bool EMainWindow::saveFile(bool ask) {
|
||||
bool EMainWindow::saveAsFile() {
|
||||
QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter());
|
||||
if (ret.isEmpty()) return false;
|
||||
if (save(ret))
|
||||
addToRecent(ret);
|
||||
if (save(ret)) addToRecent(ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef 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 <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 {
|
||||
Q_OBJECT
|
||||
|
||||
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;
|
||||
connect(this, SIGNAL(triggered()), this, SLOT(triggered()));
|
||||
connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
|
||||
@@ -50,16 +52,17 @@ public:
|
||||
connect(this, SIGNAL(hovered()), this, SLOT(hovered()));
|
||||
}
|
||||
public slots:
|
||||
void show() {setVisible(true);}
|
||||
void hide() {setVisible(false);}
|
||||
void setCheckedTrue() {setChecked(true);}
|
||||
void setCheckedFalse() {setChecked(false);}
|
||||
void show() { setVisible(true); }
|
||||
void hide() { setVisible(false); }
|
||||
void setCheckedTrue() { setChecked(true); }
|
||||
void setCheckedFalse() { setChecked(false); }
|
||||
|
||||
private:
|
||||
int index;
|
||||
private slots:
|
||||
void triggered() {emit itriggered(this, index);}
|
||||
void toggled(bool t) {emit itoggled(t, this, index);}
|
||||
void hovered() {emit ihovered(this);}
|
||||
void triggered() { emit itriggered(this, index); }
|
||||
void toggled(bool t) { emit itoggled(t, this, index); }
|
||||
void hovered() { emit ihovered(this); }
|
||||
signals:
|
||||
void itriggered(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_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems)
|
||||
|
||||
public:
|
||||
EMainWindow(QWidget * parent = 0);
|
||||
~EMainWindow();
|
||||
|
||||
virtual void reset(bool full = false) {}
|
||||
virtual bool load(const QString & path) {return true;}
|
||||
virtual bool save(const QString & path) {return true;}
|
||||
virtual bool load(const QString & path) { return true; }
|
||||
virtual bool save(const QString & path) { return true; }
|
||||
|
||||
void addSeparator() {}
|
||||
void setRecentFiles(const QStringList & rl);
|
||||
QStringList recentFiles() const;
|
||||
void setRecentMenu(QMenu * m);
|
||||
|
||||
int maxRecentItems() const {return max_recent;}
|
||||
int maxRecentItems() const { return max_recent; }
|
||||
|
||||
protected:
|
||||
// Qt`s overloaded
|
||||
void showEvent(QShowEvent * );
|
||||
void closeEvent(QCloseEvent * );
|
||||
void showEvent(QShowEvent *);
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void changeEvent(QEvent * e);
|
||||
QMenu * createPopupMenu();
|
||||
void addToRecent(const QString & path);
|
||||
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 loadSession();
|
||||
virtual void savingSession(QPIConfig & conf) {}
|
||||
virtual void loadingSession(QPIConfig & conf) {}
|
||||
virtual QSize dockTabsIconSize() const {return iconSize();}
|
||||
virtual QString loadFilter() {return "All files(*)";}
|
||||
virtual QString saveFilter() {return "All files(*)";}
|
||||
virtual QSize dockTabsIconSize() const { return iconSize(); }
|
||||
virtual QString loadFilter() { return "All files(*)"; }
|
||||
virtual QString saveFilter() { return "All files(*)"; }
|
||||
|
||||
bool checkSave();
|
||||
void setChanged(bool yes = true) {isChanged = yes; setWindowModified(yes);}
|
||||
void setChanged(bool yes = true) {
|
||||
isChanged = yes;
|
||||
setWindowModified(yes);
|
||||
}
|
||||
|
||||
void initMenus();
|
||||
void initSession();
|
||||
|
||||
QAction action_show_all_tools, action_hide_all_tools, action_show_all_docks, action_hide_all_docks;
|
||||
QString file_name;
|
||||
QList<QTabBar * > tbars;
|
||||
QList<QDockWidget * > tdocks;
|
||||
QList<QAction * > actions_recent;
|
||||
QList<QTabBar *> tbars;
|
||||
QList<QDockWidget *> tdocks;
|
||||
QList<QAction *> actions_recent;
|
||||
QAction * action_clear_recent;
|
||||
QMenu * menu_recent;
|
||||
SessionManager session;
|
||||
@@ -124,24 +135,23 @@ protected:
|
||||
|
||||
private slots:
|
||||
void changedDock();
|
||||
void sessionLoading(QPIConfig & conf) {loadingSession(conf);}
|
||||
void sessionSaving(QPIConfig & conf) {savingSession(conf);}
|
||||
void sessionLoading(QPIConfig & conf) { loadingSession(conf); }
|
||||
void sessionSaving(QPIConfig & conf) { savingSession(conf); }
|
||||
void closeDock(int index);
|
||||
void recentTriggered();
|
||||
|
||||
public slots:
|
||||
void setMaxRecentItems(int mr);
|
||||
void changed() {setChanged(true);}
|
||||
void changed() { setChanged(true); }
|
||||
void newFile();
|
||||
void openFile();
|
||||
void openFiles();
|
||||
bool saveFile(bool ask);
|
||||
bool saveFile() {return saveFile(false);}
|
||||
bool saveFile() { return saveFile(false); }
|
||||
bool saveAsFile();
|
||||
void clearRecent();
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "etabwidget.h"
|
||||
|
||||
|
||||
ETabWidget::ETabWidget(QWidget* parent): QTabWidget(parent) {
|
||||
ETabWidget::ETabWidget(QWidget * parent): QTabWidget(parent) {
|
||||
tabBar()->setMouseTracking(true);
|
||||
tabBar()->installEventFilter(this);
|
||||
}
|
||||
@@ -9,26 +9,27 @@ ETabWidget::ETabWidget(QWidget* parent): QTabWidget(parent) {
|
||||
|
||||
void ETabWidget::retranslate() {
|
||||
for (int i = 0; i < buttons.size(); ++i)
|
||||
buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);
|
||||
QList<QToolButton * > bl = findChildren<QToolButton * >();
|
||||
foreach (QToolButton * i, bl)
|
||||
i->setToolTip(QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/));
|
||||
buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/);
|
||||
QList<QToolButton *> bl = findChildren<QToolButton *>();
|
||||
foreach(QToolButton * i, bl)
|
||||
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 ret = QTabWidget::addTab(page, icon, label);
|
||||
int ret = QTabWidget::addTab(page, icon, label);
|
||||
QWidget * w = new QWidget();
|
||||
w->setLayout(new QBoxLayout(QBoxLayout::RightToLeft));
|
||||
w->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
w->layout()->setSpacing(2);
|
||||
QToolButton * b;
|
||||
foreach (const TabButton & i, buttons) {
|
||||
foreach(const TabButton & i, buttons) {
|
||||
b = new QToolButton();
|
||||
b->setToolTip(i.toolTip);
|
||||
b->setIconSize(QSize(16, 16));
|
||||
b->setIcon(i.icon);
|
||||
//b->setFlat(true);
|
||||
// b->setFlat(true);
|
||||
b->setProperty("sourceToolTip", i.toolTip);
|
||||
b->setProperty("buttonRole", i.role);
|
||||
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) {
|
||||
QList<QToolButton * > bl = findChildren<QToolButton * >();
|
||||
foreach (QToolButton * i, bl)
|
||||
if (i->property("buttonRole").toInt() == role)
|
||||
i->setVisible(yes);
|
||||
QList<QToolButton *> bl = findChildren<QToolButton *>();
|
||||
foreach(QToolButton * i, bl)
|
||||
if (i->property("buttonRole").toInt() == role) i->setVisible(yes);
|
||||
QWidget * w;
|
||||
for (int i = 0; i < buttons.size(); ++i) {
|
||||
if (buttons[i].role == role)
|
||||
buttons[i].visible = yes;
|
||||
if (buttons[i].role == role) buttons[i].visible = yes;
|
||||
w = tabBar()->tabButton(i, QTabBar::RightSide);
|
||||
if (w != 0) w->adjustSize();
|
||||
}
|
||||
@@ -57,19 +56,19 @@ void ETabWidget::setButtonVisible(int role, bool yes) {
|
||||
|
||||
/*
|
||||
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(0)->widget()));
|
||||
QTabWidget::removeTab(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(0)->widget()));
|
||||
QTabWidget::removeTab(index);
|
||||
}
|
||||
*/
|
||||
|
||||
bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
|
||||
static int prev = -1;
|
||||
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);
|
||||
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) {
|
||||
prev = i;
|
||||
emit tabHovered(i);
|
||||
@@ -94,17 +93,14 @@ bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
|
||||
void ETabWidget::changeEvent(QEvent * e) {
|
||||
QTabWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
retranslate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: retranslate(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ETabWidget::buttonClicked() {
|
||||
QToolButton * s = qobject_cast<QToolButton * >(sender());
|
||||
QToolButton * s = qobject_cast<QToolButton *>(sender());
|
||||
if (s == 0) return;
|
||||
QWidget * pw = s->parentWidget();
|
||||
if (pw == 0) return;
|
||||
|
||||
@@ -1,75 +1,81 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef 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 <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
|
||||
|
||||
public:
|
||||
explicit ETabWidget(QWidget * parent = 0);
|
||||
|
||||
|
||||
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 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);
|
||||
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void tabInserted(int) {emit countChanged();}
|
||||
void tabRemoved(int) {emit countChanged();}
|
||||
void tabInserted(int) { emit countChanged(); }
|
||||
void tabRemoved(int) { emit countChanged(); }
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
|
||||
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;
|
||||
bool visible;
|
||||
QIcon icon;
|
||||
QString srcToolTip;
|
||||
QString toolTip;
|
||||
};
|
||||
|
||||
|
||||
QList<TabButton> buttons;
|
||||
|
||||
|
||||
private slots:
|
||||
void buttonClicked();
|
||||
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void tabHovered(int tab);
|
||||
void tabButtonClicked(int tab, int role);
|
||||
|
||||
};
|
||||
|
||||
#endif // ETABWIDGET_H
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
#include "historyview.h"
|
||||
#include <QScrollBar>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
|
||||
HistoryView::HistoryView(QWidget* parent): QListWidget(parent) {
|
||||
HistoryView::HistoryView(QWidget * parent): QListWidget(parent) {
|
||||
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
setEditTriggers(NoEditTriggers);
|
||||
active_ = true;
|
||||
active_ = true;
|
||||
duplicates_ = false;
|
||||
index = 0;
|
||||
index = 0;
|
||||
setLimit(32);
|
||||
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()));
|
||||
registerAction(-1, tr("History cleared"), QImage(":/icons/clear-history.png"));
|
||||
}
|
||||
|
||||
|
||||
HistoryView::~HistoryView() {
|
||||
}
|
||||
HistoryView::~HistoryView() {}
|
||||
|
||||
|
||||
QByteArray HistoryView::current() const {
|
||||
@@ -37,8 +37,7 @@ void HistoryView::addEntry(int action, int count_, const QString & suffix) {
|
||||
QByteArray ba;
|
||||
emit commandRequest(ba);
|
||||
if (!duplicates_)
|
||||
if (current() == ba)
|
||||
return;
|
||||
if (current() == ba) return;
|
||||
int cnt = count();
|
||||
for (int i = index; i < cnt; ++i)
|
||||
if (i >= 0) delete takeItem(index);
|
||||
@@ -94,11 +93,8 @@ void HistoryView::checkLimit() {
|
||||
void HistoryView::changeEvent(QEvent * e) {
|
||||
QListWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
actions_[-1].text = tr("History cleared");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: actions_[-1].text = tr("History cleared"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +103,7 @@ void HistoryView::itemClicked(QListWidgetItem * item) {
|
||||
if (!active_) return;
|
||||
if (index == row(item) + 1) return;
|
||||
index = row(item) + 1;
|
||||
//qDebug() << actions[index - 1].command;
|
||||
// qDebug() << actions[index - 1].command;
|
||||
emit commandExecute(history_[index - 1].command);
|
||||
emit changed();
|
||||
itemSelectionChanged();
|
||||
@@ -117,7 +113,7 @@ void HistoryView::itemClicked(QListWidgetItem * item) {
|
||||
void HistoryView::itemSelectionChanged() {
|
||||
if (!active_) return;
|
||||
if (index < 1) index = 1;
|
||||
//qDebug() << "changed" << count();
|
||||
// qDebug() << "changed" << count();
|
||||
int vpos = verticalScrollBar()->value();
|
||||
blockSignals(true);
|
||||
setCurrentItem(item(index - 1));
|
||||
|
||||
@@ -1,50 +1,51 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HISTORYVIEW_H
|
||||
#define HISTORYVIEW_H
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QDebug>
|
||||
#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_PROPERTY(bool active READ isActive WRITE setActive)
|
||||
Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled)
|
||||
Q_PROPERTY(int limit READ limit WRITE setLimit)
|
||||
Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor)
|
||||
|
||||
public:
|
||||
explicit HistoryView(QWidget * parent = 0);
|
||||
~HistoryView();
|
||||
|
||||
bool isActive() const {return active_;}
|
||||
bool isDuplicatesEnabled() const {return duplicates_;}
|
||||
int limit() const {return limit_;}
|
||||
QColor historyColor() const {return color_;}
|
||||
|
||||
bool isActive() const { return active_; }
|
||||
bool isDuplicatesEnabled() const { return duplicates_; }
|
||||
int limit() const { return limit_; }
|
||||
QColor historyColor() const { return color_; }
|
||||
QByteArray current() const;
|
||||
|
||||
|
||||
void addEntry(int action, int count = 0, const QString & suffix = QString());
|
||||
void registerAction(int action, const QString & text, const QImage & icon = QImage());
|
||||
|
||||
|
||||
private:
|
||||
struct QAD_APPLICATION_EXPORT Action {
|
||||
Action(int i = -1, const QString & t = QString(), const QImage & c = QImage()): id(i), text(t) {
|
||||
@@ -63,31 +64,31 @@ private:
|
||||
int action;
|
||||
QByteArray command;
|
||||
};
|
||||
|
||||
|
||||
void checkLimit();
|
||||
void changeEvent(QEvent * e);
|
||||
QString actionText(int action, int count_);
|
||||
|
||||
|
||||
QMap<int, Action> actions_;
|
||||
QVector<Entry> history_;
|
||||
QColor color_;
|
||||
bool active_, duplicates_;
|
||||
int index, limit_;
|
||||
|
||||
|
||||
public slots:
|
||||
void setActive(bool yes) {active_ = yes;}
|
||||
void setDuplicatesEnabled(bool yes) {duplicates_ = yes;}
|
||||
void setActive(bool yes) { active_ = yes; }
|
||||
void setDuplicatesEnabled(bool yes) { duplicates_ = yes; }
|
||||
void setLimit(int l);
|
||||
void setHistoryColor(const QColor & c);
|
||||
void clear(bool silent);
|
||||
void clear() {clear(false);}
|
||||
void clear() { clear(false); }
|
||||
void undo();
|
||||
void redo();
|
||||
|
||||
|
||||
private slots:
|
||||
void itemClicked(QListWidgetItem * item);
|
||||
void itemSelectionChanged();
|
||||
|
||||
|
||||
signals:
|
||||
void undoAvailable(bool);
|
||||
void redoAvailable(bool);
|
||||
@@ -95,7 +96,6 @@ signals:
|
||||
void commandRequest(QByteArray & s);
|
||||
void commandExecute(const QByteArray & s);
|
||||
void changed();
|
||||
|
||||
};
|
||||
|
||||
#endif // HISTORYVIEW_H
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#include "logview.h"
|
||||
#include "ui_logview.h"
|
||||
#include "qad_types.h"
|
||||
|
||||
#include "ecombobox.h"
|
||||
#include <QTextDocument>
|
||||
#include "qad_types.h"
|
||||
#include "ui_logview.h"
|
||||
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QTextEdit>
|
||||
#include <QTextBlock>
|
||||
#include <QScrollBar>
|
||||
#include <QPixmap>
|
||||
#include <QEvent>
|
||||
#include <QPixmap>
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
#include <QTextBlockUserData>
|
||||
#include <QTextDocument>
|
||||
#include <QTextEdit>
|
||||
|
||||
|
||||
class TextBlockData: public QTextBlockUserData {
|
||||
@@ -19,8 +21,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
LogView::Category::Category() {
|
||||
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,
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
|
||||
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
|
||||
#else
|
||||
Qt::CaseInsensitive
|
||||
Qt::CaseInsensitive
|
||||
#endif
|
||||
);
|
||||
);
|
||||
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;
|
||||
removeCategory(regexp);
|
||||
Category c;
|
||||
c.regexp = regexp;
|
||||
c.label = label;
|
||||
c.image = icon;
|
||||
c.regexp = regexp;
|
||||
c.label = label;
|
||||
c.image = icon;
|
||||
c.text_brush = text_brush;
|
||||
c.background = background;
|
||||
c.bold = bold;
|
||||
c.makeIcon(iconImageSize(), preferredIconSize(1., this)
|
||||
c.bold = bold;
|
||||
c.makeIcon(iconImageSize(),
|
||||
preferredIconSize(1., this)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
, devicePixelRatioF()
|
||||
,
|
||||
devicePixelRatioF()
|
||||
#endif
|
||||
);
|
||||
);
|
||||
categories.append(c);
|
||||
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) {
|
||||
QRegularExpression regexp(keyword,
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
|
||||
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
|
||||
#else
|
||||
Qt::CaseInsensitive
|
||||
Qt::CaseInsensitive
|
||||
#endif
|
||||
);
|
||||
);
|
||||
removeCategory(regexp);
|
||||
}
|
||||
|
||||
@@ -153,13 +165,14 @@ void LogView::removeCategory(QRegularExpression regexp) {
|
||||
c.regexp = regexp;
|
||||
categories.removeAll(c);
|
||||
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)
|
||||
toRegularExpression()
|
||||
toRegularExpression()
|
||||
#else
|
||||
toRegExp()
|
||||
toRegExp()
|
||||
#endif
|
||||
.pattern() == regexp.pattern()) {
|
||||
.pattern() == regexp.pattern()) {
|
||||
ui->comboCategory->removeItem(i);
|
||||
--i;
|
||||
}
|
||||
@@ -188,16 +201,13 @@ void LogView::addText(const QString & text, const QString & keyword, bool insert
|
||||
QStringList sl = text.split("\n");
|
||||
tc.movePosition(QTextCursor::End);
|
||||
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) {
|
||||
tc.insertText(sl[i]);
|
||||
if (!keyword.isEmpty())
|
||||
tc.block().setUserData(new TextBlockData(keyword));
|
||||
if ((i < sl.size() - 1) || insert_newline)
|
||||
newLine(keyword);
|
||||
if (!keyword.isEmpty()) tc.block().setUserData(new TextBlockData(keyword));
|
||||
if ((i < sl.size() - 1) || insert_newline) newLine(keyword);
|
||||
}
|
||||
if (at_end)
|
||||
scrollToBottom();
|
||||
if (at_end) scrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
@@ -215,12 +225,14 @@ void LogView::changeEvent(QEvent * e) {
|
||||
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
|
||||
QSize is = iconImageSize(), is_i = preferredIconSize(1., this);
|
||||
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)
|
||||
, devicePixelRatioF()
|
||||
,
|
||||
devicePixelRatioF()
|
||||
#endif
|
||||
);
|
||||
} break;
|
||||
);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -232,19 +244,18 @@ void LogView::newLine(const QString & keyword) {
|
||||
tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
|
||||
QString line = tc.selectedText();
|
||||
QImage icon;
|
||||
foreach (const Category & c, categories) {
|
||||
foreach(const Category & c, categories) {
|
||||
bool matched = false;
|
||||
if (keyword.isEmpty()) matched = line.contains(c.regexp);
|
||||
else matched = (keyword == c.regexp.pattern());
|
||||
if (keyword.isEmpty())
|
||||
matched = line.contains(c.regexp);
|
||||
else
|
||||
matched = (keyword == c.regexp.pattern());
|
||||
if (matched) {
|
||||
QTextCharFormat cf = def_cf;
|
||||
QTextCharFormat cf = def_cf;
|
||||
QTextBlockFormat bf = def_bf;
|
||||
if (c.text_brush != Qt::NoBrush)
|
||||
cf.setForeground(c.text_brush);
|
||||
if (c.background != Qt::NoBrush)
|
||||
bf.setBackground(c.background);
|
||||
if (c.bold)
|
||||
cf.setFontWeight(QFont::Bold);
|
||||
if (c.text_brush != Qt::NoBrush) cf.setForeground(c.text_brush);
|
||||
if (c.background != Qt::NoBrush) bf.setBackground(c.background);
|
||||
if (c.bold) cf.setFontWeight(QFont::Bold);
|
||||
tc.setCharFormat(cf);
|
||||
tc.setBlockFormat(bf);
|
||||
icon = c.icon_image;
|
||||
@@ -257,13 +268,12 @@ void LogView::newLine(const QString & keyword) {
|
||||
}
|
||||
QRegularExpression regexp =
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
ui->comboCategory->currentData().toRegularExpression();
|
||||
ui->comboCategory->currentData().toRegularExpression();
|
||||
#else
|
||||
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
|
||||
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
|
||||
#endif
|
||||
QString fs = ui->lineEdit->text();
|
||||
if (isFilterVisible())
|
||||
filterBlock(tc.block(), fs, regexp);
|
||||
if (isFilterVisible()) filterBlock(tc.block(), fs, regexp);
|
||||
tc.movePosition(QTextCursor::End);
|
||||
tc.setCharFormat(def_cf);
|
||||
tc.insertBlock();
|
||||
@@ -278,15 +288,14 @@ QSize LogView::iconImageSize() {
|
||||
|
||||
|
||||
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();
|
||||
if (!line.isEmpty()) {
|
||||
if (line[0] == QChar::ObjectReplacementCharacter)
|
||||
line.remove(0, 1);
|
||||
if (line[0] == QChar::ObjectReplacementCharacter) line.remove(0, 1);
|
||||
}
|
||||
if (regexp.isValid() && !regexp.pattern().isEmpty()) {
|
||||
QString kw;
|
||||
TextBlockData * bd = (TextBlockData*)block.userData();
|
||||
TextBlockData * bd = (TextBlockData *)block.userData();
|
||||
if (bd) kw = bd->keyword;
|
||||
if (!kw.isEmpty())
|
||||
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);
|
||||
block.setVisible(vis);
|
||||
//qDebug() << "filterBlock" << line << vis;
|
||||
//if (vis != pvis)
|
||||
// qDebug() << "filterBlock" << line << vis;
|
||||
// if (vis != pvis)
|
||||
// ;//ui->textEdit->document()->mar
|
||||
}
|
||||
|
||||
@@ -325,16 +334,16 @@ void LogView::scrollToBottom() {
|
||||
|
||||
void LogView::filter() {
|
||||
QTextDocument * doc = ui->textEdit->document();
|
||||
int bc = doc->blockCount();
|
||||
int bc = doc->blockCount();
|
||||
QRegularExpression regexp;
|
||||
QString fs;
|
||||
if (isFilterVisible()) {
|
||||
regexp =
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
ui->comboCategory->currentData().toRegularExpression();
|
||||
#else
|
||||
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
|
||||
#endif
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
ui->comboCategory->currentData().toRegularExpression();
|
||||
#else
|
||||
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
|
||||
#endif
|
||||
fs = ui->lineEdit->text();
|
||||
}
|
||||
QTextBlock bl;
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOGVIEW_H
|
||||
#define LOGVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QIcon>
|
||||
#include <QImage>
|
||||
#include <QTextBlockFormat>
|
||||
#include <QWidget>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
# include <QRegularExpression>
|
||||
#else
|
||||
# include <QRegExp>
|
||||
typedef QRegExp QRegularExpression;
|
||||
typedef QRegExp QRegularExpression;
|
||||
#endif
|
||||
#include "qad_application_export.h"
|
||||
|
||||
@@ -37,19 +37,19 @@ class QTextBlock;
|
||||
class QAction;
|
||||
|
||||
namespace Ui {
|
||||
class LogView;
|
||||
class LogView;
|
||||
}
|
||||
|
||||
class QAD_APPLICATION_EXPORT LogView: public QWidget
|
||||
{
|
||||
class QAD_APPLICATION_EXPORT LogView: public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool filterVisible READ isFilterVisible WRITE setFilterVisible)
|
||||
Q_PROPERTY(int linesLimit READ linesLimit WRITE setLinesLimit)
|
||||
Q_PROPERTY(QFont logFont READ logFont WRITE setLogFont)
|
||||
|
||||
public:
|
||||
explicit LogView(QWidget * parent = 0);
|
||||
~LogView();
|
||||
|
||||
|
||||
const QTextEdit * textEdit() const;
|
||||
void setLogFont(QFont f);
|
||||
QFont logFont() const;
|
||||
@@ -58,25 +58,25 @@ public:
|
||||
int linesLimit() const;
|
||||
|
||||
void registerCategory(const QString & label,
|
||||
QString keyword = QString(),
|
||||
const QImage & icon = QImage(),
|
||||
QBrush text_brush = Qt::NoBrush,
|
||||
QBrush background = Qt::NoBrush,
|
||||
bool bold = false);
|
||||
QString keyword = QString(),
|
||||
const QImage & icon = QImage(),
|
||||
QBrush text_brush = Qt::NoBrush,
|
||||
QBrush background = Qt::NoBrush,
|
||||
bool bold = false);
|
||||
|
||||
void registerCategory(const QString & label,
|
||||
QRegularExpression regexp,
|
||||
const QImage & icon = QImage(),
|
||||
QBrush text_brush = Qt::NoBrush,
|
||||
QBrush background = Qt::NoBrush,
|
||||
bool bold = false);
|
||||
QRegularExpression regexp,
|
||||
const QImage & icon = QImage(),
|
||||
QBrush text_brush = Qt::NoBrush,
|
||||
QBrush background = Qt::NoBrush,
|
||||
bool bold = false);
|
||||
void removeCategory(QString keyword);
|
||||
void removeCategory(QRegularExpression regexp);
|
||||
void clearCategories();
|
||||
|
||||
void addText(const QString & text, bool insert_newline = true);
|
||||
void addText(const QString & text, const QString & keyword, bool insert_newline = true);
|
||||
|
||||
|
||||
private:
|
||||
struct QAD_APPLICATION_EXPORT Category {
|
||||
Category();
|
||||
@@ -88,31 +88,30 @@ private:
|
||||
QBrush text_brush;
|
||||
QBrush background;
|
||||
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 newLine(const QString & keyword);
|
||||
QSize iconImageSize();
|
||||
void filterBlock(QTextBlock block, const QString & fs, const QRegularExpression & regexp);
|
||||
|
||||
|
||||
Ui::LogView * ui;
|
||||
QList<Category> categories;
|
||||
QTextCharFormat def_cf;
|
||||
QTextBlockFormat def_bf;
|
||||
QAction * actionLogSelectAll, * actionLogCopy, * actionLogClear;
|
||||
QAction *actionLogSelectAll, *actionLogCopy, *actionLogClear;
|
||||
|
||||
public slots:
|
||||
void setFilterVisible(bool yes);
|
||||
void setLinesLimit(int l);
|
||||
void clear();
|
||||
|
||||
|
||||
private slots:
|
||||
void scrollToBottom();
|
||||
void filter();
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "edockwidget.h"
|
||||
#include "edockwidgetplugin.h"
|
||||
|
||||
#include "edockwidget.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
@@ -9,8 +11,7 @@ EDockWidgetPlugin::EDockWidgetPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
|
||||
void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -66,4 +67,3 @@ QString EDockWidgetPlugin::domXml() const {
|
||||
QString EDockWidgetPlugin::includeFile() const {
|
||||
return QLatin1String("edockwidget.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class EDockWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class EDockWidgetPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "emainwindow.h"
|
||||
#include "emainwindowplugin.h"
|
||||
|
||||
#include "emainwindow.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
@@ -9,8 +11,7 @@ EMainWindowPlugin::EMainWindowPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
|
||||
void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -66,4 +67,3 @@ QString EMainWindowPlugin::domXml() const {
|
||||
QString EMainWindowPlugin::includeFile() const {
|
||||
return QLatin1String("emainwindow.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class EMainWindowPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class EMainWindowPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "historyview.h"
|
||||
#include "historyviewplugin.h"
|
||||
|
||||
#include "historyview.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
@@ -9,8 +11,7 @@ HistoryViewPlugin::HistoryViewPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
|
||||
void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -66,4 +67,3 @@ QString HistoryViewPlugin::domXml() const {
|
||||
QString HistoryViewPlugin::includeFile() const {
|
||||
return QLatin1String("historyview.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class HistoryViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class HistoryViewPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // HISTORYVIEWPLUGIN_H
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "logview.h"
|
||||
#include "logviewplugin.h"
|
||||
|
||||
#include "logview.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
@@ -9,8 +11,7 @@ LogViewPlugin::LogViewPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
|
||||
void LogViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -66,4 +67,3 @@ QString LogViewPlugin::domXml() const {
|
||||
QString LogViewPlugin::includeFile() const {
|
||||
return QLatin1String("logview.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class LogViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class LogViewPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // LOGVIEWPLUGIN_H
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "qad_application.h"
|
||||
|
||||
#include "edockwidgetplugin.h"
|
||||
#include "emainwindowplugin.h"
|
||||
#include "historyviewplugin.h"
|
||||
@@ -6,14 +7,14 @@
|
||||
|
||||
|
||||
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 HistoryViewPlugin(this));
|
||||
m_widgets.append(new LogViewPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QADApplication::customWidgets() const {
|
||||
QList<QDesignerCustomWidgetInterface *> QADApplication::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
#ifndef QAD_APPLICATION_H
|
||||
#define QAD_APPLICATION_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
#include <QtDesigner/QtDesigner>
|
||||
|
||||
class QADApplication: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
class QADApplication
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetCollectionInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "qad.application")
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit QADApplication(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
QList<QDesignerCustomWidgetInterface *> m_widgets;
|
||||
};
|
||||
|
||||
#endif // QAD_APPLICATION_H
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <QDebug>
|
||||
#include "qsingleapplication.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
#define QSA_SHMSIZE 4096
|
||||
#define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32))
|
||||
@@ -9,12 +10,11 @@
|
||||
QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
|
||||
shm.setKey(app_name);
|
||||
exiting = false;
|
||||
first = !shm.attach();
|
||||
first = !shm.attach();
|
||||
if (!first) {
|
||||
shm.detach();
|
||||
first = !shm.attach();
|
||||
if (!first)
|
||||
return;
|
||||
if (!first) return;
|
||||
}
|
||||
shm.create(QSA_SHMSIZE);
|
||||
shm.attach();
|
||||
@@ -23,7 +23,7 @@ QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
|
||||
if (d) memset(d, 0, sizeof(quint32));
|
||||
shm.unlock();
|
||||
start();
|
||||
//qDebug() << "start listen";
|
||||
// qDebug() << "start listen";
|
||||
}
|
||||
|
||||
|
||||
@@ -31,15 +31,14 @@ QSingleApplication::~QSingleApplication() {
|
||||
if (first) {
|
||||
exiting = true;
|
||||
quit();
|
||||
if (!wait(100))
|
||||
terminate();
|
||||
if (!wait(100)) terminate();
|
||||
}
|
||||
if (shm.isAttached()) shm.detach();
|
||||
}
|
||||
|
||||
|
||||
void QSingleApplication::sendMessage(const QByteArray & m) {
|
||||
//qDebug() << "send message" << first << shm.isAttached();
|
||||
// qDebug() << "send message" << first << shm.isAttached();
|
||||
if (first || !shm.isAttached()) return;
|
||||
if (m.size() > int(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));
|
||||
num++;
|
||||
memcpy(d, &num, 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)), &size, sizeof(quint32));
|
||||
memcpy((((char *)d) + sizeof(quint32) + sizeof(quint32)), m.constData(), size);
|
||||
}
|
||||
shm.unlock();
|
||||
}
|
||||
@@ -68,12 +67,12 @@ void QSingleApplication::run() {
|
||||
memcpy(&num, d, sizeof(quint32));
|
||||
if (pnum != num) {
|
||||
pnum = num;
|
||||
//qDebug() << "new message" << num;
|
||||
memcpy(&size, (((const char*)d) + sizeof(quint32)), sizeof(quint32));
|
||||
// qDebug() << "new message" << num;
|
||||
memcpy(&size, (((const char *)d) + sizeof(quint32)), sizeof(quint32));
|
||||
if (size <= int(QSA_MSGSIZE)) {
|
||||
QByteArray msg;
|
||||
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);
|
||||
} else {
|
||||
qDebug() << "[QSingleApplication] Invalid message size:" << size;
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QSINGLEAPPLICATION_H
|
||||
#define QSINGLEAPPLICATION_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QSharedMemory>
|
||||
#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
|
||||
|
||||
public:
|
||||
QSingleApplication(const QString & app_name = QString("qapp"));
|
||||
~QSingleApplication();
|
||||
|
||||
bool isFirst() const {return first;}
|
||||
|
||||
|
||||
bool isFirst() const { return first; }
|
||||
|
||||
private:
|
||||
void run();
|
||||
|
||||
|
||||
QSharedMemory shm;
|
||||
bool first, exiting;
|
||||
|
||||
|
||||
public slots:
|
||||
void sendMessage(const QByteArray & m);
|
||||
|
||||
|
||||
signals:
|
||||
void messageReceived(QByteArray);
|
||||
|
||||
};
|
||||
|
||||
#endif // QSINGLEAPPLICATION_H
|
||||
|
||||
@@ -1,49 +1,45 @@
|
||||
#include "ribbon.h"
|
||||
|
||||
#include "qad_types.h"
|
||||
|
||||
#include <QScrollBar>
|
||||
|
||||
|
||||
Ribbon::Ribbon(QMainWindow * parent_): QToolBar() {
|
||||
tab = 0;
|
||||
tab = 0;
|
||||
scroll_area = 0;
|
||||
delay_e = true;
|
||||
delay = 1000;
|
||||
hovered = -1;
|
||||
delay_e = true;
|
||||
delay = 1000;
|
||||
hovered = -1;
|
||||
setObjectName("ribbon");
|
||||
setProperty("ribbon", true);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
parent = parent_;
|
||||
if (parent_)
|
||||
parent_->installEventFilter(this);
|
||||
if (parent_) parent_->installEventFilter(this);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
Ribbon::~Ribbon() {
|
||||
}
|
||||
Ribbon::~Ribbon() {}
|
||||
|
||||
|
||||
bool Ribbon::eventFilter(QObject * o, QEvent * e) {
|
||||
//qDebug() << e;
|
||||
// qDebug() << e;
|
||||
if (o == parent) {
|
||||
if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate)
|
||||
_resize();
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish)
|
||||
_setIconsSize();
|
||||
if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate) _resize();
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) _setIconsSize();
|
||||
return QToolBar::eventFilter(o, e);
|
||||
}
|
||||
if (e->type() == QEvent::ActionChanged) {
|
||||
QToolButton * b = qobject_cast<QToolButton * >((QObject * )o->property("ribbonButton").toLongLong());
|
||||
if (b != 0)
|
||||
b->setEnabled(qobject_cast<QAction * >(o)->isEnabled());
|
||||
QToolButton * b = qobject_cast<QToolButton *>((QObject *)o->property("ribbonButton").toLongLong());
|
||||
if (b != 0) b->setEnabled(qobject_cast<QAction *>(o)->isEnabled());
|
||||
}
|
||||
return QToolBar::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::timerEvent(QTimerEvent * e) {
|
||||
if (hovers.value(e->timerId(), -1) == hovered)
|
||||
tab->setCurrentIndex(hovered);
|
||||
if (hovers.value(e->timerId(), -1) == hovered) tab->setCurrentIndex(hovered);
|
||||
hovers.remove(e->timerId());
|
||||
killTimer(e->timerId());
|
||||
}
|
||||
@@ -52,11 +48,8 @@ void Ribbon::timerEvent(QTimerEvent * e) {
|
||||
void Ribbon::changeEvent(QEvent * e) {
|
||||
QToolBar::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
retranslate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: retranslate(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,16 +57,16 @@ void Ribbon::changeEvent(QEvent * e) {
|
||||
void Ribbon::_resize() {
|
||||
return; // WARNING
|
||||
for (int i = 0; i < tab->count(); ++i) {
|
||||
int h = ((QScrollArea*)(tab->widget(i)))->sizeHint().height();
|
||||
if (((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->isVisible())
|
||||
h += ((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->height();
|
||||
((QScrollArea*)(tab->widget(i)))->setMinimumHeight(h);
|
||||
int h = ((QScrollArea *)(tab->widget(i)))->sizeHint().height();
|
||||
if (((QScrollArea *)(tab->widget(i)))->horizontalScrollBar()->isVisible())
|
||||
h += ((QScrollArea *)(tab->widget(i)))->horizontalScrollBar()->height();
|
||||
((QScrollArea *)(tab->widget(i)))->setMinimumHeight(h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::_setIconsSize() {
|
||||
//qDebug() << "resize" << preferredIconSize() << QApplication::font();
|
||||
// qDebug() << "resize" << preferredIconSize() << QApplication::font();
|
||||
setTabIconSize(preferredIconSize(2, this));
|
||||
setIconSize(preferredIconSize(3, this));
|
||||
}
|
||||
@@ -86,7 +79,6 @@ void Ribbon::_setButtonText(QToolButton * b, QAction * a) {
|
||||
sc += "\n" + s.toString(QKeySequence::NativeText);
|
||||
}
|
||||
b->setToolTip(a->text() + sc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -101,11 +93,10 @@ void Ribbon::setVisible(bool yes) {
|
||||
void Ribbon::init() {
|
||||
if (parent == 0) return;
|
||||
if (parent->menuBar() == 0) return;
|
||||
QList<QAction * > lm = parent->menuBar()->actions(), la;
|
||||
QList<QAction *> lm = parent->menuBar()->actions(), la;
|
||||
QString prev_tab;
|
||||
if (tab) {
|
||||
if (tab->currentIndex() >= 0)
|
||||
prev_tab = tab->tabText(tab->currentIndex());
|
||||
if (tab->currentIndex() >= 0) prev_tab = tab->tabText(tab->currentIndex());
|
||||
tab->deleteLater();
|
||||
}
|
||||
clear();
|
||||
@@ -117,24 +108,24 @@ void Ribbon::init() {
|
||||
connect(tab, SIGNAL(currentChanged(int)), this, SIGNAL(currentTabChanged(int)));
|
||||
tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
QFrame * g;
|
||||
QBoxLayout * l, * tl;
|
||||
QBoxLayout *l, *tl;
|
||||
QToolButton * b;
|
||||
//tab->setIconSize(QSize(32, 32));
|
||||
// tab->setIconSize(QSize(32, 32));
|
||||
for (QAction * i: lm) {
|
||||
if (!i->menu()) continue;
|
||||
//if (!i->menu()->isVisible()) continue;
|
||||
la = i->menu()->actions();
|
||||
// if (!i->menu()->isVisible()) continue;
|
||||
la = i->menu()->actions();
|
||||
QIcon tic = i->icon();
|
||||
if (!tic.isNull())
|
||||
i->setProperty("__icon", QVariant::fromValue<QIcon>(tic));
|
||||
else
|
||||
tic = i->property("__icon").value<QIcon>();
|
||||
//#ifdef Q_OS_MACOS
|
||||
// tic = QIcon();
|
||||
//#endif
|
||||
// #ifdef Q_OS_MACOS
|
||||
// tic = QIcon();
|
||||
// #endif
|
||||
tab->addTab(new QWidget(), tic, i->text());
|
||||
//qDebug() << this << i->icon() << i->text();
|
||||
//continue;
|
||||
// qDebug() << this << i->icon() << i->text();
|
||||
// continue;
|
||||
/*QScrollArea * sa = new QScrollArea();
|
||||
sa->setWidget(new QWidget());
|
||||
sa->setWidgetResizable(true);
|
||||
@@ -143,7 +134,7 @@ void Ribbon::init() {
|
||||
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
sa->setFrameShape(QFrame::NoFrame);
|
||||
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());
|
||||
tl = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
tl->setSpacing(2);
|
||||
@@ -152,7 +143,8 @@ void Ribbon::init() {
|
||||
#else
|
||||
tl->setContentsMargins(2, 0, 2, 2);
|
||||
#endif
|
||||
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel);
|
||||
g = new QFrame();
|
||||
g->setFrameShape(QFrame::StyledPanel);
|
||||
l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
g->setLayout(l);
|
||||
l->setSpacing(2);
|
||||
@@ -161,24 +153,25 @@ void Ribbon::init() {
|
||||
if (j->isSeparator()) {
|
||||
if (l->isEmpty()) continue;
|
||||
tl->addWidget(g);
|
||||
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel);
|
||||
g = new QFrame();
|
||||
g->setFrameShape(QFrame::StyledPanel);
|
||||
l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
l->setSpacing(2);
|
||||
l->setContentsMargins(2, 2, 2, 2);
|
||||
g->setLayout(l);
|
||||
continue;
|
||||
}
|
||||
if (qobject_cast<QWidgetAction*>(j)) {
|
||||
QWidget * _w = qobject_cast<QWidgetAction*>(j)->defaultWidget();
|
||||
if (qobject_cast<QWidgetAction *>(j)) {
|
||||
QWidget * _w = qobject_cast<QWidgetAction *>(j)->defaultWidget();
|
||||
l->addWidget(_w);
|
||||
_w->show();
|
||||
continue;
|
||||
}
|
||||
b = new QToolButton();
|
||||
//b->setVisible(j->isVisible());
|
||||
// b->setVisible(j->isVisible());
|
||||
b->setEnabled(j->isEnabled());
|
||||
b->setProperty("ribbonAction", qlonglong((void * )j));
|
||||
j->setProperty("ribbonButton", qlonglong((void * )b));
|
||||
b->setProperty("ribbonAction", qlonglong((void *)j));
|
||||
j->setProperty("ribbonButton", qlonglong((void *)b));
|
||||
j->installEventFilter(this);
|
||||
if (j->menu() != 0) {
|
||||
b->setPopupMode(QToolButton::InstantPopup);
|
||||
@@ -193,11 +186,11 @@ void Ribbon::init() {
|
||||
} else
|
||||
connect(b, SIGNAL(clicked()), j, SLOT(trigger()));
|
||||
}
|
||||
//b->setIconSize(QSize(16, 16));
|
||||
// b->setIconSize(QSize(16, 16));
|
||||
b->setIcon(j->icon());
|
||||
_setButtonText(b, j);
|
||||
//b->addAction(j);
|
||||
//b->setShortcut(j->shortcut());
|
||||
// b->addAction(j);
|
||||
// b->setShortcut(j->shortcut());
|
||||
b->setAutoRaise(true);
|
||||
b->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||
@@ -206,10 +199,9 @@ void Ribbon::init() {
|
||||
}
|
||||
tl->addWidget(g);
|
||||
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);
|
||||
if (i->text() == prev_tab)
|
||||
tab->setCurrentIndex(tab->count() - 1);
|
||||
if (i->text() == prev_tab) tab->setCurrentIndex(tab->count() - 1);
|
||||
}
|
||||
setFloatable(false);
|
||||
setMovable(false);
|
||||
@@ -219,7 +211,7 @@ void Ribbon::init() {
|
||||
scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scroll_area->setWidget(tab);*/
|
||||
_resize();
|
||||
//addWidget(scroll_area);
|
||||
// addWidget(scroll_area);
|
||||
addWidget(tab);
|
||||
parent->addToolBar(Qt::TopToolBarArea, this);
|
||||
parent->menuBar()->hide();
|
||||
@@ -231,13 +223,13 @@ void Ribbon::init() {
|
||||
void Ribbon::retranslate() {
|
||||
QAction * a;
|
||||
for (QToolButton * i: buttons) {
|
||||
a = (QAction * )(i->property("ribbonAction").toLongLong());
|
||||
a = (QAction *)(i->property("ribbonAction").toLongLong());
|
||||
if (a == 0) continue;
|
||||
_setButtonText(i, a);
|
||||
//i->setShortcut(a->shortcut());
|
||||
// i->setShortcut(a->shortcut());
|
||||
}
|
||||
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;
|
||||
tab->setTabText(i, a->text());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef 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 "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
|
||||
|
||||
public:
|
||||
explicit Ribbon(QMainWindow * parent = 0);
|
||||
~Ribbon();
|
||||
@@ -45,41 +46,51 @@ public:
|
||||
void retranslate();
|
||||
void setIconSize(const QSize & size);
|
||||
void setTabIconSize(const QSize & size);
|
||||
void setButtonStyle(const Qt::ToolButtonStyle & style) {foreach (QToolButton * i, buttons) i->setToolButtonStyle(style);}
|
||||
void setAutoSwitchEnabled(bool yes) {delay_e = yes;}
|
||||
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;}
|
||||
void setButtonStyle(const Qt::ToolButtonStyle & style) {
|
||||
foreach(QToolButton * i, buttons)
|
||||
i->setToolButtonStyle(style);
|
||||
}
|
||||
void setAutoSwitchEnabled(bool yes) { delay_e = yes; }
|
||||
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:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void timerEvent(QTimerEvent * e);
|
||||
void changeEvent(QEvent *e);
|
||||
void changeEvent(QEvent * e);
|
||||
void _resize();
|
||||
void _setIconsSize();
|
||||
void _setButtonText(QToolButton * b, QAction * a);
|
||||
|
||||
int hovered, delay;
|
||||
bool delay_e;
|
||||
QList<QToolButton * > buttons;
|
||||
QList<QToolButton *> buttons;
|
||||
QMap<int, int> hovers;
|
||||
ETabWidget * tab;
|
||||
QScrollArea * scroll_area;
|
||||
QMainWindow * parent;
|
||||
|
||||
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:
|
||||
void setVisible(bool yes);
|
||||
void setHidden(bool yes) {setVisible(!yes);}
|
||||
void show() {setVisible(true);}
|
||||
void hide() {setVisible(false);}
|
||||
|
||||
void setHidden(bool yes) { setVisible(!yes); }
|
||||
void show() { setVisible(true); }
|
||||
void hide() { setVisible(false); }
|
||||
|
||||
signals:
|
||||
void currentTabChanged(int);
|
||||
|
||||
};
|
||||
|
||||
#endif // RIBBON_H
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "alignedtextitem.h"
|
||||
|
||||
#include "blockbase.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
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 ret = f;
|
||||
QFont ret = f;
|
||||
double scl = 16. / fontHeight();
|
||||
ret.setPointSizeF(ret.pointSizeF() * scl);
|
||||
return ret;
|
||||
|
||||
@@ -1,67 +1,81 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ALIGNEDTEXTITEM_H
|
||||
#define ALIGNEDTEXTITEM_H
|
||||
|
||||
#include <QGraphicsSimpleTextItem>
|
||||
#include <QPen>
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include "qad_blockview_export.h"
|
||||
#include <QGraphicsSimpleTextItem>
|
||||
#include <QPen>
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT AlignedTextItem: public QGraphicsItem {
|
||||
public:
|
||||
AlignedTextItem(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 setPen(const QPen & p) {text_.setPen(p); _move();}
|
||||
void setBrush(const QBrush & b) {text_.setBrush(b); _move();}
|
||||
void setAlignment(Qt::Alignment align) {align_ = align; _move();}
|
||||
|
||||
QString text() const {return text_.text();}
|
||||
QFont font() const {return font_;}
|
||||
QPen pen() const {return text_.pen();}
|
||||
QBrush brush() const {return text_.brush();}
|
||||
Qt::Alignment alignment() const {return align_;}
|
||||
|
||||
void clear() {setText(QString());}
|
||||
|
||||
enum {Type = UserType + 0x100};
|
||||
void setPen(const QPen & p) {
|
||||
text_.setPen(p);
|
||||
_move();
|
||||
}
|
||||
void setBrush(const QBrush & b) {
|
||||
text_.setBrush(b);
|
||||
_move();
|
||||
}
|
||||
void setAlignment(Qt::Alignment align) {
|
||||
align_ = align;
|
||||
_move();
|
||||
}
|
||||
|
||||
QString text() const { return text_.text(); }
|
||||
QFont font() const { return font_; }
|
||||
QPen pen() const { return text_.pen(); }
|
||||
QBrush brush() const { return text_.brush(); }
|
||||
Qt::Alignment alignment() const { return align_; }
|
||||
|
||||
void clear() { setText(QString()); }
|
||||
|
||||
enum {
|
||||
Type = UserType + 0x100
|
||||
};
|
||||
|
||||
static QFont sceneFont(const QFont & f);
|
||||
|
||||
|
||||
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 int type() const {return Type;}
|
||||
|
||||
void _move() {text_.setPos(-_point(align_));}
|
||||
virtual int type() const { return Type; }
|
||||
|
||||
void _move() { text_.setPos(-_point(align_)); }
|
||||
QPointF _point(Qt::Alignment a) const;
|
||||
|
||||
|
||||
QGraphicsSimpleTextItem text_;
|
||||
Qt::Alignment align_;
|
||||
QFont font_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
#include "blockbase.h"
|
||||
|
||||
#include "alignedtextitem.h"
|
||||
#include "qvariantedit.h"
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
|
||||
QDataStream & operator<<(QDataStream & s, const QGraphicsItem * item) {
|
||||
if (!item) {
|
||||
s << int(-1);
|
||||
return s;
|
||||
}
|
||||
const QGraphicsRectItem * irect = qgraphicsitem_cast<const QGraphicsRectItem*>(item);
|
||||
const QGraphicsEllipseItem * iell = qgraphicsitem_cast<const QGraphicsEllipseItem*>(item);
|
||||
const QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<const QGraphicsSimpleTextItem*>(item);
|
||||
const AlignedTextItem * iatext = qgraphicsitem_cast<const AlignedTextItem*>(item);
|
||||
const QGraphicsLineItem * iline = qgraphicsitem_cast<const QGraphicsLineItem*>(item);
|
||||
const QGraphicsPathItem * ipath = qgraphicsitem_cast<const QGraphicsPathItem*>(item);
|
||||
const QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<const QGraphicsPixmapItem*>(item);
|
||||
const QGraphicsRectItem * irect = qgraphicsitem_cast<const QGraphicsRectItem *>(item);
|
||||
const QGraphicsEllipseItem * iell = qgraphicsitem_cast<const QGraphicsEllipseItem *>(item);
|
||||
const QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<const QGraphicsSimpleTextItem *>(item);
|
||||
const AlignedTextItem * iatext = qgraphicsitem_cast<const AlignedTextItem *>(item);
|
||||
const QGraphicsLineItem * iline = qgraphicsitem_cast<const QGraphicsLineItem *>(item);
|
||||
const QGraphicsPathItem * ipath = qgraphicsitem_cast<const QGraphicsPathItem *>(item);
|
||||
const QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<const QGraphicsPixmapItem *>(item);
|
||||
if (irect) {
|
||||
s << int(0) << (irect->pen()) << (irect->brush()) << (irect->rect());
|
||||
} else if (iell) {
|
||||
@@ -38,72 +39,181 @@ QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item) {
|
||||
int type_; s >> type_;
|
||||
QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item) {
|
||||
int type_;
|
||||
s >> type_;
|
||||
if (type_ < 0) {
|
||||
item = 0;
|
||||
return s;
|
||||
}
|
||||
QGraphicsRectItem * nrect = 0;
|
||||
QGraphicsEllipseItem * nell = 0;
|
||||
QGraphicsRectItem * nrect = 0;
|
||||
QGraphicsEllipseItem * nell = 0;
|
||||
QGraphicsSimpleTextItem * ntext = 0;
|
||||
AlignedTextItem * natext = 0;
|
||||
QGraphicsLineItem * nline = 0;
|
||||
QGraphicsPathItem * npath = 0;
|
||||
QGraphicsPixmapItem * npixmap = 0;
|
||||
item = 0;
|
||||
AlignedTextItem * natext = 0;
|
||||
QGraphicsLineItem * nline = 0;
|
||||
QGraphicsPathItem * npath = 0;
|
||||
QGraphicsPixmapItem * npixmap = 0;
|
||||
item = 0;
|
||||
switch (type_) {
|
||||
case 0:
|
||||
nrect = new QGraphicsRectItem(); item = nrect;
|
||||
{QPen _v; s >> _v; nrect->setPen(_v);}
|
||||
{QBrush _v; s >> _v; nrect->setBrush(_v);}
|
||||
{QRectF _v; s >> _v; nrect->setRect(_v);}
|
||||
nrect = new QGraphicsRectItem();
|
||||
item = nrect;
|
||||
{
|
||||
QPen _v;
|
||||
s >> _v;
|
||||
nrect->setPen(_v);
|
||||
}
|
||||
{
|
||||
QBrush _v;
|
||||
s >> _v;
|
||||
nrect->setBrush(_v);
|
||||
}
|
||||
{
|
||||
QRectF _v;
|
||||
s >> _v;
|
||||
nrect->setRect(_v);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
nell = new QGraphicsEllipseItem(); item = nell;
|
||||
{QPen _v; s >> _v; nell->setPen(_v);}
|
||||
{QBrush _v; s >> _v; nell->setBrush(_v);}
|
||||
{QRectF _v; s >> _v; nell->setRect(_v);}
|
||||
nell = new QGraphicsEllipseItem();
|
||||
item = nell;
|
||||
{
|
||||
QPen _v;
|
||||
s >> _v;
|
||||
nell->setPen(_v);
|
||||
}
|
||||
{
|
||||
QBrush _v;
|
||||
s >> _v;
|
||||
nell->setBrush(_v);
|
||||
}
|
||||
{
|
||||
QRectF _v;
|
||||
s >> _v;
|
||||
nell->setRect(_v);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ntext = new QGraphicsSimpleTextItem(); item = ntext;
|
||||
{QPen _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);}
|
||||
ntext = new QGraphicsSimpleTextItem();
|
||||
item = ntext;
|
||||
{
|
||||
QPen _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;
|
||||
case 6:
|
||||
natext = new AlignedTextItem(); item = natext;
|
||||
{QPen _v; s >> _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);}
|
||||
natext = new AlignedTextItem();
|
||||
item = natext;
|
||||
{
|
||||
QPen _v;
|
||||
s >> _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;
|
||||
case 3:
|
||||
nline = new QGraphicsLineItem(); item = nline;
|
||||
{QPen _v; s >> _v; nline->setPen(_v);}
|
||||
{QLineF _v; s >> _v; nline->setLine(_v);}
|
||||
nline = new QGraphicsLineItem();
|
||||
item = nline;
|
||||
{
|
||||
QPen _v;
|
||||
s >> _v;
|
||||
nline->setPen(_v);
|
||||
}
|
||||
{
|
||||
QLineF _v;
|
||||
s >> _v;
|
||||
nline->setLine(_v);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
npath = new QGraphicsPathItem(); item = npath;
|
||||
{QPen _v; s >> _v; npath->setPen(_v);}
|
||||
{QPainterPath _v; s >> _v; npath->setPath(_v);}
|
||||
npath = new QGraphicsPathItem();
|
||||
item = npath;
|
||||
{
|
||||
QPen _v;
|
||||
s >> _v;
|
||||
npath->setPen(_v);
|
||||
}
|
||||
{
|
||||
QPainterPath _v;
|
||||
s >> _v;
|
||||
npath->setPath(_v);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
npixmap = new QGraphicsPixmapItem(); item = npixmap;
|
||||
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);}
|
||||
npixmap = new QGraphicsPixmapItem();
|
||||
item = npixmap;
|
||||
{
|
||||
QPixmap _v;
|
||||
s >> _v;
|
||||
npixmap->setPixmap(_v);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
npixmap = new QGraphicsPixmapItem(); item = npixmap;
|
||||
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);}
|
||||
{QTransform _t; s >> _t; npixmap->setTransform(_t);}
|
||||
npixmap = new QGraphicsPixmapItem();
|
||||
item = npixmap;
|
||||
{
|
||||
QPixmap _v;
|
||||
s >> _v;
|
||||
npixmap->setPixmap(_v);
|
||||
}
|
||||
{
|
||||
QTransform _t;
|
||||
s >> _t;
|
||||
npixmap->setTransform(_t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (item) {
|
||||
{QPointF _v; s >> _v; item->setPos(_v);}
|
||||
{qreal _v; s >> _v; item->setRotation(_v);}
|
||||
{int _v; s >> _v; item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);}
|
||||
{
|
||||
QPointF _v;
|
||||
s >> _v;
|
||||
item->setPos(_v);
|
||||
}
|
||||
{
|
||||
qreal _v;
|
||||
s >> _v;
|
||||
item->setRotation(_v);
|
||||
}
|
||||
{
|
||||
int _v;
|
||||
s >> _v;
|
||||
item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKBASE_H
|
||||
#define BLOCKBASE_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include "qad_blockview_export.h"
|
||||
#include "qad_types.h"
|
||||
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsItem>
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QGraphicsView>
|
||||
#include <QStack>
|
||||
#include "qad_types.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
static const int _blockitem_current_version_ = 1;
|
||||
|
||||
|
||||
enum BlockviewItemData {
|
||||
bvidSelected = 1000, // bool
|
||||
bvidType , // BlockviewItemType
|
||||
bvidItemPos , // QPointF
|
||||
bvidDecorText , // QString src text for QGraphicsSimpleTextItem
|
||||
bvidMoveParent , // bool flag for move parent
|
||||
bvidVisualizeSelection , // bool flag for visualize selection
|
||||
bvidItemSelection , // bool BlockItem selection
|
||||
bvidTmpItem , // bool item is temporary, ignore
|
||||
bvidBlockDecor , // bool item is BlockItem decor
|
||||
bvidDTHandle , // bool
|
||||
bvidCorrectMove , // bool
|
||||
bvidSelected = 1000, // bool
|
||||
bvidType, // BlockviewItemType
|
||||
bvidItemPos, // QPointF
|
||||
bvidDecorText, // QString src text for QGraphicsSimpleTextItem
|
||||
bvidMoveParent, // bool flag for move parent
|
||||
bvidVisualizeSelection, // bool flag for visualize selection
|
||||
bvidItemSelection, // bool BlockItem selection
|
||||
bvidTmpItem, // bool item is temporary, ignore
|
||||
bvidBlockDecor, // bool item is BlockItem decor
|
||||
bvidDTHandle, // bool
|
||||
bvidCorrectMove, // bool
|
||||
};
|
||||
|
||||
enum BlockviewItemType {
|
||||
@@ -57,16 +58,15 @@ enum BlockviewItemType {
|
||||
bvitDecor,
|
||||
};
|
||||
|
||||
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, const 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_ENUMS(Action)
|
||||
|
||||
public:
|
||||
|
||||
enum Action {
|
||||
BlockAdd = 1,
|
||||
BlockMove,
|
||||
@@ -82,7 +82,6 @@ public:
|
||||
BusSegmentRemove,
|
||||
Paste
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKBASE_H
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#include "blockview.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() {
|
||||
temp_ = temp;
|
||||
_init();
|
||||
if (!temp) setData(bvidType, bvitBus);
|
||||
else hide();
|
||||
if (!temp)
|
||||
setData(bvidType, bvitBus);
|
||||
else
|
||||
hide();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +20,12 @@ BlockBusItem::BlockBusItem(const BlockBusItem & other): QGraphicsObject(), Prope
|
||||
setPen(other.pen());
|
||||
setBrush(other.brush());
|
||||
setBusType(other.busType());
|
||||
square_node = other.square_node;
|
||||
max_ep = other.max_ep;
|
||||
pol = other.pol;
|
||||
segments = other.segments;
|
||||
im_bus = other.im_bus;
|
||||
im_end = other.im_end;
|
||||
square_node = other.square_node;
|
||||
max_ep = other.max_ep;
|
||||
pol = other.pol;
|
||||
segments = other.segments;
|
||||
im_bus = other.im_bus;
|
||||
im_end = other.im_end;
|
||||
im_bus_scale = other.im_bus_scale;
|
||||
im_end_scale = other.im_end_scale;
|
||||
updateGeometry();
|
||||
@@ -33,26 +36,34 @@ void BlockBusItem::_init() {
|
||||
setZValue(1.);
|
||||
setBusType(-1);
|
||||
setAcceptHoverEvents(true);
|
||||
ph.setColor(Qt::blue); ph.setJoinStyle(Qt::MiterJoin);
|
||||
bh.setColor(Qt::blue); bh.setStyle(Qt::SolidPattern);
|
||||
pu = pa = pr = ph; bu = ba = br = bh;
|
||||
grid_step = 10.;
|
||||
ph.setColor(Qt::blue);
|
||||
ph.setJoinStyle(Qt::MiterJoin);
|
||||
bh.setColor(Qt::blue);
|
||||
bh.setStyle(Qt::SolidPattern);
|
||||
pu = pa = pr = ph;
|
||||
bu = ba = br = bh;
|
||||
grid_step = 10.;
|
||||
pu.setWidth(1);
|
||||
pu.setColor(Qt::black); bu.setColor(Qt::black);
|
||||
pa.setColor(Qt::darkGreen); ba.setColor(Qt::darkGreen);
|
||||
pr.setColor(Qt::darkRed); br.setColor(Qt::darkRed);
|
||||
pn.setColor(Qt::gray); pn.setStyle(Qt::DashLine);
|
||||
pu.setColor(Qt::black);
|
||||
bu.setColor(Qt::black);
|
||||
pa.setColor(Qt::darkGreen);
|
||||
ba.setColor(Qt::darkGreen);
|
||||
pr.setColor(Qt::darkRed);
|
||||
br.setColor(Qt::darkRed);
|
||||
pn.setColor(Qt::gray);
|
||||
pn.setStyle(Qt::DashLine);
|
||||
if (temp_) {
|
||||
pu.setStyle(Qt::DashLine);
|
||||
pu.setColor(Qt::darkGray);
|
||||
bu.setColor(Qt::darkGray);
|
||||
}
|
||||
setPen(pu); setBrush(bu);
|
||||
setPen(pu);
|
||||
setBrush(bu);
|
||||
square_node = false;
|
||||
max_ep = 0;
|
||||
max_ep = 0;
|
||||
selPoint = selSegment = state_ = -1;
|
||||
pen_width = 2.;
|
||||
point_size = 3.;
|
||||
pen_width = 2.;
|
||||
point_size = 3.;
|
||||
im_bus_scale = im_end_scale = 1.;
|
||||
moved = deleted = mark_in = mark_out = new_segment = mm_cancel = lm_point = false;
|
||||
anim_point_size.setTargetObject(this);
|
||||
@@ -68,19 +79,19 @@ void BlockBusItem::reconnect() {
|
||||
if (temp_) return;
|
||||
if (!scene()) 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) {
|
||||
if (temp_) return QGraphicsObject::sceneEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::GraphicsSceneHoverEnter: hoverEnterEvent((QGraphicsSceneHoverEvent * )e); break;
|
||||
case QEvent::GraphicsSceneHoverMove: hoverMoveEvent((QGraphicsSceneHoverEvent * )e); break;
|
||||
case QEvent::GraphicsSceneHoverLeave: hoverLeaveEvent((QGraphicsSceneHoverEvent * )e); break;
|
||||
case QEvent::GraphicsSceneMousePress: mousePressEvent((QGraphicsSceneMouseEvent * )e); break;
|
||||
case QEvent::GraphicsSceneMouseMove: mouseMoveEvent((QGraphicsSceneMouseEvent * )e); break;
|
||||
case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent((QGraphicsSceneMouseEvent * )e); break;
|
||||
case QEvent::GraphicsSceneHoverEnter: hoverEnterEvent((QGraphicsSceneHoverEvent *)e); break;
|
||||
case QEvent::GraphicsSceneHoverMove: hoverMoveEvent((QGraphicsSceneHoverEvent *)e); break;
|
||||
case QEvent::GraphicsSceneHoverLeave: hoverLeaveEvent((QGraphicsSceneHoverEvent *)e); break;
|
||||
case QEvent::GraphicsSceneMousePress: mousePressEvent((QGraphicsSceneMouseEvent *)e); break;
|
||||
case QEvent::GraphicsSceneMouseMove: mouseMoveEvent((QGraphicsSceneMouseEvent *)e); break;
|
||||
case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent((QGraphicsSceneMouseEvent *)e); break;
|
||||
default: break;
|
||||
}
|
||||
return QGraphicsObject::sceneEvent(e);
|
||||
@@ -95,7 +106,7 @@ int BlockBusItem::addPoint(const QPointF & point, bool update) {
|
||||
selPoint = pol.size() - 1;
|
||||
segments << QPair<int, int>(selPoint, segments[selSegment].second);
|
||||
segments[selSegment].second = selPoint;
|
||||
selSegment = -1;
|
||||
selSegment = -1;
|
||||
updateGeometry();
|
||||
if (scene() != 0 && update) scene()->update();
|
||||
return pol.size() - 1;
|
||||
@@ -122,32 +133,33 @@ void BlockBusItem::removePoint(int index) {
|
||||
if (index < 0 || index > pol.size() - 1) return;
|
||||
int sc = 0, fs = -1, ss = -1;
|
||||
for (int i = 0; i < segments.size(); ++i)
|
||||
if (segments[i].first == index ||
|
||||
segments[i].second == index) {
|
||||
sc++;
|
||||
if (fs < 0) fs = i;
|
||||
else ss = i;
|
||||
if (segments[i].first == index || segments[i].second == index) {
|
||||
sc++;
|
||||
if (fs < 0)
|
||||
fs = i;
|
||||
else
|
||||
ss = i;
|
||||
}
|
||||
int ei(0);
|
||||
switch (sc) {
|
||||
case 1:
|
||||
segments.removeAt(fs);
|
||||
break;
|
||||
case 1: segments.removeAt(fs); break;
|
||||
case 2:
|
||||
if (segments[ss].first == index) ei = segments[ss].second;
|
||||
else ei = segments[ss].first;
|
||||
if (segments[fs].first == index) segments[fs].first = ei;
|
||||
else segments[fs].second = ei;
|
||||
if (segments[ss].first == index)
|
||||
ei = segments[ss].second;
|
||||
else
|
||||
ei = segments[ss].first;
|
||||
if (segments[fs].first == index)
|
||||
segments[fs].first = ei;
|
||||
else
|
||||
segments[fs].second = ei;
|
||||
segments.removeAt(ss);
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
pol.remove(index);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first >= index)
|
||||
segments[i].first--;
|
||||
if (segments[i].second >= index)
|
||||
segments[i].second--;
|
||||
if (segments[i].first >= index) segments[i].first--;
|
||||
if (segments[i].second >= index) segments[i].second--;
|
||||
}
|
||||
selPoint = -1;
|
||||
checkDelete();
|
||||
@@ -162,25 +174,19 @@ void BlockBusItem::removeSegment(int index) {
|
||||
if (pif > pis) qSwap<int>(pif, pis);
|
||||
int scf = 0, scs = 0;
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first == pif ||
|
||||
segments[i].second == pif)
|
||||
scf++;
|
||||
if (segments[i].first == pis ||
|
||||
segments[i].second == pis)
|
||||
scs++;
|
||||
if (segments[i].first == pif || segments[i].second == pif) scf++;
|
||||
if (segments[i].first == pis || segments[i].second == pis) scs++;
|
||||
}
|
||||
if (scs <= 2) removePoint(pis);
|
||||
if (scf <= 2) removePoint(pif);
|
||||
if (scs <= 2 || scf <= 2) selSegment = -1;
|
||||
if (scene() != 0) scene()->update();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::appendPoint(const QPointF & p) {
|
||||
pol << p;
|
||||
if (pol.size() > 1)
|
||||
segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
|
||||
if (pol.size() > 1) segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
@@ -229,13 +235,13 @@ void BlockBusItem::setSquareNodes(bool yes) {
|
||||
|
||||
|
||||
void BlockBusItem::markAsInput() {
|
||||
mark_in = true;
|
||||
mark_in = true;
|
||||
mark_out = false;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::markAsOutput() {
|
||||
mark_in = false;
|
||||
mark_in = false;
|
||||
mark_out = true;
|
||||
}
|
||||
|
||||
@@ -266,17 +272,23 @@ void BlockBusItem::simplify(bool full) {
|
||||
int s0 = segs[0], s1 = segs[1];
|
||||
QPointF cp = pol[p], sp[2];
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (segments[segs[i]].first == p) sp[i] = pol[segments[segs[i]].second];
|
||||
else sp[i] = pol[segments[segs[i]].first];
|
||||
if (segments[segs[i]].first == p)
|
||||
sp[i] = pol[segments[segs[i]].second];
|
||||
else
|
||||
sp[i] = pol[segments[segs[i]].first];
|
||||
}
|
||||
QLineF l0(sp[0], cp), l1(cp, sp[1]);
|
||||
if (qAbs(l0.angle() - l1.angle()) > 0.1) continue;
|
||||
if (segments[s0].first == p) {
|
||||
if (segments[s1].first == p) segments[s0].first = segments[s1].second;
|
||||
else segments[s0].first = segments[s1].first;
|
||||
if (segments[s1].first == p)
|
||||
segments[s0].first = segments[s1].second;
|
||||
else
|
||||
segments[s0].first = segments[s1].first;
|
||||
} else {
|
||||
if (segments[s1].first == p) segments[s0].second = segments[s1].second;
|
||||
else segments[s0].second = segments[s1].first;
|
||||
if (segments[s1].first == p)
|
||||
segments[s0].second = segments[s1].second;
|
||||
else
|
||||
segments[s0].second = segments[s1].first;
|
||||
}
|
||||
segments.removeAt(s1);
|
||||
pol.remove(p);
|
||||
@@ -292,8 +304,7 @@ void BlockBusItem::simplify(bool full) {
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::adjustLine() {
|
||||
}
|
||||
void BlockBusItem::adjustLine() {}
|
||||
|
||||
|
||||
int BlockBusItem::endpointCount() const {
|
||||
@@ -301,16 +312,16 @@ int BlockBusItem::endpointCount() const {
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > BlockBusItem::connectedBlocks() const {
|
||||
QList<BlockItemPin * > pins = connections_.values();
|
||||
QSet<BlockItem * > ret;
|
||||
foreach (BlockItemPin * p, pins)
|
||||
QList<BlockItem *> BlockBusItem::connectedBlocks() const {
|
||||
QList<BlockItemPin *> pins = connections_.values();
|
||||
QSet<BlockItem *> ret;
|
||||
foreach(BlockItemPin * p, pins)
|
||||
ret << p->parent();
|
||||
return ret.values();
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItemPin * > BlockBusItem::connectedPins() const {
|
||||
QList<BlockItemPin *> BlockBusItem::connectedPins() const {
|
||||
return connections_.values();
|
||||
}
|
||||
|
||||
@@ -318,14 +329,14 @@ QList<BlockItemPin * > BlockBusItem::connectedPins() const {
|
||||
BlockBusItem::PointInfo BlockBusItem::pointInfo(QPointF pos) const {
|
||||
PointInfo ret;
|
||||
int pi = -1, si = -1;
|
||||
testPoint(pos, &pi, & si);
|
||||
testPoint(pos, &pi, &si);
|
||||
if (pi < 0 && si < 0) return ret;
|
||||
if (si >= 0) {
|
||||
ret.type = PointInfo::Type::Segment;
|
||||
} else {
|
||||
if (endpoints().contains(pi)) {
|
||||
ret.type = PointInfo::Type::Endpoint;
|
||||
ret.pin = connections_.value(pi, nullptr);
|
||||
ret.pin = connections_.value(pi, nullptr);
|
||||
} else
|
||||
ret.type = PointInfo::Type::Node;
|
||||
}
|
||||
@@ -350,9 +361,8 @@ void BlockBusItem::clearBusState() {
|
||||
|
||||
QByteArray BlockBusItem::save() const {
|
||||
ChunkStream cs;
|
||||
cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen())
|
||||
<< cs.chunk(5, brush()) << 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 << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen()) << cs.chunk(5, brush())
|
||||
<< cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props) << cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale);
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
@@ -369,9 +379,9 @@ void BlockBusItem::load(const QByteArray & data) {
|
||||
case 4: setPen(cs.getData<QPen>()); break;
|
||||
case 5: setBrush(cs.getData<QBrush>()); break;
|
||||
case 6: pol = cs.getData<QPolygonF>(); break;
|
||||
case 7: segments = cs.getData<QList<QPair<int, int> > >(); break;
|
||||
case 8: props = cs.getData<QList<BlockItem::Property> >(); break;
|
||||
case 9: im_bus_scale = cs.getData<double>(); break;
|
||||
case 7: segments = cs.getData<QList<QPair<int, int>>>(); break;
|
||||
case 8: props = cs.getData<QList<BlockItem::Property>>(); break;
|
||||
case 9: im_bus_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() {
|
||||
segments_s = segments;
|
||||
ends_ind_s = ends_ind;
|
||||
ends_s = ends;
|
||||
pol_s = pol;
|
||||
ends_s = ends;
|
||||
pol_s = pol;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::restoreState() {
|
||||
segments = segments_s;
|
||||
ends_ind = ends_ind_s;
|
||||
ends = ends_s;
|
||||
pol = pol_s;
|
||||
ends = ends_s;
|
||||
pol = pol_s;
|
||||
}
|
||||
|
||||
|
||||
@@ -429,8 +439,8 @@ bool BlockBusItem::checkDelete() {
|
||||
|
||||
|
||||
void BlockBusItem::emitAction(BlockItemBase::Action a) {
|
||||
qobject_cast<BlockView*>(scene()->views().back())->schemeAction(a, QList<QGraphicsItem*>() << this);
|
||||
qobject_cast<BlockView*>(scene()->views().back())->connectionsChanged();
|
||||
qobject_cast<BlockView *>(scene()->views().back())->schemeAction(a, QList<QGraphicsItem *>() << this);
|
||||
qobject_cast<BlockView *>(scene()->views().back())->connectionsChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -441,8 +451,7 @@ QVector<int> BlockBusItem::endpoints() const {
|
||||
counts[segments[i].second]++;
|
||||
}
|
||||
for (int i = 0; i < counts.size(); ++i) {
|
||||
if (counts[i] == 1)
|
||||
ret << i;
|
||||
if (counts[i] == 1) ret << i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -455,16 +464,16 @@ QVector<int> BlockBusItem::endpointLine(int ep, double angle) const {
|
||||
if (ep < 0 || np < 0) return ret;
|
||||
if (pol[np] == pol[ep]) return ret;
|
||||
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;
|
||||
//qDebug() << "check next" << segments.size();
|
||||
// qDebug() << "check next" << segments.size();
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
//qDebug() << i << np << pointSegmentsCount(np);
|
||||
// qDebug() << i << np << pointSegmentsCount(np);
|
||||
if (np < 0) break;
|
||||
if (pointSegmentsCount(np) != 2) break;
|
||||
if (i > 0) {
|
||||
QLineF l(pol[pp], pol[np]);
|
||||
//qDebug() << i << l.angle() << angle;
|
||||
// qDebug() << i << l.angle() << angle;
|
||||
if (qAbs(l.angle() - angle) > 0.1) break;
|
||||
}
|
||||
ret << np;
|
||||
@@ -472,7 +481,6 @@ QVector<int> BlockBusItem::endpointLine(int ep, double angle) const {
|
||||
np = neighborSegmentPoint(np, &seg);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -492,8 +500,14 @@ int BlockBusItem::neighborSegmentPoint(int point, int * seg) const {
|
||||
if (point < 0 || !seg) return -1;
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (i == *seg) continue;
|
||||
if (segments[i].first == point) {*seg = i; return segments[i].second;}
|
||||
if (segments[i].second == point) {*seg = i; return segments[i].first ;}
|
||||
if (segments[i].first == point) {
|
||||
*seg = i;
|
||||
return segments[i].second;
|
||||
}
|
||||
if (segments[i].second == point) {
|
||||
*seg = i;
|
||||
return segments[i].first;
|
||||
}
|
||||
}
|
||||
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 {
|
||||
for (int i = 0; i < pol.size(); ++i) {
|
||||
if ((pol[i] - pos).manhattanLength() <= (for_trace ? 5. : 10.)) { // Point
|
||||
*sel_point = i;
|
||||
*sel_point = i;
|
||||
*sel_segment = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
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;
|
||||
return;
|
||||
}
|
||||
}
|
||||
*sel_point = -1;
|
||||
*sel_point = -1;
|
||||
*sel_segment = -1;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
|
||||
tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n")
|
||||
+ tr("Add point: Ctrl + LeftClick\n"
|
||||
"Remove point\\segment: Ctrl + RightClick\n"
|
||||
"Remove connection: Shift + RightClick\n"
|
||||
"Move point\\segment: Shift + LeftPress\n"
|
||||
"Change trace mode: press Shift, when mouse move");
|
||||
tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n") +
|
||||
tr("Add point: Ctrl + LeftClick\n"
|
||||
"Remove point\\segment: Ctrl + RightClick\n"
|
||||
"Remove connection: Shift + RightClick\n"
|
||||
"Move point\\segment: Shift + LeftPress\n"
|
||||
"Change trace mode: press Shift, when mouse move");
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
if (temp_) return;
|
||||
QPointF sp = e->scenePos();
|
||||
int pp = selPoint;
|
||||
int ps = selSegment;
|
||||
bool empt = !(selPoint >= 0 || selSegment >= 0);
|
||||
int pp = selPoint;
|
||||
int ps = selSegment;
|
||||
bool empt = !(selPoint >= 0 || selSegment >= 0);
|
||||
testPoint(sp, &selPoint, &selSegment);
|
||||
BlockView * bv = 0;
|
||||
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->isBlockAnimationEnabled()) {
|
||||
setPointSize(0);
|
||||
anim_point_size.start();
|
||||
}
|
||||
} else setPointSize(anim_point_size.endValue().toDouble());
|
||||
} else
|
||||
setPointSize(anim_point_size.endValue().toDouble());
|
||||
}
|
||||
|
||||
if (selPoint >= 0 || selSegment >= 0) {
|
||||
if (empt) {
|
||||
QList<BlockItemPin * > pins = connectedPins();
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
QList<BlockItemPin *> pins = connectedPins();
|
||||
foreach(BlockItemPin * p, pins) {
|
||||
p->animAccept();
|
||||
}
|
||||
}
|
||||
@@ -563,15 +578,15 @@ void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
}
|
||||
if (bv) bv->cur_bus = 0;
|
||||
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;
|
||||
for (int i = 0; i < il.size(); ++i) {
|
||||
QGraphicsItem * b = il[i];
|
||||
if ((b->data(bvidType).toInt() == bvitBus) && b != this) {
|
||||
int tp = -1, ts = -1;
|
||||
((BlockBusItem*)b)->testPoint(sp, &tp, &ts);
|
||||
((BlockBusItem *)b)->testPoint(sp, &tp, &ts);
|
||||
if (tp >= 0 || ts >= 0) {
|
||||
foreach (QGraphicsItem * b2, bil)
|
||||
foreach(QGraphicsItem * b2, bil)
|
||||
b2->stackBefore(b);
|
||||
break;
|
||||
}
|
||||
@@ -585,14 +600,13 @@ void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
if (temp_) return;
|
||||
selPoint = selSegment = -1;
|
||||
setPen(pu); setBrush(bu);
|
||||
setPen(pu);
|
||||
setBrush(bu);
|
||||
setToolTip(QString());
|
||||
anim_point_size.stop();
|
||||
BlockView * bv = 0;
|
||||
if (!scene()->views().isEmpty())
|
||||
bv = qobject_cast<BlockView*>(scene()->views().back());
|
||||
if (bv && (QApplication::mouseButtons() == 0))
|
||||
bv->cur_bus = 0;
|
||||
if (!scene()->views().isEmpty()) bv = qobject_cast<BlockView *>(scene()->views().back());
|
||||
if (bv && (QApplication::mouseButtons() == 0)) bv->cur_bus = 0;
|
||||
update();
|
||||
QGraphicsObject::hoverLeaveEvent(e);
|
||||
}
|
||||
@@ -601,18 +615,16 @@ void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
|
||||
if (temp_) return;
|
||||
lp = quantize(e->scenePos(), grid_step);
|
||||
if (e->button() != Qt::RightButton)
|
||||
bpol = pol;
|
||||
if (e->button() != Qt::RightButton) bpol = pol;
|
||||
BlockView * bv = 0;
|
||||
if (!scene()->views().isEmpty()) {
|
||||
bv = qobject_cast<BlockView*>(scene()->views().back());
|
||||
bv = qobject_cast<BlockView *>(scene()->views().back());
|
||||
}
|
||||
if (bv) {
|
||||
if (selPoint >= 0 || selSegment >= 0)
|
||||
bv->cur_bus = this;
|
||||
if (selPoint >= 0 || selSegment >= 0) bv->cur_bus = this;
|
||||
}
|
||||
if (new_segment) {
|
||||
qobject_cast<BlockView*>(scene()->views().back())->newBranchCancel();
|
||||
qobject_cast<BlockView *>(scene()->views().back())->newBranchCancel();
|
||||
}
|
||||
new_segment = false;
|
||||
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;
|
||||
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_MID_BUTTON )) btncnt++;
|
||||
if (e->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
|
||||
if (btncnt > 0) mm_mods = e->modifiers();
|
||||
if (btncnt >= 2 && e->button() == Qt::RightButton) {
|
||||
//qDebug() << "bus revert";
|
||||
// qDebug() << "bus revert";
|
||||
mm_cancel = true;
|
||||
moved = false;
|
||||
pol = bpol;
|
||||
moved = false;
|
||||
pol = bpol;
|
||||
prepareGeometryChange();
|
||||
return;
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) {
|
||||
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 {
|
||||
if (selPoint >= 0)
|
||||
press_pos = pol[selPoint];
|
||||
@@ -646,10 +659,9 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
|
||||
}
|
||||
if (max_ep >= 2) {
|
||||
if (endpointCount() >= max_ep)
|
||||
if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0)
|
||||
return;
|
||||
if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) return;
|
||||
}
|
||||
qobject_cast<BlockView*>(scene()->views().back())->newBranch(this);
|
||||
qobject_cast<BlockView *>(scene()->views().back())->newBranch(this);
|
||||
new_segment = true;
|
||||
return;
|
||||
}
|
||||
@@ -657,7 +669,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
|
||||
deleteLater();
|
||||
}
|
||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
//qDebug() << "remove" << selPoint << selSegment;
|
||||
// qDebug() << "remove" << selPoint << selSegment;
|
||||
if (e->buttons().testFlag(Qt::RightButton)) {
|
||||
if (selPoint >= 0 && selPoint <= pol.size() - 1) {
|
||||
removePoint(selPoint);
|
||||
@@ -673,8 +685,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
|
||||
}
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) {
|
||||
if (addPoint(e->scenePos()) >= 0)
|
||||
emitAction(BlockItemBase::BusPointAdd);
|
||||
if (addPoint(e->scenePos()) >= 0) emitAction(BlockItemBase::BusPointAdd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -693,12 +704,12 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
|
||||
}
|
||||
BlockView * bv = 0;
|
||||
if (!scene()->views().isEmpty()) {
|
||||
bv = qobject_cast<BlockView*>(scene()->views().back());
|
||||
bv = qobject_cast<BlockView *>(scene()->views().back());
|
||||
}
|
||||
qp = quantize(e->scenePos(), grid_step);
|
||||
lp = qp - lp;
|
||||
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;
|
||||
}
|
||||
if (new_segment) {
|
||||
@@ -707,8 +718,7 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
|
||||
} else {
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) {
|
||||
lm_point = selPoint >= 0;
|
||||
if (selPoint >= 0 && selPoint <= pol.size() - 1)
|
||||
pol[selPoint] += lp;
|
||||
if (selPoint >= 0 && selPoint <= pol.size() - 1) pol[selPoint] += lp;
|
||||
if (selSegment >= 0 && selSegment <= segments.size() - 1) {
|
||||
pol[segments[selSegment].first] += lp;
|
||||
pol[segments[selSegment].second] += lp;
|
||||
@@ -722,14 +732,14 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
|
||||
|
||||
|
||||
void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) {
|
||||
mm_mods = Qt::KeyboardModifiers();
|
||||
mm_mods = Qt::KeyboardModifiers();
|
||||
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_MID_BUTTON )) btncnt++;
|
||||
if (e->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
|
||||
if (btncnt == 0) mm_cancel = false;
|
||||
if (new_segment) {
|
||||
qobject_cast<BlockView*>(scene()->views().back())->newBranchAccept(this);
|
||||
qobject_cast<BlockView *>(scene()->views().back())->newBranchAccept(this);
|
||||
updateGeometry();
|
||||
selPoint = selSegment = -1;
|
||||
}
|
||||
@@ -739,7 +749,7 @@ void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) {
|
||||
emitAction(BlockItemBase::BusPointMove);
|
||||
} else {
|
||||
reconnect();
|
||||
emitAction( BlockItemBase::BusSegmentMove);
|
||||
emitAction(BlockItemBase::BusSegmentMove);
|
||||
}
|
||||
}
|
||||
moved = new_segment = false;
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKBUSITEM_H
|
||||
@@ -24,15 +24,18 @@
|
||||
#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_INTERFACES(QGraphicsItem)
|
||||
Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false)
|
||||
friend class BlockView;
|
||||
|
||||
public:
|
||||
BlockBusItem(bool temp = false);
|
||||
BlockBusItem(const BlockBusItem & other);
|
||||
~BlockBusItem() {;}
|
||||
~BlockBusItem() { ; }
|
||||
|
||||
struct QAD_BLOCKVIEW_EXPORT PointInfo {
|
||||
enum class Type {
|
||||
@@ -41,30 +44,46 @@ public:
|
||||
Endpoint,
|
||||
Segment
|
||||
};
|
||||
Type type = Type::None;
|
||||
Type type = Type::None;
|
||||
BlockItemPin * pin = nullptr; // if tEndpoint and pin connected
|
||||
};
|
||||
|
||||
void setGridStep(double gs) {grid_step = gs;}
|
||||
void setEndpointsNumber(int num) {max_ep = num;}
|
||||
void setImages(const QImage & bus, const QImage & end = QImage()) {im_bus = bus; im_end = end; update();}
|
||||
void setBusImageScale(double s) {im_bus_scale = s; update();}
|
||||
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 setGridStep(double gs) { grid_step = gs; }
|
||||
void setEndpointsNumber(int num) { max_ep = num; }
|
||||
void setImages(const QImage & bus, const QImage & end = QImage()) {
|
||||
im_bus = bus;
|
||||
im_end = end;
|
||||
update();
|
||||
}
|
||||
void setBusImageScale(double s) {
|
||||
im_bus_scale = s;
|
||||
update();
|
||||
}
|
||||
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(qreal x, qreal y);
|
||||
void movePolyline(const QPointF & dp);
|
||||
void clear();
|
||||
void setPen(const QPen & p) {p_ = p; update();}
|
||||
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 setPen(const QPen & p) {
|
||||
p_ = p;
|
||||
update();
|
||||
}
|
||||
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 setColor(const QColor & c);
|
||||
void setSquareNodes(bool yes);
|
||||
@@ -74,24 +93,26 @@ public:
|
||||
void simplify(bool full = true);
|
||||
void adjustLine();
|
||||
int endpointCount() const;
|
||||
bool isBusSelected() const {return selSegment >= 0 || selPoint >= 0;}
|
||||
QList<BlockItem * > connectedBlocks() const;
|
||||
QList<BlockItemPin * > connectedPins() const;
|
||||
bool isBusSelected() const { return selSegment >= 0 || selPoint >= 0; }
|
||||
QList<BlockItem *> connectedBlocks() const;
|
||||
QList<BlockItemPin *> connectedPins() const;
|
||||
PointInfo pointInfo(QPointF pos) const;
|
||||
|
||||
|
||||
void setBusState(bool state);
|
||||
bool busState() const {return state_ > 0;}
|
||||
bool busState() const { return state_ > 0; }
|
||||
void clearBusState();
|
||||
|
||||
|
||||
QByteArray save() const;
|
||||
void load(const QByteArray & data);
|
||||
BlockBusItem * copy() const;
|
||||
|
||||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
enum {Type = UserType + 2};
|
||||
|
||||
|
||||
enum {
|
||||
Type = UserType + 2
|
||||
};
|
||||
|
||||
protected:
|
||||
void _init();
|
||||
void reconnect();
|
||||
@@ -108,7 +129,7 @@ protected:
|
||||
QVector<int> endpoints() const;
|
||||
QVector<int> endpointLine(int ep, double angle) const;
|
||||
int neighborSegmentPoint(int point, int * seg) const;
|
||||
int type() const {return Type;}
|
||||
int type() const { return Type; }
|
||||
QRectF boundingRect() const;
|
||||
bool sceneEvent(QEvent * e);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
|
||||
@@ -118,13 +139,13 @@ protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * e);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent * e);
|
||||
void paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w = 0);
|
||||
|
||||
|
||||
QPointF lp, new_start, new_end, press_pos, qp;
|
||||
QPen p_, ph, pu, pa, pr, pn;
|
||||
QBrush b_, bh, bu, ba, br;
|
||||
QString tt, bus_name;
|
||||
QList<QPair<int, int> > segments, ends_ind, segments_s, ends_ind_s;
|
||||
QMap<int, BlockItemPin * > connections_;
|
||||
QList<QPair<int, int>> segments, ends_ind, segments_s, ends_ind_s;
|
||||
QMap<int, BlockItemPin *> connections_;
|
||||
QVector<int> ends, ends_s;
|
||||
QImage im_bus, im_end;
|
||||
QPolygonF pol, bpol, pol_s;
|
||||
@@ -133,9 +154,9 @@ protected:
|
||||
double pen_width, grid_step, im_bus_scale, im_end_scale;
|
||||
int selPoint, selSegment, max_ep, bus_type, state_;
|
||||
bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point;
|
||||
|
||||
|
||||
private:
|
||||
double pointSize() const {return point_size;}
|
||||
double pointSize() const { return point_size; }
|
||||
void setPointSize(double s);
|
||||
|
||||
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, BlockBusItem *& b) {
|
||||
QByteArray ba; s >> ba;
|
||||
inline QDataStream & operator<<(QDataStream & s, const BlockBusItem * b) {
|
||||
s << b->save();
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator>>(QDataStream & s, BlockBusItem *& b) {
|
||||
QByteArray ba;
|
||||
s >> ba;
|
||||
b = new BlockBusItem();
|
||||
b->load(ba);
|
||||
return s;
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#include "blockeditor.h"
|
||||
#include "ui_blockeditor.h"
|
||||
#include "drawtools.h"
|
||||
|
||||
#include "blockview.h"
|
||||
#include <QToolBar>
|
||||
#include "drawtools.h"
|
||||
#include "ui_blockeditor.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QTimer>
|
||||
#include <QToolBar>
|
||||
|
||||
|
||||
BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEditor) {
|
||||
init = false;
|
||||
m_editorMode = false;
|
||||
BlockEditor::BlockEditor(QWidget * parent): QWidget(parent), ui(new Ui::BlockEditor) {
|
||||
init = false;
|
||||
m_editorMode = false;
|
||||
m_pinsEditable = true;
|
||||
ui->setupUi(this);
|
||||
src_title = windowTitle();
|
||||
@@ -20,13 +22,15 @@ BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEdi
|
||||
ui->blockView->addItem(&block);
|
||||
ui->blockView->viewport()->installEventFilter(this);
|
||||
DrawTools * drawtools = new DrawTools(ui->blockView);
|
||||
connect(drawtools, SIGNAL(itemCreated(QGraphicsItem*)), this, SLOT(addItem(QGraphicsItem*)));
|
||||
drawtools->textEditCombo()->addItems(QStringList() << "%name" << "%value" << "%id");
|
||||
connect(drawtools, SIGNAL(itemCreated(QGraphicsItem *)), this, SLOT(addItem(QGraphicsItem *)));
|
||||
drawtools->textEditCombo()->addItems(QStringList() << "%name"
|
||||
<< "%value"
|
||||
<< "%id");
|
||||
ui->layoutProperties->addWidget(drawtools->propertyWidget());
|
||||
ui->actionRemove_items->setEnabled(false);
|
||||
ui->button_color->setColor(Qt::lightGray);
|
||||
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);
|
||||
|
||||
QToolBar * bar;
|
||||
@@ -39,7 +43,7 @@ BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEdi
|
||||
bar->setOrientation(Qt::Vertical);
|
||||
bar->addActions(drawtools->actionsForZ());
|
||||
bar->addSeparator();
|
||||
bar->addActions(QList<QAction*>() << ui->actionRemove_items);
|
||||
bar->addActions(QList<QAction *>() << ui->actionRemove_items);
|
||||
ui->widgetBarZ->setMinimumSize(bar->sizeHint());
|
||||
init = true;
|
||||
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;
|
||||
b.loadModel(model);
|
||||
ui->spin_w->setValue(b.width());
|
||||
@@ -74,15 +78,15 @@ void BlockEditor::loadModel(const QByteArray &model) {
|
||||
block.loadModel(model);
|
||||
treePinsClear();
|
||||
ui->treePins->blockSignals(true);
|
||||
QVector<BlockItemPin * > pins = block.pins();
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
QVector<BlockItemPin *> pins = block.pins();
|
||||
foreach(BlockItemPin * p, pins) {
|
||||
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << p->text() << QString::number(p->busType()));
|
||||
ti->setData(0, Qt::UserRole, qulonglong(p));
|
||||
ti->setData(0, Qt::UserRole + 1, (int)p->alignment());
|
||||
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
||||
pin_tli[p->alignment()]->addChild(ti);
|
||||
}
|
||||
foreach (QGraphicsItem * i, block.decors()) {
|
||||
foreach(QGraphicsItem * i, block.decors()) {
|
||||
i->setData(bvidMoveParent, false);
|
||||
i->setData(bvidCorrectMove, true);
|
||||
}
|
||||
@@ -121,7 +125,7 @@ void BlockEditor::selectionChanged() {
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::addItem(QGraphicsItem *item) {
|
||||
void BlockEditor::addItem(QGraphicsItem * item) {
|
||||
block.addDecor(item);
|
||||
item->setData(bvidMoveParent, false);
|
||||
item->setData(bvidCorrectMove, true);
|
||||
@@ -138,9 +142,13 @@ void BlockEditor::updateBlock() {
|
||||
void BlockEditor::treePinsClear() {
|
||||
ui->treePins->blockSignals(true);
|
||||
ui->treePins->clear();
|
||||
QFont bf(font()); bf.setBold(true);
|
||||
QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom;
|
||||
QStringList an = QStringList() << "Left" << "Right" << "Top" << "Bottom";
|
||||
QFont bf(font());
|
||||
bf.setBold(true);
|
||||
QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom;
|
||||
QStringList an = QStringList() << "Left"
|
||||
<< "Right"
|
||||
<< "Top"
|
||||
<< "Bottom";
|
||||
pin_tli.clear();
|
||||
for (int i = 0; i < al.size(); ++i) {
|
||||
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 (o == ui->treePins->viewport()) {
|
||||
if (e->type() == QEvent::Drop) {
|
||||
@@ -176,17 +184,15 @@ bool BlockEditor::eventFilter(QObject *o, QEvent *e) {
|
||||
void BlockEditor::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
break;
|
||||
case QEvent::LanguageChange: ui->retranslateUi(this); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_actionRemove_items_triggered() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
foreach (QGraphicsItem * i, si)
|
||||
QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
|
||||
foreach(QGraphicsItem * i, si)
|
||||
block.removeDecor(i);
|
||||
}
|
||||
|
||||
@@ -233,10 +239,10 @@ void BlockEditor::on_buttonClear_clicked() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlockEditor::on_buttonPinAdd_clicked() {
|
||||
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->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);
|
||||
@@ -265,10 +271,10 @@ void BlockEditor::on_buttonPinDup_clicked() {
|
||||
|
||||
void BlockEditor::on_buttonPinDelete_clicked() {
|
||||
ui->treePins->blockSignals(true);
|
||||
QList<QTreeWidgetItem*> si = ui->treePins->selectedItems();
|
||||
foreach (QTreeWidgetItem * i, si) {
|
||||
QList<QTreeWidgetItem *> si = ui->treePins->selectedItems();
|
||||
foreach(QTreeWidgetItem * i, si) {
|
||||
if (!i->parent()) continue;
|
||||
block.removePin((BlockItemPin*)(i->data(0, Qt::UserRole).toLongLong()));
|
||||
block.removePin((BlockItemPin *)(i->data(0, Qt::UserRole).toLongLong()));
|
||||
delete i;
|
||||
}
|
||||
ui->treePins->blockSignals(false);
|
||||
@@ -283,7 +289,7 @@ void BlockEditor::on_buttonPinClear_clicked() {
|
||||
|
||||
void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
|
||||
if (!item) return;
|
||||
BlockItemPin * pin = (BlockItemPin*)item->data(0, Qt::UserRole).toULongLong();
|
||||
BlockItemPin * pin = (BlockItemPin *)item->data(0, Qt::UserRole).toULongLong();
|
||||
if (!pin) return;
|
||||
switch (column) {
|
||||
case 0:
|
||||
@@ -297,16 +303,15 @@ void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlockEditor::arrangePins() {
|
||||
QVector<BlockItemPin * > pins = block.pins();
|
||||
QList<QTreeWidgetItem*> tli = pin_tli.values();
|
||||
foreach (QTreeWidgetItem * ti, tli) {
|
||||
QVector<BlockItemPin *> pins = block.pins();
|
||||
QList<QTreeWidgetItem *> tli = pin_tli.values();
|
||||
foreach(QTreeWidgetItem * ti, tli) {
|
||||
for (int i = 0; i < ti->childCount(); ++i) {
|
||||
foreach (BlockItemPin * p, pins)
|
||||
if (p == (BlockItemPin*)(ti->child(i)->data(0, Qt::UserRole).toULongLong())) {
|
||||
foreach(BlockItemPin * p, pins)
|
||||
if (p == (BlockItemPin *)(ti->child(i)->data(0, Qt::UserRole).toULongLong())) {
|
||||
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 + 1, ti->data(0, Qt::UserRole).toInt());
|
||||
break;
|
||||
@@ -325,11 +330,15 @@ void BlockEditor::arrangePins() {
|
||||
|
||||
QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
QComboBox * combo = new QComboBox(parent);
|
||||
int cv = index.data().toInt();
|
||||
combo->addItem("Left", int(Qt::AlignLeft)); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0);
|
||||
combo->addItem("Right", int(Qt::AlignRight)); 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);
|
||||
int cv = index.data().toInt();
|
||||
combo->addItem("Left", int(Qt::AlignLeft));
|
||||
if (cv == Qt::AlignLeft) combo->setCurrentIndex(0);
|
||||
combo->addItem("Right", int(Qt::AlignRight));
|
||||
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);
|
||||
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 {
|
||||
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 {
|
||||
model->setData(index, ((QSpinBox*)editor)->value());
|
||||
model->setData(index, ((QSpinBox *)editor)->value());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKEDITOR_H
|
||||
#define BLOCKEDITOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QStyledItemDelegate>
|
||||
#include "blockitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class BlockEditor;
|
||||
class BlockEditor;
|
||||
}
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockEditor : public QWidget
|
||||
{
|
||||
class QAD_BLOCKVIEW_EXPORT BlockEditor: public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool editorMode READ editorMode WRITE setEditorMode)
|
||||
Q_PROPERTY(bool pinsEditable READ pinsEditable WRITE setPinsEditable)
|
||||
|
||||
public:
|
||||
explicit BlockEditor(QWidget *parent = 0);
|
||||
explicit BlockEditor(QWidget * parent = 0);
|
||||
~BlockEditor();
|
||||
|
||||
|
||||
bool editorMode() const {return m_editorMode;}
|
||||
bool pinsEditable() const {return m_pinsEditable;}
|
||||
bool editorMode() const { return m_editorMode; }
|
||||
bool pinsEditable() const { return m_pinsEditable; }
|
||||
|
||||
public slots:
|
||||
void loadFile(QString path);
|
||||
@@ -67,14 +68,14 @@ private slots:
|
||||
void on_buttonPinDup_clicked();
|
||||
void on_buttonPinDelete_clicked();
|
||||
void on_buttonPinClear_clicked();
|
||||
void on_treePins_itemChanged(QTreeWidgetItem *item, int column);
|
||||
void on_treePins_itemChanged(QTreeWidgetItem * item, int column);
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
Ui::BlockEditor *ui;
|
||||
QMap<int, QTreeWidgetItem*> pin_tli;
|
||||
Ui::BlockEditor * ui;
|
||||
QMap<int, QTreeWidgetItem *> pin_tli;
|
||||
BlockItem block;
|
||||
QString src_title, cur_file;
|
||||
bool init;
|
||||
@@ -83,26 +84,28 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT PinAlignDelegate: public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QString displayText(const QVariant & value, const QLocale & locale) 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 {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QString displayText(const QVariant & value, const QLocale & locale) 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:
|
||||
typedef QPair<int, QString> ISPair;
|
||||
QVector<ISPair> buses;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "blockview.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
#define BLOCKITEM_DEFAULT_PIN_MARGIN 20
|
||||
|
||||
BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(),
|
||||
g_main(this), g_selection(this) {
|
||||
BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(), g_main(this), g_selection(this) {
|
||||
setData(bvidType, bvitBlock);
|
||||
setZValue(2.);
|
||||
setAcceptHoverEvents(true);
|
||||
@@ -58,11 +58,9 @@ void BlockItem::_resize(QSizeF s) {
|
||||
|
||||
void BlockItem::_moveToTop(bool only_decors) {
|
||||
qreal dy = -g_main.rect().center().y() + 10;
|
||||
if (!only_decors)
|
||||
moveBy(0., dy);
|
||||
foreach (QGraphicsItem * d, decors_)
|
||||
if (!only_decors) moveBy(0., dy);
|
||||
foreach(QGraphicsItem * d, decors_)
|
||||
d->moveBy(0., -dy);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -70,30 +68,27 @@ BlockItemPin * BlockItem::addPin(BlockItemPin * pin, bool update_) {
|
||||
pin->setParentItem(this);
|
||||
if (!pins_[pin->alignment()].contains(pin)) pins_[pin->alignment()] << pin;
|
||||
pin->parent_ = this;
|
||||
if (update_)
|
||||
arrangePins();
|
||||
if (update_) arrangePins();
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::addPin(Qt::Alignment align, int bus_type, const QString & text, bool update_) {
|
||||
BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this);
|
||||
pin->parent_ = this;
|
||||
pin->parent_ = this;
|
||||
pins_[pin->alignment()] << pin;
|
||||
if (update_)
|
||||
arrangePins();
|
||||
if (update_) arrangePins();
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::removePin(BlockItemPin * pin) {
|
||||
if (!pin) return;
|
||||
QMutableMapIterator<Qt::Alignment, QVector<BlockItemPin * > > it(pins_);
|
||||
QMutableMapIterator<Qt::Alignment, QVector<BlockItemPin *>> it(pins_);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QVector<BlockItemPin * > & pv(it.value());
|
||||
if (pv.contains(pin))
|
||||
pv.remove(it.value().indexOf(pin));
|
||||
QVector<BlockItemPin *> & pv(it.value());
|
||||
if (pv.contains(pin)) pv.remove(it.value().indexOf(pin));
|
||||
}
|
||||
delete pin;
|
||||
arrangePins();
|
||||
@@ -102,12 +97,13 @@ void BlockItem::removePin(BlockItemPin * pin) {
|
||||
|
||||
void BlockItem::addDecor(QGraphicsItem * item) {
|
||||
if (decors_.contains(item)) return;
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem*>(item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->setData(bvidDecorText, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem*>(item))
|
||||
qgraphicsitem_cast<AlignedTextItem*>(item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem*>(item)->text());
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem *>(item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)->setData(bvidDecorText,
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem *>(item))
|
||||
qgraphicsitem_cast<AlignedTextItem *>(item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(item)->text());
|
||||
item->setData(bvidMoveParent, true);
|
||||
item->setData(bvidBlockDecor, true);
|
||||
decors_ << item;
|
||||
@@ -117,12 +113,13 @@ void BlockItem::addDecor(QGraphicsItem * item) {
|
||||
|
||||
void BlockItem::addDecor(QGraphicsItem & item) {
|
||||
if (decors_.contains(&item)) return;
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(&item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem*>(&item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->setData(bvidDecorText, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem*>(&item))
|
||||
qgraphicsitem_cast<AlignedTextItem*>(&item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem*>(&item)->text());
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(&item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem *>(&item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)->setData(bvidDecorText,
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem *>(&item))
|
||||
qgraphicsitem_cast<AlignedTextItem *>(&item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(&item)->text());
|
||||
item.setData(bvidMoveParent, true);
|
||||
item.setData(bvidBlockDecor, true);
|
||||
item.setParentItem(this);
|
||||
@@ -130,22 +127,21 @@ void BlockItem::addDecor(QGraphicsItem & item) {
|
||||
|
||||
|
||||
void BlockItem::removeDecor(QGraphicsItem * item) {
|
||||
if (scene() && item)
|
||||
scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
|
||||
if (scene() && item) scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
|
||||
decors_.removeAll(item);
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
QVector<BlockItemPin * > BlockItem::takePins() {
|
||||
QVector<BlockItemPin * > ret = pins();
|
||||
QVector<BlockItemPin *> BlockItem::takePins() {
|
||||
QVector<BlockItemPin *> ret = pins();
|
||||
pins_.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::clearPins() {
|
||||
QList<QVector<BlockItemPin * > > mp = pins_.values();
|
||||
QList<QVector<BlockItemPin *>> mp = pins_.values();
|
||||
for (int i = 0; i < mp.size(); ++i)
|
||||
qDeleteAll(mp[i]);
|
||||
pins_.clear();
|
||||
@@ -156,7 +152,7 @@ void BlockItem::clearDecors() {
|
||||
bool pbs = false;
|
||||
if (scene()) pbs = scene()->blockSignals(true);
|
||||
if (scene()) {
|
||||
foreach (QGraphicsItem * i, decors_)
|
||||
foreach(QGraphicsItem * i, decors_)
|
||||
scene()->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
|
||||
}
|
||||
qDeleteAll(decors_);
|
||||
@@ -168,9 +164,9 @@ void BlockItem::clearDecors() {
|
||||
}
|
||||
|
||||
|
||||
QVector<BlockItemPin * > BlockItem::pins() const {
|
||||
QList<QVector<BlockItemPin * > > mp = pins_.values();
|
||||
QVector<BlockItemPin * > ret;
|
||||
QVector<BlockItemPin *> BlockItem::pins() const {
|
||||
QList<QVector<BlockItemPin *>> mp = pins_.values();
|
||||
QVector<BlockItemPin *> ret;
|
||||
for (int i = 0; i < mp.size(); ++i)
|
||||
ret << mp[i];
|
||||
return ret;
|
||||
@@ -186,15 +182,15 @@ QByteArray BlockItem::saveModel() {
|
||||
|
||||
|
||||
void BlockItem::loadModel(const QByteArray & data) {
|
||||
//qDebug() << "load from" << data.size() << "bytes";
|
||||
// qDebug() << "load from" << data.size() << "bytes";
|
||||
clearPins();
|
||||
clearDecors();
|
||||
col = Qt::lightGray;
|
||||
_resize(QSizeF(100., 60.));
|
||||
if (data.isEmpty()) return;
|
||||
ChunkStream cs(data);
|
||||
QVector<BlockItemPin * > tp;
|
||||
QList<QGraphicsItem * > dl;
|
||||
QVector<BlockItemPin *> tp;
|
||||
QList<QGraphicsItem *> dl;
|
||||
int version = -1;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
@@ -204,30 +200,32 @@ void BlockItem::loadModel(const QByteArray & data) {
|
||||
case 4: setColor(cs.getData<QColor>()); break;
|
||||
case 5:
|
||||
cs.get(tp);
|
||||
foreach (BlockItemPin * p, tp) addPin(p);
|
||||
foreach(BlockItemPin * p, tp)
|
||||
addPin(p);
|
||||
break;
|
||||
case 6:
|
||||
cs.get(dl);
|
||||
foreach (QGraphicsItem * d, dl) addDecor(d);
|
||||
foreach(QGraphicsItem * d, dl)
|
||||
addDecor(d);
|
||||
break;
|
||||
case 7: setPinsMargin(cs.getData<int>()); break;
|
||||
case 0xFF: cs.get(version); break;
|
||||
}
|
||||
}
|
||||
if (version <= 0)
|
||||
_moveToTop(true);
|
||||
if (version <= 0) _moveToTop(true);
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockItem::save() const {
|
||||
ChunkStream cs;
|
||||
QMap<QString, QList<BlockItem::Property> > pp;
|
||||
foreach (BlockItemPin * p, pins()) {
|
||||
//qDebug() << "save pin" << p->text() << "->" << p->properties().size();
|
||||
QMap<QString, QList<BlockItem::Property>> pp;
|
||||
foreach(BlockItemPin * p, pins()) {
|
||||
// qDebug() << "save pin" << p->text() << "->" << p->properties().size();
|
||||
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(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();
|
||||
}
|
||||
|
||||
@@ -235,7 +233,7 @@ QByteArray BlockItem::save() const {
|
||||
void BlockItem::load(const QByteArray & data) {
|
||||
if (data.isEmpty()) return;
|
||||
ChunkStream cs(data);
|
||||
QMap<QString, QList<BlockItem::Property> > _p;
|
||||
QMap<QString, QList<BlockItem::Property>> _p;
|
||||
int version = -1;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
@@ -244,17 +242,16 @@ void BlockItem::load(const QByteArray & data) {
|
||||
case 3: cs.get(props); break;
|
||||
case 5:
|
||||
cs.get(_p);
|
||||
//qDebug() << "load pins" << _p.size();
|
||||
foreach (BlockItemPin * p, pins()) {
|
||||
//qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text());
|
||||
if (_p.contains(p->text()))
|
||||
p->properties() = _p[p->text()];
|
||||
// qDebug() << "load pins" << _p.size();
|
||||
foreach(BlockItemPin * p, pins()) {
|
||||
// qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text());
|
||||
if (_p.contains(p->text())) p->properties() = _p[p->text()];
|
||||
}
|
||||
break;
|
||||
case 6: setSize(cs.getData<QSizeF>()); break;
|
||||
case 10: setData(2000, 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;
|
||||
}
|
||||
}
|
||||
@@ -272,8 +269,8 @@ BlockItem * BlockItem::copy() const {
|
||||
ret->setSelected(false);
|
||||
ret->props = props;
|
||||
ret->setPinsMargin(pinsMargin());
|
||||
QVector<BlockItemPin * > mp = pins();
|
||||
foreach (BlockItemPin * p, mp) {
|
||||
QVector<BlockItemPin *> mp = pins();
|
||||
foreach(BlockItemPin * p, mp) {
|
||||
BlockItemPin * np = new BlockItemPin();
|
||||
np->setBusType(p->busType());
|
||||
np->setAlignment(p->alignment());
|
||||
@@ -283,39 +280,38 @@ BlockItem * BlockItem::copy() const {
|
||||
ret->addPin(np);
|
||||
}
|
||||
QByteArray ba;
|
||||
foreach (QGraphicsItem * i, decors_) {
|
||||
foreach(QGraphicsItem * i, decors_) {
|
||||
ba.clear();
|
||||
QGraphicsItem * ni = 0;
|
||||
QDataStream s(&ba, QIODevice::ReadWrite); s << i;
|
||||
QDataStream s2(ba); s2 >> ni;
|
||||
if (ni)
|
||||
ret->addDecor(ni);
|
||||
QDataStream s(&ba, QIODevice::ReadWrite);
|
||||
s << i;
|
||||
QDataStream s2(ba);
|
||||
s2 >> ni;
|
||||
if (ni) ret->addDecor(ni);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockItem::connectedBuses() const {
|
||||
QList<BlockBusItem * > ret;
|
||||
foreach (BlockItemPin * p, pins())
|
||||
QList<BlockBusItem *> BlockItem::connectedBuses() const {
|
||||
QList<BlockBusItem *> ret;
|
||||
foreach(BlockItemPin * p, pins())
|
||||
ret << p->connectedBuses();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::pinByText(const QString & t) const {
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (p->text() == t)
|
||||
return p;
|
||||
foreach(BlockItemPin * p, pins())
|
||||
if (p->text() == t) return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const {
|
||||
if (bus == 0) return 0;
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (p->connectedBuses().contains(bus))
|
||||
return p;
|
||||
foreach(BlockItemPin * p, pins())
|
||||
if (p->connectedBuses().contains(bus)) return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -337,7 +333,8 @@ void BlockItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
|
||||
anim_thick.setStartValue(thickness());
|
||||
anim_thick.setEndValue(2.5);
|
||||
anim_thick.start();
|
||||
} else setThickness(2.5);
|
||||
} else
|
||||
setThickness(2.5);
|
||||
emit blockHoverEnter(this);
|
||||
}
|
||||
|
||||
@@ -349,7 +346,8 @@ void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
anim_thick.setStartValue(thickness());
|
||||
anim_thick.setEndValue(1);
|
||||
anim_thick.start();
|
||||
} else setThickness(1);
|
||||
} else
|
||||
setThickness(1);
|
||||
emit blockHoverLeave(this);
|
||||
}
|
||||
|
||||
@@ -357,25 +355,29 @@ void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
#define _POS(m) (i - ((cp.size() - 1) / 2)) * m
|
||||
|
||||
void BlockItem::arrangePins() {
|
||||
QVector<BlockItemPin * > pl = pins();
|
||||
QVector<BlockItemPin *> pl = pins();
|
||||
pins_.clear();
|
||||
foreach (BlockItemPin * p, pl)
|
||||
foreach(BlockItemPin * p, pl)
|
||||
pins_[p->alignment()] << p;
|
||||
QVector<BlockItemPin * > cp = pins_.value(Qt::AlignBottom);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), bottom());
|
||||
QVector<BlockItemPin *> cp = pins_.value(Qt::AlignBottom);
|
||||
for (int i = 0; i < cp.size(); ++i)
|
||||
cp[i]->setPos(_POS(pins_margin), bottom());
|
||||
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);
|
||||
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);
|
||||
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
|
||||
|
||||
|
||||
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) {
|
||||
prop_bindings.removeAt(i);
|
||||
i--;
|
||||
@@ -385,7 +387,7 @@ void BlockItem::removeBindings(const QString & bind_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) {
|
||||
prop_bindings.removeAt(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) {
|
||||
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) {
|
||||
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) {
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
QList<QPair<QString, QString> > BlockItem::getBindings() {
|
||||
QList<QPair<QString, QString>> BlockItem::getBindings() {
|
||||
return prop_bindings;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
return prop_bindings[i].second;
|
||||
}
|
||||
@@ -441,14 +443,14 @@ QString BlockItem::getBindName(const QString & prop_name) const {
|
||||
|
||||
QStringList BlockItem::getBindNames() const {
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList BlockItem::getBindProps() const {
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
@@ -456,7 +458,7 @@ QStringList BlockItem::getBindProps() const {
|
||||
|
||||
QVariant BlockItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
|
||||
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) {
|
||||
g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 16));
|
||||
anim_sel.setStartValue(selectionRect());
|
||||
@@ -490,4 +492,3 @@ QRectF BlockItem::selectionRect() const {
|
||||
void BlockItem::setSelectionRect(const QRectF & r) {
|
||||
g_selection.setRect(r);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKITEM_H
|
||||
#define BLOCKITEM_H
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include "blockitempin.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 BlockItemPin;
|
||||
friend class DrawTools;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false)
|
||||
Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false)
|
||||
|
||||
public:
|
||||
BlockItem(QGraphicsItem * parent = 0);
|
||||
~BlockItem();
|
||||
@@ -44,26 +47,32 @@ public:
|
||||
void addDecor(QGraphicsItem * item);
|
||||
void addDecor(QGraphicsItem & item);
|
||||
void removeDecor(QGraphicsItem * item);
|
||||
QVector<BlockItemPin * > takePins();
|
||||
QVector<BlockItemPin *> takePins();
|
||||
void clearPins();
|
||||
void clearDecors();
|
||||
QVector<BlockItemPin * > pins() const;
|
||||
QList<QGraphicsItem * > decors() const {return decors_;}
|
||||
QList<BlockBusItem * > connectedBuses() const;
|
||||
QVector<BlockItemPin *> pins() const;
|
||||
QList<QGraphicsItem *> decors() const { return decors_; }
|
||||
QList<BlockBusItem *> connectedBuses() const;
|
||||
BlockItemPin * pinByText(const QString & t) const;
|
||||
BlockItemPin * pinAtBus(BlockBusItem * bus) const;
|
||||
QColor color() const {return col;}
|
||||
void setColor(QColor c) {col = c; _resize(size());}
|
||||
QSizeF size() const {return g_main.rect().size();}
|
||||
QColor color() const { return col; }
|
||||
void setColor(QColor c) {
|
||||
col = c;
|
||||
_resize(size());
|
||||
}
|
||||
QSizeF size() const { return g_main.rect().size(); }
|
||||
QRectF sceneRect() const;
|
||||
qreal width() const {return size().width();}
|
||||
qreal height() const {return size().height();}
|
||||
int pinsMargin() const {return pins_margin;}
|
||||
void setSize(QSizeF s) {_resize(s);}
|
||||
void setSize(qreal w, qreal h) {setSize(QSizeF(w, h));}
|
||||
void setWidth(qreal w) {setSize(QSizeF(w, size().height()));}
|
||||
void setHeight(qreal h) {setSize(QSizeF(size().width(), h));}
|
||||
void setPinsMargin(int marg) {if (marg > 1 && marg < 256) pins_margin = marg; arrangePins();}
|
||||
qreal width() const { return size().width(); }
|
||||
qreal height() const { return size().height(); }
|
||||
int pinsMargin() const { return pins_margin; }
|
||||
void setSize(QSizeF s) { _resize(s); }
|
||||
void setSize(qreal w, qreal h) { setSize(QSizeF(w, h)); }
|
||||
void setWidth(qreal w) { setSize(QSizeF(w, size().height())); }
|
||||
void setHeight(qreal h) { setSize(QSizeF(size().width(), h)); }
|
||||
void setPinsMargin(int marg) {
|
||||
if (marg > 1 && marg < 256) pins_margin = marg;
|
||||
arrangePins();
|
||||
}
|
||||
|
||||
QByteArray saveModel();
|
||||
void loadModel(const QByteArray & data);
|
||||
@@ -76,34 +85,36 @@ public:
|
||||
void addBinding(const QString & prop_name, const QString & bind_name);
|
||||
void applyBinding(const QString & bind_name, const QVariant & bind_value);
|
||||
void applyBindings(const PropertyStorage & bindings);
|
||||
void setBindings(const QList<QPair<QString, QString> > & bindings);
|
||||
QList<QPair<QString, QString> > getBindings();
|
||||
void setBindings(const QList<QPair<QString, QString>> & bindings);
|
||||
QList<QPair<QString, QString>> getBindings();
|
||||
QString getBindName(const QString & prop_name) const;
|
||||
QStringList getBindNames() const;
|
||||
QStringList getBindProps() const;
|
||||
|
||||
enum {Type = UserType + 1};
|
||||
enum {
|
||||
Type = UserType + 1
|
||||
};
|
||||
|
||||
protected:
|
||||
void _resize(QSizeF s);
|
||||
void _moveToTop(bool only_decors = false);
|
||||
int type() const {return Type;}
|
||||
int type() const { return Type; }
|
||||
QRectF boundingRect() const;
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
|
||||
double left() const {return boundingRect().left();}
|
||||
double right() const {return boundingRect().right();}
|
||||
double top() const {return boundingRect().top();}
|
||||
double bottom() const {return boundingRect().bottom();}
|
||||
double left() const { return boundingRect().left(); }
|
||||
double right() const { return boundingRect().right(); }
|
||||
double top() const { return boundingRect().top(); }
|
||||
double bottom() const { return boundingRect().bottom(); }
|
||||
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = nullptr) {}
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant & value);
|
||||
|
||||
QGraphicsRectItem g_main, g_selection;
|
||||
int pins_margin;
|
||||
QColor col;
|
||||
QMap<Qt::Alignment, QVector<BlockItemPin * > > pins_;
|
||||
QList<QGraphicsItem * > decors_;
|
||||
QList<QPair<QString, QString> > prop_bindings; // <property_name, binding_name>
|
||||
QMap<Qt::Alignment, QVector<BlockItemPin *>> pins_;
|
||||
QList<QGraphicsItem *> decors_;
|
||||
QList<QPair<QString, QString>> prop_bindings; // <property_name, binding_name>
|
||||
|
||||
private:
|
||||
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;
|
||||
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;}
|
||||
inline QDataStream & operator >>(QDataStream & s, BlockItemPin *& p) {
|
||||
s << cs.data();
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator>>(QDataStream & s, BlockItemPin *& p) {
|
||||
ChunkStream cs(s);
|
||||
p = new BlockItemPin();
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: p->setAlignment((Qt::Alignment)cs.getData<int>()); break;
|
||||
case 2: p->setBusType(cs.getData<int>()); break;
|
||||
case 3: p->setText(cs.getData<QString>()); break;
|
||||
case 4: p->setToolTip(cs.getData<QString>()); break;
|
||||
case 1: p->setAlignment((Qt::Alignment)cs.getData<int>()); break;
|
||||
case 2: p->setBusType(cs.getData<int>()); break;
|
||||
case 3: p->setText(cs.getData<QString>()); break;
|
||||
case 4: p->setToolTip(cs.getData<QString>()); break;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const BlockItem * b) {s << b->save(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, BlockItem *& b) {
|
||||
QByteArray ba; s >> ba;
|
||||
inline QDataStream & operator<<(QDataStream & s, const BlockItem * b) {
|
||||
s << b->save();
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator>>(QDataStream & s, BlockItem *& b) {
|
||||
QByteArray ba;
|
||||
s >> ba;
|
||||
b = new BlockItem();
|
||||
b->load(ba);
|
||||
return s;
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
#include "blockview.h"
|
||||
|
||||
#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;
|
||||
setData(bvidType, bvitPin);
|
||||
setAcceptHoverEvents(true);
|
||||
text_item.setData(bvidMoveParent, true);
|
||||
ell_item.setData(bvidVisualizeSelection, true);
|
||||
br[Disconnected] = QBrush(Qt::lightGray);
|
||||
br[Connected] = QBrush(Qt::darkGreen);
|
||||
br[Hover] = QBrush(Qt::blue);
|
||||
br[Drop] = QBrush(Qt::green);
|
||||
br[Accept] = QBrush(Qt::green);
|
||||
br[Reject] = QBrush(Qt::red);
|
||||
br[Connected] = QBrush(Qt::darkGreen);
|
||||
br[Hover] = QBrush(Qt::blue);
|
||||
br[Drop] = QBrush(Qt::green);
|
||||
br[Accept] = QBrush(Qt::green);
|
||||
br[Reject] = QBrush(Qt::red);
|
||||
anim_pin_size.setTargetObject(this);
|
||||
anim_pin_size.setPropertyName("pinSize");
|
||||
anim_pin_size.setEasingCurve(QEasingCurve::OutElastic);
|
||||
@@ -42,7 +46,7 @@ void BlockItemPin::animAccept() {
|
||||
|
||||
void BlockItemPin::setState(State s) {
|
||||
State os = state_;
|
||||
state_ = s;
|
||||
state_ = s;
|
||||
setBrush(br[int(state_)]);
|
||||
if (s == Accept && os != Accept) {
|
||||
animAccept();
|
||||
@@ -61,8 +65,7 @@ void BlockItemPin::enlargePin(bool enlarge) {
|
||||
resizePin(sz);
|
||||
return;
|
||||
}
|
||||
if (sz == anim_pin_size.endValue())
|
||||
return;
|
||||
if (sz == anim_pin_size.endValue()) return;
|
||||
anim_pin_size.stop();
|
||||
anim_pin_size.setStartValue(pinSize());
|
||||
anim_pin_size.setEndValue(sz);
|
||||
@@ -71,7 +74,7 @@ void BlockItemPin::enlargePin(bool enlarge) {
|
||||
|
||||
|
||||
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) {
|
||||
text_item.setFont(AlignedTextItem::sceneFont(QApplication::font()));
|
||||
QRectF tbr = text_item.boundingRect();
|
||||
QRectF tbr = text_item.boundingRect();
|
||||
const double r = 7.;
|
||||
ell_item.setRect(-r, -r, r+r, r+r);
|
||||
ell_item.setSpanAngle(16*180);
|
||||
ell_item.setRect(-r, -r, r + r, r + r);
|
||||
ell_item.setSpanAngle(16 * 180);
|
||||
text_item.resetTransform();
|
||||
text_item.setPos(0, -tbr.height() / 2.);
|
||||
text_item.setTransformOriginPoint(0, tbr.height() / 2.);
|
||||
switch (align) {
|
||||
case Qt::AlignBottom: ell_item.setStartAngle(16*0); text_item.setRotation(-90.); 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;
|
||||
case Qt::AlignBottom:
|
||||
ell_item.setStartAngle(16 * 0);
|
||||
text_item.setRotation(-90.);
|
||||
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;
|
||||
}
|
||||
if (affect_parent && parent_)
|
||||
parent_->arrangePins();
|
||||
if (affect_parent && parent_) parent_->arrangePins();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::_reparent() {
|
||||
if (parentItem() == 0) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(parentItem()) == 0) return;
|
||||
QPen p = qgraphicsitem_cast<BlockItem*>(parentItem())->g_main.pen();
|
||||
if (qgraphicsitem_cast<BlockItem *>(parentItem()) == 0) return;
|
||||
QPen p = qgraphicsitem_cast<BlockItem *>(parentItem())->g_main.pen();
|
||||
ell_item.setPen(p);
|
||||
if (scene()) {
|
||||
text_item.setFont(AlignedTextItem::sceneFont(scene()->font()));
|
||||
@@ -132,18 +150,20 @@ QGraphicsView * BlockItemPin::_view() const {
|
||||
|
||||
|
||||
QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
|
||||
if (change == QGraphicsItem::ItemParentChange)
|
||||
_reparent();
|
||||
if (change == QGraphicsItem::ItemParentChange) _reparent();
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
|
||||
QGraphicsView * v = _view();
|
||||
bool m_pin_mc = false;
|
||||
bool m_pin_mc = false;
|
||||
if (v) {
|
||||
qobject_cast<BlockView*>(v)->getPinMC(&m_pin_mc);
|
||||
QMetaObject::invokeMethod(v, [this, v](){qobject_cast<BlockView*>(v)->pinHoverInOut(this);}, Qt::QueuedConnection);
|
||||
qobject_cast<BlockView *>(v)->getPinMC(&m_pin_mc);
|
||||
QMetaObject::invokeMethod(
|
||||
v,
|
||||
[this, v]() { qobject_cast<BlockView *>(v)->pinHoverInOut(this); },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
if ((state() != Disconnected) && !m_pin_mc) return;
|
||||
saveState();
|
||||
@@ -159,6 +179,6 @@ void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
enlargePin(false);
|
||||
update();
|
||||
if (v) {
|
||||
qobject_cast<BlockView*>(v)->pinHoverInOut(nullptr);
|
||||
qobject_cast<BlockView *>(v)->pinHoverInOut(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKITEMPIN_H
|
||||
#define BLOCKITEMPIN_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsObject>
|
||||
#include "alignedtextitem.h"
|
||||
#include "blockbase.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QStack>
|
||||
#include <QDebug>
|
||||
#include <QGraphicsView>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QStack>
|
||||
#include <qmath.h>
|
||||
#include "blockbase.h"
|
||||
#include "alignedtextitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class BlockItem;
|
||||
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 BlockItem;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false)
|
||||
|
||||
public:
|
||||
BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0);
|
||||
|
||||
@@ -58,45 +61,59 @@ public:
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
None = 0x0,
|
||||
Input = 0x1,
|
||||
Output = 0x2,
|
||||
None = 0x0,
|
||||
Input = 0x1,
|
||||
Output = 0x2,
|
||||
InputOutput = 0x3
|
||||
};
|
||||
|
||||
void setPen(const QPen & p) {ell_item.setPen(p);}
|
||||
QPen pen() const {return ell_item.pen();}
|
||||
void setBrush(const QBrush & b) {ell_item.setBrush(b);}
|
||||
QBrush brush() const {return ell_item.brush();}
|
||||
void setPen(const QPen & p) { ell_item.setPen(p); }
|
||||
QPen pen() const { return ell_item.pen(); }
|
||||
void setBrush(const QBrush & b) { ell_item.setBrush(b); }
|
||||
QBrush brush() const { return ell_item.brush(); }
|
||||
|
||||
int busType() const {return bus_type;}
|
||||
Qt::Alignment alignment() const {return align;}
|
||||
QString text() const {return text_item.text();}
|
||||
State state() const {return state_;}
|
||||
int busType() const { return bus_type; }
|
||||
Qt::Alignment alignment() const { return align; }
|
||||
QString text() const { return text_item.text(); }
|
||||
State state() const { return state_; }
|
||||
|
||||
void setBusType(int type_) {bus_type = type_;}
|
||||
void setAlignment(Qt::Alignment a) {align = a; _init(true);}
|
||||
void setText(const QString & t) {text_item.setText(t); _init(true);}
|
||||
void setBusType(int type_) { bus_type = type_; }
|
||||
void setAlignment(Qt::Alignment a) {
|
||||
align = a;
|
||||
_init(true);
|
||||
}
|
||||
void setText(const QString & t) {
|
||||
text_item.setText(t);
|
||||
_init(true);
|
||||
}
|
||||
void setState(State s);
|
||||
|
||||
void saveState() {sstate_.push(state_);}
|
||||
bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;}
|
||||
void clearStateStack() {sstate_.clear();}
|
||||
void saveState() { sstate_.push(state_); }
|
||||
bool restoreState() {
|
||||
if (sstate_.isEmpty()) return false;
|
||||
setState(sstate_.pop());
|
||||
return true;
|
||||
}
|
||||
void clearStateStack() { sstate_.clear(); }
|
||||
|
||||
void enlargePin(bool enlarge);
|
||||
|
||||
BlockItem * parent() const {return parent_;}
|
||||
QList<BlockBusItem * > connectedBuses() const {return buses_;}
|
||||
BlockItem * parent() const { return parent_; }
|
||||
QList<BlockBusItem *> connectedBuses() const { return buses_; }
|
||||
|
||||
enum {Type = UserType + 3};
|
||||
enum {
|
||||
Type = UserType + 3
|
||||
};
|
||||
|
||||
public slots:
|
||||
void animAccept();
|
||||
|
||||
protected:
|
||||
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());}
|
||||
int type() const {return Type;}
|
||||
QRectF boundingRect() const {
|
||||
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);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
|
||||
@@ -108,7 +125,7 @@ protected:
|
||||
QGraphicsEllipseItem ell_item;
|
||||
QGraphicsSimpleTextItem text_item;
|
||||
QStack<State> sstate_;
|
||||
QList<BlockBusItem * > buses_;
|
||||
QList<BlockBusItem *> buses_;
|
||||
BlockItem * parent_;
|
||||
Qt::Alignment align;
|
||||
QBrush br[6];
|
||||
@@ -122,7 +139,6 @@ private:
|
||||
|
||||
QPropertyAnimation anim_pin_size;
|
||||
QPropertyAnimation anim_accept;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#include "blockview.h"
|
||||
|
||||
#include "qad_types.h"
|
||||
#include <qmath.h>
|
||||
#include <QScrollBar>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QApplication>
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QElapsedTimer>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMimeData>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QVector2D>
|
||||
#include <QClipboard>
|
||||
#include <QMimeData>
|
||||
#include <QElapsedTimer>
|
||||
#include <qmath.h>
|
||||
|
||||
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() {
|
||||
qRegisterMetaType<BlockItem*>();
|
||||
qRegisterMetaType<BlockItemPin*>();
|
||||
qRegisterMetaType<BlockBusItem*>();
|
||||
qRegisterMetaType<BlockItem *>();
|
||||
qRegisterMetaType<BlockItemPin *>();
|
||||
qRegisterMetaType<BlockBusItem *>();
|
||||
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;
|
||||
match_bus = bus_from = cur_bus = 0;
|
||||
mm_ci = 0;
|
||||
hpin = 0;
|
||||
ghost_ = 0;
|
||||
grid_step = 10.;
|
||||
grid_points = 1;
|
||||
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 1, Qt::NoPen);
|
||||
thick = 1;
|
||||
thumb_hide_delay = 500;
|
||||
timer_thumb = 0;
|
||||
smode = BlockView::MultiSelection;
|
||||
mm_ci = 0;
|
||||
hpin = 0;
|
||||
ghost_ = 0;
|
||||
grid_step = 10.;
|
||||
grid_points = 1;
|
||||
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 1, Qt::NoPen);
|
||||
thick = 1;
|
||||
thumb_hide_delay = 500;
|
||||
timer_thumb = 0;
|
||||
smode = BlockView::MultiSelection;
|
||||
cur_scl = thumb_scl = prev_app_scale = 1.;
|
||||
_talpha = 0.;
|
||||
_talpha = 0.;
|
||||
ae_enabled = is_block_anim = is_nav_anim = true;
|
||||
nav_prev_aa = nav_prev_imaa = nav_prev_grid = true;
|
||||
square_node = block_emit_selection = false;
|
||||
thumb_size = QSizeF(200, 200);
|
||||
thumb_size = QSizeF(200, 200);
|
||||
if (scene() == 0) {
|
||||
scene_ = new QGraphicsScene;
|
||||
setScene(scene_);
|
||||
@@ -120,18 +121,12 @@ bool BlockView::event(QEvent * e) {
|
||||
|
||||
bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
if (o == &widget_thumb) {
|
||||
QMouseEvent * me = (QMouseEvent*)e;
|
||||
if(!me) return true;
|
||||
QMouseEvent * me = (QMouseEvent *)e;
|
||||
if (!me) return true;
|
||||
switch (e->type()) {
|
||||
case QEvent::Paint:
|
||||
drawThumb();
|
||||
return true;
|
||||
case QEvent::Enter:
|
||||
thumbShow();
|
||||
break;
|
||||
case QEvent::Leave:
|
||||
restartTimer(timer_thumb, thumb_hide_delay);
|
||||
break;
|
||||
case QEvent::Paint: drawThumb(); return true;
|
||||
case QEvent::Enter: thumbShow(); break;
|
||||
case QEvent::Leave: restartTimer(timer_thumb, thumb_hide_delay); break;
|
||||
case QEvent::MouseButtonPress:
|
||||
thumb_press = me->pos();
|
||||
widget_thumb.setCursor(Qt::ClosedHandCursor);
|
||||
@@ -140,12 +135,9 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
scrollFromThumb();
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
widget_thumb.setCursor(Qt::OpenHandCursor);
|
||||
break;
|
||||
case QEvent::MouseButtonRelease: widget_thumb.setCursor(Qt::OpenHandCursor); break;
|
||||
case QEvent::MouseMove:
|
||||
if (me->buttons() == 0)
|
||||
widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
|
||||
if (me->buttons() == 0) widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) {
|
||||
thumb_vr.translate(me->pos() - thumb_press);
|
||||
scrollFromThumb();
|
||||
@@ -157,24 +149,30 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
return QGraphicsView::eventFilter(o, e);
|
||||
}
|
||||
if (o == scene_) {
|
||||
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent*)e;
|
||||
QList<QGraphicsItem * > mil;
|
||||
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent *)e;
|
||||
QList<QGraphicsItem *> mil;
|
||||
QPointF mdp;
|
||||
bool fmm_drag = false;
|
||||
int btncnt = 0;
|
||||
int btncnt = 0;
|
||||
switch (e->type()) {
|
||||
case QEvent::GraphicsSceneMouseDoubleClick:
|
||||
scene_point = me->scenePos();
|
||||
mil = scene_->items(scene_point);
|
||||
foreach (QGraphicsItem * i, mil) {
|
||||
mil = scene_->items(scene_point);
|
||||
foreach(QGraphicsItem * i, mil) {
|
||||
if (i->data(bvidTmpItem).toBool()) continue;
|
||||
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;
|
||||
}
|
||||
if (i->data(bvidType).toInt() == bvitBus) {
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(i)->isBusSelected()) {
|
||||
QMetaObject::invokeMethod(this, [this, i](){busDoubleClicked(qgraphicsitem_cast<BlockBusItem*>(i));}, Qt::QueuedConnection);
|
||||
if (qgraphicsitem_cast<BlockBusItem *>(i)->isBusSelected()) {
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, i]() { busDoubleClicked(qgraphicsitem_cast<BlockBusItem *>(i)); },
|
||||
Qt::QueuedConnection);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -187,23 +185,23 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
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_MID_BUTTON )) btncnt++;
|
||||
if (me->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
|
||||
mm_cancel = btncnt >= 2;
|
||||
match_bus = bus_from = 0;
|
||||
hpin = 0;
|
||||
copy_dp = QPointF();
|
||||
//qDebug() << mm_cancel << moved << sel_rect.isVisible();
|
||||
hpin = 0;
|
||||
copy_dp = QPointF();
|
||||
// qDebug() << mm_cancel << moved << sel_rect.isVisible();
|
||||
if (sel_rect.isVisible()) {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
block_emit_selection = true;
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
block_emit_selection = true;
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
i->setSelected(i->data(bvidSelected).toBool());
|
||||
block_emit_selection = false;
|
||||
emit selectionChanged();
|
||||
}
|
||||
//qDebug() << "cur_bus" << cur_bus;
|
||||
// qDebug() << "cur_bus" << cur_bus;
|
||||
if (cur_bus) {
|
||||
return false;
|
||||
}
|
||||
@@ -235,30 +233,30 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
mm_mods = me->modifiers();
|
||||
mm_drag = moved = false;
|
||||
screen_point = me->screenPos();
|
||||
scene_point = me->scenePos();
|
||||
screen_point = me->screenPos();
|
||||
scene_point = me->scenePos();
|
||||
if ((me->button() == QT_MID_BUTTON) || (me->button() == Qt::RightButton)) {
|
||||
thumbShow();
|
||||
restartTimer(timer_thumb, thumb_hide_delay);
|
||||
return true;
|
||||
}
|
||||
mil = scene_->items(scene_point);
|
||||
//qDebug() << "mil" << mil;
|
||||
// qDebug() << "mil" << mil;
|
||||
while (!mil.isEmpty()) {
|
||||
mm_ci = mil.front();
|
||||
if (mm_ci->data(bvidDTHandle).toBool()) return QGraphicsView::eventFilter(o, e);
|
||||
if (mm_ci->data(bvidTmpItem).toBool() || mm_ci->data(bvidItemSelection).toBool()) {
|
||||
mil.pop_front();
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (mil.isEmpty()) {
|
||||
mm_ci = 0;
|
||||
return true;
|
||||
}
|
||||
while (mm_ci->data(bvidType).toInt() == bvitBus) {
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci))
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci)->isBusSelected())
|
||||
break;
|
||||
if (qgraphicsitem_cast<BlockBusItem *>(mm_ci))
|
||||
if (qgraphicsitem_cast<BlockBusItem *>(mm_ci)->isBusSelected()) break;
|
||||
if (mil.size() > 1) {
|
||||
mm_ci = mil[1];
|
||||
mil.pop_front();
|
||||
@@ -272,8 +270,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
mm_ci = mil[1];
|
||||
mil.pop_front();
|
||||
if (mm_ci->data(bvidVisualizeSelection).toBool())
|
||||
if (mil.size() > 1)
|
||||
mm_ci = mil[1];
|
||||
if (mil.size() > 1) mm_ci = mil[1];
|
||||
} else
|
||||
mm_ci = 0;
|
||||
}
|
||||
@@ -282,10 +279,10 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
while (mm_ci->parentItem() != 0)
|
||||
mm_ci = mm_ci->parentItem();
|
||||
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->sceneRect().contains(scene_point)) {
|
||||
//qDebug() << "return";
|
||||
// qDebug() << "return";
|
||||
mm_ci = 0;
|
||||
}
|
||||
}
|
||||
@@ -294,27 +291,27 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
if (mm_ci) {
|
||||
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();
|
||||
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->clearStateStack();
|
||||
qgraphicsitem_cast<BlockItemPin *>(mm_ci)->clearStateStack();
|
||||
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.show();
|
||||
new_bus = true;
|
||||
qDeleteAll(tmp_buses);
|
||||
tmp_buses.clear();
|
||||
foreach (BlockItemPin * p, last_multiconnect_pl) {
|
||||
foreach(BlockItemPin * p, last_multiconnect_pl) {
|
||||
tmp_buses << new BlockBusItem(true);
|
||||
tmp_buses.back()->setBusType(p->busType());
|
||||
addItem(tmp_buses.back());
|
||||
}
|
||||
//qDebug() << "new" << ;
|
||||
// qDebug() << "new" << ;
|
||||
prev_tcb = m_trace_with_buses;
|
||||
newBusStarted(tmp_bus.busType());
|
||||
markPins(tmp_bus.busType());
|
||||
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignLeft ||
|
||||
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignRight)
|
||||
if (qgraphicsitem_cast<BlockItemPin *>(mm_ci)->alignment() == Qt::AlignLeft ||
|
||||
qgraphicsitem_cast<BlockItemPin *>(mm_ci)->alignment() == Qt::AlignRight)
|
||||
wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal);
|
||||
else
|
||||
wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical);
|
||||
@@ -325,11 +322,11 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
cur_scl = qSqrt(transform().determinant());
|
||||
break;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
//qDebug() << "move mm_ci" << mm_ci << mm_cancel;
|
||||
// qDebug() << "move mm_ci" << mm_ci << mm_cancel;
|
||||
if (mm_ci)
|
||||
if (mm_ci->data(bvidTmpItem).toBool()) {
|
||||
mm_ci = 0;
|
||||
@@ -346,19 +343,21 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
} else {
|
||||
if (tmp_bus.isVisible()) {
|
||||
mil = scene_->items(me->scenePos());
|
||||
mil = scene_->items(me->scenePos());
|
||||
hpin = 0;
|
||||
foreach (QGraphicsItem * i, mil)
|
||||
foreach(QGraphicsItem * i, mil)
|
||||
if (i->data(bvidType).toInt() == bvitPin) {
|
||||
hpin = qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
hpin = qgraphicsitem_cast<BlockItemPin *>(i);
|
||||
break;
|
||||
}
|
||||
if (hpin) {
|
||||
if (hpin->state() == BlockItemPin::Accept) {
|
||||
unhoverPins(hpin);
|
||||
hoverAcceptedPin(hpin, true);
|
||||
} else hpin = 0;
|
||||
} else unhoverPins();
|
||||
} else
|
||||
hpin = 0;
|
||||
} else
|
||||
unhoverPins();
|
||||
if (new_branch) {
|
||||
matchBus();
|
||||
break;
|
||||
@@ -366,7 +365,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
trace(trace_from, me->scenePos(), &tmp_bus);
|
||||
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
|
||||
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);
|
||||
tmp_buses[i]->show();
|
||||
}
|
||||
@@ -378,7 +377,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
if (fmm_drag) {
|
||||
fmm_drag = false;
|
||||
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()) {
|
||||
clearSelection();
|
||||
mm_ci->setSelected(true);
|
||||
@@ -392,21 +391,22 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
sel_items = scene_->selectedItems();
|
||||
deleteCopyTemp();
|
||||
QList<BlockItem * > bi;
|
||||
foreach (QGraphicsItem * i, sel_items) {
|
||||
QList<BlockItem *> bi;
|
||||
foreach(QGraphicsItem * i, sel_items) {
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) {
|
||||
//qDebug() << "copy";
|
||||
bi << qgraphicsitem_cast<BlockItem*>(i);
|
||||
// qDebug() << "copy";
|
||||
bi << qgraphicsitem_cast<BlockItem *>(i);
|
||||
BlockItem * ti = bi.back()->copy();
|
||||
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);
|
||||
copy_items << ti;
|
||||
scene_->addItem(ti);
|
||||
}
|
||||
}
|
||||
QList<BlockBusItem * > ibi = internalBuses(bi);
|
||||
foreach (BlockBusItem * i, ibi) {
|
||||
QList<BlockBusItem *> ibi = internalBuses(bi);
|
||||
foreach(BlockBusItem * i, ibi) {
|
||||
i = i->copy();
|
||||
i->setOpacity(i->opacity() * 0.5);
|
||||
copy_buses << i;
|
||||
@@ -416,7 +416,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
setCursor(Qt::DragCopyCursor);
|
||||
}
|
||||
} else {
|
||||
//qDebug() << "move smode" << smode;
|
||||
// qDebug() << "move smode" << smode;
|
||||
if (smode == BlockView::SingleSelection) {
|
||||
if (fmm_drag) {
|
||||
clearSelection();
|
||||
@@ -432,8 +432,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
if (mm_ci == 0) {
|
||||
scene_->addItem(&sel_rect);
|
||||
sel_rect.show();
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier))
|
||||
clearSelection();
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier)) clearSelection();
|
||||
} else {
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_ci->isSelected()) {
|
||||
clearSelection();
|
||||
@@ -442,8 +441,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
saveSelState();
|
||||
if (mm_ci != 0)
|
||||
if (!sel_items.contains(mm_ci))
|
||||
mm_ci = 0;
|
||||
if (!sel_items.contains(mm_ci)) mm_ci = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,46 +450,39 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
else {
|
||||
if (mm_drag && mm_ci != 0) {
|
||||
mdp = (me->scenePos() - scene_point);
|
||||
if (grid_snap)
|
||||
mdp = quantize(mdp, grid_step);
|
||||
if (grid_snap) mdp = quantize(mdp, grid_step);
|
||||
if (!mdp.isNull()) {
|
||||
scene_point += mdp;
|
||||
copy_dp += mdp;
|
||||
}
|
||||
if (mm_copy) {
|
||||
if (!mdp.isNull())
|
||||
moved = true;
|
||||
foreach (QGraphicsItem * i, copy_items)
|
||||
if (!mdp.isNull()) moved = true;
|
||||
foreach(QGraphicsItem * i, copy_items)
|
||||
i->setPos(i->pos() + mdp);
|
||||
foreach (BlockBusItem * i, copy_buses)
|
||||
foreach(BlockBusItem * i, copy_buses)
|
||||
i->movePolyline(mdp);
|
||||
}
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) {
|
||||
if (!mdp.isNull())
|
||||
moved = true;
|
||||
foreach (QGraphicsItem * i, sel_items)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsMovable))
|
||||
i->setPos(i->pos() + mdp);
|
||||
if (!me->modifiers().testFlag(Qt::AltModifier))
|
||||
moveBuses(sel_items, mdp);
|
||||
if (!mdp.isNull()) moved = true;
|
||||
foreach(QGraphicsItem * i, sel_items)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsMovable)) i->setPos(i->pos() + mdp);
|
||||
if (!me->modifiers().testFlag(Qt::AltModifier)) moveBuses(sel_items, mdp);
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (mm_ci)
|
||||
if (mm_ci->data(bvidBlockDecor).toBool())
|
||||
return true;
|
||||
if (mm_ci->data(bvidBlockDecor).toBool()) return true;
|
||||
}
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0)
|
||||
return true;
|
||||
//qDebug() << "scene mouse";
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0) return true;
|
||||
// qDebug() << "scene mouse";
|
||||
break;
|
||||
case QEvent::GraphicsSceneMouseRelease:
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) btncnt++;
|
||||
if (me->buttons().testFlag(Qt::RightButton)) btncnt++;
|
||||
if (me->buttons().testFlag(QT_MID_BUTTON)) btncnt++;
|
||||
cur_bus = 0;
|
||||
cur_bus = 0;
|
||||
mm_cancel = btncnt > 0;
|
||||
if (mm_cancel || (me->button() == QT_MID_BUTTON) || (me->button() == Qt::RightButton)) {
|
||||
mm_ci = 0;
|
||||
@@ -504,15 +495,15 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
if (mm_ci->data(bvidItemSelection).toBool()) break;
|
||||
if (mm_copy) {
|
||||
QList<QGraphicsItem*> ai;
|
||||
QList<QGraphicsItem *> ai;
|
||||
blockSignals(true);
|
||||
if (moved) {
|
||||
QList<BlockItem*> ci;
|
||||
QList<BlockBusItem*> bi;
|
||||
foreach (QGraphicsItem * b, sel_items)
|
||||
QList<BlockItem *> ci;
|
||||
QList<BlockBusItem *> bi;
|
||||
foreach(QGraphicsItem * b, sel_items)
|
||||
if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) {
|
||||
ci << qgraphicsitem_cast<BlockItem*>(b);
|
||||
ai << qgraphicsitem_cast<QGraphicsItem*>(b);
|
||||
ci << qgraphicsitem_cast<BlockItem *>(b);
|
||||
ai << qgraphicsitem_cast<QGraphicsItem *>(b);
|
||||
}
|
||||
bi = internalBuses(ci);
|
||||
if (!ci.isEmpty()) copyBlocks(ci, copy_dp);
|
||||
@@ -530,10 +521,9 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
hideTmpBuses(false);
|
||||
}
|
||||
if (moved && pm_connect) {
|
||||
QList<QGraphicsItem*> ci;
|
||||
foreach (QGraphicsItem * b, sel_items)
|
||||
if (b->data(bvidType).toInt() == bvitBlock)
|
||||
ci << b;
|
||||
QList<QGraphicsItem *> ci;
|
||||
foreach(QGraphicsItem * b, sel_items)
|
||||
if (b->data(bvidType).toInt() == bvitBlock) ci << b;
|
||||
simplifyBuses();
|
||||
emitActionEvent(BlockItemBase::BlockMove, ci);
|
||||
reconnectAll();
|
||||
@@ -545,7 +535,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
BlockBusItem * nb = new BlockBusItem(tmp_bus);
|
||||
addItem(nb, tmp_buses.isEmpty());
|
||||
newBusCreated(nb);
|
||||
foreach (BlockBusItem * b, tmp_buses) {
|
||||
foreach(BlockBusItem * b, tmp_buses) {
|
||||
nb = new BlockBusItem(*b);
|
||||
addItem(nb, b == tmp_buses.back());
|
||||
newBusCreated(nb);
|
||||
@@ -553,7 +543,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
} else {
|
||||
if (connectTmpToBus(match_bus)) {
|
||||
newBusCreated(match_bus);
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << match_bus);
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << match_bus);
|
||||
emit connectionsChanged();
|
||||
}
|
||||
}
|
||||
@@ -570,34 +560,28 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
switch (smode) {
|
||||
case SingleSelection:
|
||||
clearSelection();
|
||||
if (mm_ci)
|
||||
mm_ci->setSelected(true);
|
||||
if (mm_ci) mm_ci->setSelected(true);
|
||||
break;
|
||||
case MultiSelection:
|
||||
if (mm_ci == 0 || !me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
clearSelection();
|
||||
if (mm_ci)
|
||||
mm_ci->setSelected(true);
|
||||
if (mm_ci) mm_ci->setSelected(true);
|
||||
} else {
|
||||
if (mm_ci != 0) {
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (mm_ci->data(bvidType).toInt() == bvitBlock)
|
||||
mm_ci->setSelected(!mm_ci->isSelected());
|
||||
if (mm_ci->data(bvidType).toInt() == bvitBlock) mm_ci->setSelected(!mm_ci->isSelected());
|
||||
} else
|
||||
mm_ci->setSelected(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
clearSelection();
|
||||
break;
|
||||
default: clearSelection(); break;
|
||||
}
|
||||
}
|
||||
sel_rect.hide();
|
||||
if (sel_rect.scene())
|
||||
scene_->removeItem(&sel_rect);
|
||||
if (sel_rect.scene()) scene_->removeItem(&sel_rect);
|
||||
mm_drag = false;
|
||||
mm_ci = 0;
|
||||
mm_ci = 0;
|
||||
unsetCursor();
|
||||
break;
|
||||
default: break;
|
||||
@@ -637,9 +621,8 @@ void BlockView::wheelEvent(QWheelEvent * e) {
|
||||
#else
|
||||
double scl = 1. - e->angleDelta().y() / 500.;
|
||||
#endif
|
||||
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running))
|
||||
nav_target = _nav();
|
||||
QRectF r = nav_target;
|
||||
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) nav_target = _nav();
|
||||
QRectF r = nav_target;
|
||||
double vw = viewport()->width(), vh = viewport()->height();
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
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();
|
||||
if (event->buttons().testFlag(QT_MID_BUTTON) || event->buttons().testFlag(Qt::RightButton)) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
if (sel_rect.scene())
|
||||
scene_->removeItem(&sel_rect);
|
||||
if (sel_rect.scene()) scene_->removeItem(&sel_rect);
|
||||
}
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
}
|
||||
@@ -677,7 +659,7 @@ void BlockView::mouseReleaseEvent(QMouseEvent * event) {
|
||||
void BlockView::updateNavRect() {
|
||||
QPointF t = mapToScene(viewport()->rect().topLeft());
|
||||
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) {
|
||||
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
|
||||
if (pin) {
|
||||
//qDebug() << "pin" << pin->state();
|
||||
// qDebug() << "pin" << pin->state();
|
||||
if (pin->state() == BlockItemPin::Hover) {
|
||||
highlightNearPins(pin, e->modifiers());
|
||||
}
|
||||
@@ -727,20 +709,20 @@ void BlockView::keyPressEvent(QKeyEvent * e) {
|
||||
if (e->key() == Qt::Key_Shift) {
|
||||
retrace = true;
|
||||
switch (wavetrace.preferredDirection()) {
|
||||
case BlockViewWavetrace::NoTrace: wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal); break;
|
||||
case BlockViewWavetrace::Horizontal: wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical); break;
|
||||
case BlockViewWavetrace::Vertical: wavetrace.setPreferredDirection(BlockViewWavetrace::NoTrace); break;
|
||||
case BlockViewWavetrace::NoTrace: wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal); break;
|
||||
case BlockViewWavetrace::Horizontal: wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical); break;
|
||||
case BlockViewWavetrace::Vertical: wavetrace.setPreferredDirection(BlockViewWavetrace::NoTrace); break;
|
||||
}
|
||||
}
|
||||
if (e->key() == Qt::Key_Alt) {
|
||||
retrace = true;
|
||||
retrace = true;
|
||||
m_trace_with_buses = !m_trace_with_buses;
|
||||
}
|
||||
if (retrace) {
|
||||
trace(last_trace_from, trace_to, &tmp_bus);
|
||||
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
|
||||
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);
|
||||
tmp_buses[i]->show();
|
||||
}
|
||||
@@ -754,7 +736,7 @@ void BlockView::keyPressEvent(QKeyEvent * e) {
|
||||
void BlockView::keyReleaseEvent(QKeyEvent * e) {
|
||||
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
|
||||
if (pin) {
|
||||
//qDebug() << "pin" << pin->state();
|
||||
// qDebug() << "pin" << pin->state();
|
||||
if (pin->state() == BlockItemPin::Hover) {
|
||||
highlightNearPins(pin, e->modifiers());
|
||||
}
|
||||
@@ -781,7 +763,10 @@ void BlockView::scrollContentsBy(int dx, int dy) {
|
||||
thumbShow();
|
||||
restartTimer(timer_thumb, thumb_hide_delay);
|
||||
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;
|
||||
}
|
||||
if (!grid_visible) return;
|
||||
rx = quantize(rect.left(), sx);
|
||||
ry = quantize(rect.top(), sy);
|
||||
rx = quantize(rect.left(), sx);
|
||||
ry = quantize(rect.top(), sy);
|
||||
bool gp = grid_points > 0.5;
|
||||
if (gp) {
|
||||
QPen pp(grid_pen.color(), qMax<int>(grid_points, thick), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
pp.setCosmetic(true);
|
||||
painter->setPen(pp);
|
||||
for(int i = 0; i < qCeil(rect.width() / sx) + 1; ++i)
|
||||
for(int j = 0; j < qCeil(rect.height() / sy) + 1; ++j)
|
||||
for (int i = 0; i < qCeil(rect.width() / sx) + 1; ++i)
|
||||
for (int j = 0; j < qCeil(rect.height() / sy) + 1; ++j)
|
||||
painter->drawPoint(rx + i * sx, ry + j * sy);
|
||||
}
|
||||
if (grid_pen.style() == Qt::NoPen) return;
|
||||
QPen pen = grid_pen;
|
||||
pen.setWidth(qMax<int>(pen.width(), thick));
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
emit schemeAction(action, items);
|
||||
}
|
||||
@@ -868,18 +853,20 @@ void BlockView::getPinMC(bool * v) {
|
||||
void BlockView::drawThumb() {
|
||||
if (!minimap) return;
|
||||
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;
|
||||
if (sr.width() >= sr.height())
|
||||
thumb_scl = thumb_size.width() / sr.width();
|
||||
else
|
||||
thumb_scl = thumb_size.height() / sr.height();
|
||||
tr = sr * thumb_scl;
|
||||
tr = sr * thumb_scl;
|
||||
cur_scl = qSqrt(transform().determinant());
|
||||
thumb_scl /= cur_scl;
|
||||
QSizeF vs(size().width() - verticalScrollBar()->width(), size().height() - horizontalScrollBar()->height());
|
||||
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);
|
||||
|
||||
p.setBrush(Qt::lightGray);
|
||||
@@ -920,7 +907,7 @@ void BlockView::thumbHide() {
|
||||
thumb_anim.setStartValue(_thumb());
|
||||
thumb_anim.setEndValue(0.);
|
||||
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();
|
||||
thumb_anim.stop();
|
||||
_setThumb(1.);
|
||||
//qDebug() << "show" << thumb_anim.startValue() << thumb_anim.endValue();
|
||||
// qDebug() << "show" << thumb_anim.startValue() << thumb_anim.endValue();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::clearSelection() {
|
||||
bool pb = block_emit_selection;
|
||||
bool pb = block_emit_selection;
|
||||
block_emit_selection = true;
|
||||
sel_items.clear();
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(false);
|
||||
block_emit_selection = pb;
|
||||
if (!block_emit_selection)
|
||||
emit selectionChanged();
|
||||
if (!block_emit_selection) emit selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -950,84 +936,80 @@ void BlockView::addItem(QGraphicsItem * item, bool emit_action) {
|
||||
scene_->addItem(item);
|
||||
applyGridStep();
|
||||
if (item->data(bvidType).toInt() == bvitBus) {
|
||||
loadBus(qgraphicsitem_cast<BlockBusItem*>(item));
|
||||
((BlockBusItem*)item)->setSquareNodes(square_node);
|
||||
connect((BlockBusItem*)item, SIGNAL(destroyed(QObject*)), this, SLOT(removedBus(QObject*)), Qt::UniqueConnection);
|
||||
if (emit_action) emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << item);
|
||||
loadBus(qgraphicsitem_cast<BlockBusItem *>(item));
|
||||
((BlockBusItem *)item)->setSquareNodes(square_node);
|
||||
connect((BlockBusItem *)item, SIGNAL(destroyed(QObject *)), this, SLOT(removedBus(QObject *)), Qt::UniqueConnection);
|
||||
if (emit_action) emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << item);
|
||||
emit connectionsChanged();
|
||||
return;
|
||||
}
|
||||
if (item->data(bvidType).toInt() == bvitBlock) {
|
||||
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(blockHoverLeave(BlockItem*)), this, SIGNAL(blockHoverLeave(BlockItem*)), Qt::UniqueConnection);
|
||||
if (emit_action) emitActionEvent(BlockItemBase::BlockAdd, QList<QGraphicsItem*>() << item);
|
||||
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(blockHoverLeave(BlockItem *)), this, SIGNAL(blockHoverLeave(BlockItem *)), Qt::UniqueConnection);
|
||||
if (emit_action) emitActionEvent(BlockItemBase::BlockAdd, QList<QGraphicsItem *>() << item);
|
||||
return;
|
||||
}
|
||||
item->setData(bvidType, bvitDecor);
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::buses() const {
|
||||
QList<BlockBusItem * > ret;
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
QList<BlockBusItem *> BlockView::buses() const {
|
||||
QList<BlockBusItem *> ret;
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if ((i->data(bvidType).toInt() == bvitBus) && !i->data(bvidTmpItem).toBool())
|
||||
if (!copy_buses.contains((BlockBusItem*)i))
|
||||
ret << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
if (!copy_buses.contains((BlockBusItem *)i)) ret << qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::wrongConnectedBuses() const {
|
||||
QList<BlockBusItem * > sl = buses(), ret;
|
||||
QList<BlockItem * > bl = blocks();
|
||||
foreach (BlockItem * b, bl) {
|
||||
QVector<BlockItemPin * > pins = b->pins();
|
||||
foreach (BlockItemPin * p, pins)
|
||||
QList<BlockBusItem *> BlockView::wrongConnectedBuses() const {
|
||||
QList<BlockBusItem *> sl = buses(), ret;
|
||||
QList<BlockItem *> bl = blocks();
|
||||
foreach(BlockItem * b, bl) {
|
||||
QVector<BlockItemPin *> pins = b->pins();
|
||||
foreach(BlockItemPin * p, pins)
|
||||
if (p->state() == BlockItemPin::Reject) {
|
||||
QPointF pp = p->scenePos();
|
||||
foreach (BlockBusItem * s, sl)
|
||||
foreach(BlockBusItem * s, sl)
|
||||
if (s->pol.contains(pp))
|
||||
if (!ret.contains(s))
|
||||
ret << s;
|
||||
if (!ret.contains(s)) ret << s;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > BlockView::blocks() const {
|
||||
QList<BlockItem * > ret;
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool())
|
||||
ret << qgraphicsitem_cast<BlockItem*>(i);
|
||||
QList<BlockItem *> BlockView::blocks() const {
|
||||
QList<BlockItem *> ret;
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) ret << qgraphicsitem_cast<BlockItem *>(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<QGraphicsItem * > BlockView::decors() const {
|
||||
QList<QGraphicsItem*> ret, gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if ((i->data(bvidType).toInt() == bvitDecor) && !i->data(bvidTmpItem).toBool() && !i->data(bvidItemSelection).toBool() && (i->parentItem() == 0)
|
||||
&& (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i))
|
||||
QList<QGraphicsItem *> BlockView::decors() const {
|
||||
QList<QGraphicsItem *> ret, gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if ((i->data(bvidType).toInt() == bvitDecor) && !i->data(bvidTmpItem).toBool() && !i->data(bvidItemSelection).toBool() &&
|
||||
(i->parentItem() == 0) && (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem *)i))
|
||||
ret << i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return cbl.front();
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const {
|
||||
if (!b0 || !b1) return QList<BlockBusItem * >();
|
||||
QSet<BlockBusItem * > bs0 = QList2QSet(b0->connectedBuses()),
|
||||
bs1 = QList2QSet(b1->connectedBuses());
|
||||
QList<BlockBusItem *> BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const {
|
||||
if (!b0 || !b1) return QList<BlockBusItem *>();
|
||||
QSet<BlockBusItem *> bs0 = QList2QSet(b0->connectedBuses()), bs1 = QList2QSet(b1->connectedBuses());
|
||||
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->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;
|
||||
BlockBusItem * nb = new BlockBusItem();
|
||||
nb->setBusType(p0->busType());
|
||||
loadBus(nb);
|
||||
if (!bl0.isEmpty() && !bl1.isEmpty()) { // connect two existing buses
|
||||
if (!bl0.isEmpty() && !bl1.isEmpty()) { // connect two existing buses
|
||||
} else {
|
||||
if ((bl0.isEmpty() && !bl1.isEmpty()) || (bl1.isEmpty() && !bl0.isEmpty())) { // connect empty pin to existing bus
|
||||
BlockItemPin * ep = 0;
|
||||
BlockBusItem * eb = 0;
|
||||
if (bl0.isEmpty()) {ep = p0; eb = bl1[0];}
|
||||
else {ep = p1; eb = bl0[0];}
|
||||
double md = -1; int mi = -1;
|
||||
if (bl0.isEmpty()) {
|
||||
ep = p0;
|
||||
eb = bl1[0];
|
||||
} else {
|
||||
ep = p1;
|
||||
eb = bl0[0];
|
||||
}
|
||||
double md = -1;
|
||||
int mi = -1;
|
||||
QPointF sp = ep->scenePos();
|
||||
if (eb->pol.size() == 2) {
|
||||
eb->selSegment = 0;
|
||||
eb->addPoint((eb->pol[0] + eb->pol[1]) / 2.);
|
||||
eb->selPoint = -1;
|
||||
mi = 2;
|
||||
mi = 2;
|
||||
} else {
|
||||
for (int i = 0; i < eb->pol.size(); ++i) {
|
||||
if (eb->ends.contains(i)) continue;
|
||||
@@ -1092,7 +1080,7 @@ bool BlockView::connectPins(BlockItemPin * p0, BlockItemPin * p1) {
|
||||
}
|
||||
reconnectAll();
|
||||
newBusCreated(nb);
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << nb);
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << nb);
|
||||
emit connectionsChanged();
|
||||
return true;
|
||||
}
|
||||
@@ -1159,17 +1147,19 @@ void BlockView::fitInView() {
|
||||
|
||||
|
||||
QRectF BlockView::itemsBoundingRect() const {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
if (gi.isEmpty()) return QRectF();
|
||||
bool f = true;
|
||||
QRectF ret;
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->isVisible() && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i)) {
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->isVisible() && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem *)i)) {
|
||||
if (!(i->data(bvidItemSelection).toBool()) && !i->data(bvidTmpItem).toBool()) {
|
||||
QRectF br = i->mapRectToScene(i->boundingRect());
|
||||
if (br.width() <= 1 || br.height() <= 1) continue;
|
||||
if (f) ret = br;
|
||||
else ret |= br;
|
||||
if (f)
|
||||
ret = br;
|
||||
else
|
||||
ret |= br;
|
||||
f = false;
|
||||
}
|
||||
}
|
||||
@@ -1178,96 +1168,93 @@ QRectF BlockView::itemsBoundingRect() const {
|
||||
|
||||
|
||||
void BlockView::restoreSelState() {
|
||||
//qDebug() << "restoreSelState";
|
||||
foreach (QGraphicsItem * i, sel_items) {
|
||||
// qDebug() << "restoreSelState";
|
||||
foreach(QGraphicsItem * i, sel_items) {
|
||||
i->setPos(i->data(bvidItemPos).toPointF());
|
||||
}
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->data(bvidType).toInt() == bvitBus) {
|
||||
BlockBusItem * bi = qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
bi->pol = bi->bpol;
|
||||
BlockBusItem * bi = qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
bi->pol = bi->bpol;
|
||||
bi->prepareGeometryChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::saveSelState() {
|
||||
//qDebug() << "saveSelState";
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
sel_items = scene_->selectedItems();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
// qDebug() << "saveSelState";
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
sel_items = scene_->selectedItems();
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
i->setData(bvidSelected, i->isSelected());
|
||||
i->setData(bvidItemPos, i->pos());
|
||||
if (i->data(bvidType).toInt() == bvitBus)
|
||||
qgraphicsitem_cast<BlockBusItem*>(i)->bpol = qgraphicsitem_cast<BlockBusItem*>(i)->pol;
|
||||
if (i->data(bvidType).toInt() == bvitBus) qgraphicsitem_cast<BlockBusItem *>(i)->bpol = qgraphicsitem_cast<BlockBusItem *>(i)->pol;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::saveBusesState() {
|
||||
QList<BlockBusItem*> bl = buses();
|
||||
foreach (BlockBusItem * b, bl)
|
||||
QList<BlockBusItem *> bl = buses();
|
||||
foreach(BlockBusItem * b, bl)
|
||||
b->saveState();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::restoreBusesState() {
|
||||
QList<BlockBusItem*> bl = buses();
|
||||
foreach (BlockBusItem * b, bl)
|
||||
QList<BlockBusItem *> bl = buses();
|
||||
foreach(BlockBusItem * b, bl)
|
||||
b->restoreState();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::applySelRect(QGraphicsSceneMouseEvent * me) {
|
||||
QList<QGraphicsItem*> ci = sel_rect.collidingItems(Qt::IntersectsItemBoundingRect);
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
bool add = me->modifiers().testFlag(Qt::ControlModifier);
|
||||
QList<QGraphicsItem*> sil = scene_->selectedItems();
|
||||
block_emit_selection = true;
|
||||
if (!add) clearSelection();
|
||||
QList<QGraphicsItem *> ci = sel_rect.collidingItems(Qt::IntersectsItemBoundingRect);
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
bool add = me->modifiers().testFlag(Qt::ControlModifier);
|
||||
QList<QGraphicsItem *> sil = scene_->selectedItems();
|
||||
block_emit_selection = true;
|
||||
if (!add)
|
||||
clearSelection();
|
||||
else {
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
i->setSelected(i->data(bvidSelected).toBool());
|
||||
}
|
||||
foreach (QGraphicsItem * i, ci) {
|
||||
foreach(QGraphicsItem * i, ci) {
|
||||
i->setSelected(!i->isSelected());
|
||||
}
|
||||
block_emit_selection = false;
|
||||
if (sil != scene_->selectedItems())
|
||||
emit selectionChanged();
|
||||
if (sil != scene_->selectedItems()) emit selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::applyGridStep() {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->type() == QGraphicsItem::UserType + 2)
|
||||
qgraphicsitem_cast<BlockBusItem*>(i)->setGridStep(grid_step);
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->type() == QGraphicsItem::UserType + 2) qgraphicsitem_cast<BlockBusItem *>(i)->setGridStep(grid_step);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) {
|
||||
if (primary) {
|
||||
if (hpin)
|
||||
scene_pos_to = hpin->scenePos();
|
||||
if (hpin) scene_pos_to = hpin->scenePos();
|
||||
last_trace_from = scene_pos_from;
|
||||
trace_to = scene_pos_to;
|
||||
trace_to = scene_pos_to;
|
||||
}
|
||||
QRect sr = scene_->sceneRect().toRect();
|
||||
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;
|
||||
tm.restart();
|
||||
wavetrace.resize(sr.size() / grid_step);
|
||||
wavetrace.fill(BlockViewWavetrace::Empty);
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->data(bvidType).toInt() == bvitBlock) {
|
||||
QRect ir = i->mapRectToScene(i->boundingRect()).toRect().normalized();
|
||||
wavetrace.fill(QRect(ir.topLeft() / grid_step + dp, ir.bottomRight() / grid_step + dp), BlockViewWavetrace::Blocked);
|
||||
QVector<BlockItemPin * > pins = qgraphicsitem_cast<BlockItem * >(i)->pins();
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
QVector<BlockItemPin *> pins = qgraphicsitem_cast<BlockItem *>(i)->pins();
|
||||
foreach(BlockItemPin * p, pins) {
|
||||
if (p->busType() == bus->busType())
|
||||
wavetrace.fill(quantize(p->scenePos(), grid_step).toPoint() / grid_step + dp, BlockViewWavetrace::Empty);
|
||||
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) {
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->data(bvidType).toInt() == bvitBus) {
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem * >(i);
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
if (!b) continue;
|
||||
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;
|
||||
@@ -1287,24 +1274,23 @@ void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem
|
||||
if ((dx + dy) < grid_step) continue;
|
||||
BlockViewWavetrace::CellState cs = BlockViewWavetrace::Blocked;
|
||||
if (dx >= dy) { // by x
|
||||
sx = grid_step;
|
||||
sy = sx * dy / dx;
|
||||
sx = grid_step;
|
||||
sy = sx * dy / dx;
|
||||
steps = qRound(dx / grid_step);
|
||||
cs = BlockViewWavetrace::HorizontalBus;
|
||||
cs = BlockViewWavetrace::HorizontalBus;
|
||||
} else {
|
||||
sy = grid_step;
|
||||
sx = sy * dx / dy;
|
||||
sy = grid_step;
|
||||
sx = sy * dx / dy;
|
||||
steps = qRound(dy / grid_step);
|
||||
cs = BlockViewWavetrace::VerticalBus;
|
||||
cs = BlockViewWavetrace::VerticalBus;
|
||||
}
|
||||
sx *= signx;
|
||||
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) {
|
||||
QPoint tp = quantize(cp, grid_step).toPoint() / grid_step + dp;
|
||||
if (tp != qpt)
|
||||
wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
|
||||
//qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
|
||||
if (tp != qpt) wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
|
||||
// qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
|
||||
cp += QPointF(sx, sy);
|
||||
}
|
||||
}
|
||||
@@ -1313,67 +1299,63 @@ void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem
|
||||
bus->clear();
|
||||
if (wavetrace.trace(quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp, qpt)) {
|
||||
wavetrace.gatherPath();
|
||||
foreach (const QPoint & p, wavetrace.path()) {
|
||||
foreach(const QPoint & p, wavetrace.path()) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::clearBusStates() {
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->data(bvidType).toInt() == bvitBus) {
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
b->clearBusState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::matchBus() {
|
||||
match_bus = 0;
|
||||
bool bv = tmp_bus.isVisible();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
QList<BlockBusItem * > buses;
|
||||
QList<BlockItem * > blockl;
|
||||
match_bus = 0;
|
||||
bool bv = tmp_bus.isVisible();
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
QList<BlockBusItem *> buses;
|
||||
QList<BlockItem *> blockl;
|
||||
int sp = -1, ss = -1;
|
||||
QPointF point;
|
||||
iconnect = false;
|
||||
if (!tmp_bus.pol.isEmpty())
|
||||
point = tmp_bus.pol.back();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (!tmp_bus.pol.isEmpty()) point = tmp_bus.pol.back();
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i != bus_from) {
|
||||
if (i->data(bvidType).toInt() == bvitBus)
|
||||
buses << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
if (i->data(bvidType).toInt() == bvitBlock)
|
||||
blockl << qgraphicsitem_cast<BlockItem*>(i);
|
||||
if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
if (i->data(bvidType).toInt() == bvitBlock) blockl << qgraphicsitem_cast<BlockItem *>(i);
|
||||
}
|
||||
}
|
||||
foreach (BlockBusItem * b, buses) {
|
||||
foreach(BlockBusItem * b, buses) {
|
||||
b->clearBusState();
|
||||
b->selPoint = b->selSegment = -1;
|
||||
}
|
||||
if (!bv) return;
|
||||
BlockBusItem * b(0);
|
||||
if (m_pin_mc) {
|
||||
foreach (BlockItem * b_, blockl)
|
||||
foreach (BlockItemPin * p_, b_->pins())
|
||||
foreach(BlockItem * b_, blockl)
|
||||
foreach(BlockItemPin * p_, b_->pins())
|
||||
if (p_->scenePos() == point) {
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
//qDebug() << "1" << buses.size() << tmp_bus.pol;
|
||||
// qDebug() << "1" << buses.size() << tmp_bus.pol;
|
||||
for (int i = 0; i < buses.size(); ++i) {
|
||||
b = buses[i];
|
||||
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) || b == 0) return;
|
||||
//qDebug("2");
|
||||
// qDebug("2");
|
||||
match_bus = b;
|
||||
if ((b->busType() != tmp_bus.busType()) || b->connections_.value(sp, 0) != 0) {
|
||||
b->setBusState(false);
|
||||
@@ -1405,7 +1387,7 @@ void BlockView::matchBus() {
|
||||
}
|
||||
iconnect = true;
|
||||
b->setBusState(true);
|
||||
b->selPoint = sp;
|
||||
b->selPoint = sp;
|
||||
b->selSegment = ss;
|
||||
}
|
||||
}
|
||||
@@ -1416,8 +1398,7 @@ bool BlockView::connectTmpToBus(BlockBusItem * bus) {
|
||||
if (!bus->busState()) return false;
|
||||
if (tmp_bus.pol.size() < 2) return false;
|
||||
int np = bus->selPoint;
|
||||
if (np < 0)
|
||||
np = bus->addPoint(tmp_bus.pol.back());
|
||||
if (np < 0) np = bus->addPoint(tmp_bus.pol.back());
|
||||
if (np < 0) return false;
|
||||
tmp_bus.pol.pop_back();
|
||||
int lp = bus->pol.size();
|
||||
@@ -1433,18 +1414,16 @@ bool BlockView::connectTmpToBus(BlockBusItem * bus) {
|
||||
|
||||
void BlockView::markPins(int bus_type) {
|
||||
unhoverPins();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidType).toInt() == bvitPin) {
|
||||
BlockItemPin * p = qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
BlockItemPin * p = qgraphicsitem_cast<BlockItemPin *>(i);
|
||||
p->saveState();
|
||||
if (m_pin_mc) {
|
||||
if (p->busType() == bus_type)
|
||||
p->setState(BlockItemPin::Accept);
|
||||
if (p->busType() == bus_type) p->setState(BlockItemPin::Accept);
|
||||
} else {
|
||||
if (p->busType() == bus_type) {
|
||||
if (p->state() == BlockItemPin::Disconnected)
|
||||
p->setState(BlockItemPin::Accept);
|
||||
if (p->state() == BlockItemPin::Disconnected) p->setState(BlockItemPin::Accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1454,12 +1433,13 @@ void BlockView::markPins(int bus_type) {
|
||||
|
||||
void BlockView::unmarkPins(bool to_normal) {
|
||||
unhoverPins();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidType).toInt() == bvitPin) {
|
||||
qgraphicsitem_cast<BlockItemPin*>(i)->restoreState();
|
||||
qgraphicsitem_cast<BlockItemPin *>(i)->restoreState();
|
||||
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) {
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (excl_pin == ((BlockItemPin*)i)) continue;
|
||||
void BlockView::unhoverPins(BlockItemPin * excl_pin) {
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (excl_pin == ((BlockItemPin *)i)) continue;
|
||||
if (i->data(bvidType).toInt() == bvitPin) {
|
||||
((BlockItemPin*)i)->enlargePin(false);
|
||||
((BlockItemPin *)i)->enlargePin(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::simplifyBuses() {
|
||||
QList<BlockBusItem*> bl = buses();
|
||||
foreach (BlockBusItem * b, bl)
|
||||
QList<BlockBusItem *> bl = buses();
|
||||
foreach(BlockBusItem * b, bl)
|
||||
b->simplify();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::moveBuses(const QList<QGraphicsItem * > & items, QPointF dp) {
|
||||
void BlockView::moveBuses(const QList<QGraphicsItem *> & items, QPointF dp) {
|
||||
if (dp.isNull()) return;
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
QVector<BlockItemPin * > pins;
|
||||
QList<BlockBusItem * > buses;
|
||||
//qDebug() << "move" << dp;
|
||||
foreach (QGraphicsItem * i, items)
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
QVector<BlockItemPin *> pins;
|
||||
QList<BlockBusItem *> buses;
|
||||
// qDebug() << "move" << dp;
|
||||
foreach(QGraphicsItem * i, items)
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) && i->flags().testFlag(QGraphicsItem::ItemIsMovable))
|
||||
pins << qgraphicsitem_cast<BlockItem*>(i)->pins();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(bvidType).toInt() == bvitBus)
|
||||
buses << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
foreach (BlockBusItem * b, buses) {
|
||||
QList<BlockItemPin * > bpins = b->connections_.values();
|
||||
pins << qgraphicsitem_cast<BlockItem *>(i)->pins();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
foreach(BlockBusItem * b, buses) {
|
||||
QList<BlockItemPin *> bpins = b->connections_.values();
|
||||
if (!bpins.isEmpty()) {
|
||||
foreach (BlockItemPin * p, pins)
|
||||
foreach(BlockItemPin * p, pins)
|
||||
bpins.removeAll(p);
|
||||
if (bpins.isEmpty()) {
|
||||
b->movePolyline(dp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
foreach(BlockItemPin * p, pins) {
|
||||
QList<int> ends = b->connections_.keys(p);
|
||||
for (int i = 0; i < ends.size(); ++i) {
|
||||
QPointF pdp = dp;
|
||||
double ang = 0.;
|
||||
double ang = 0.;
|
||||
switch (p->alignment()) {
|
||||
case Qt::AlignRight : pdp.setX(0.); ang = 0.; 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;
|
||||
case Qt::AlignRight:
|
||||
pdp.setX(0.);
|
||||
ang = 0.;
|
||||
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;
|
||||
}
|
||||
QVector<int> epl = b->endpointLine(ends[i], ang);
|
||||
foreach (int e, epl)
|
||||
foreach(int e, epl)
|
||||
b->movePoint(e, pdp);
|
||||
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 * > ret;
|
||||
QList<BlockBusItem *> BlockView::internalBuses(const QList<BlockItem *> & items) {
|
||||
QList<BlockBusItem *> ret;
|
||||
if (items.isEmpty()) return ret;
|
||||
QList<BlockBusItem * > sbl = buses();
|
||||
QSet<BlockItem * > sis = QList2QSet(items);
|
||||
foreach (BlockBusItem * bi, sbl) {
|
||||
QList<BlockBusItem *> sbl = buses();
|
||||
QSet<BlockItem *> sis = QList2QSet(items);
|
||||
foreach(BlockBusItem * bi, sbl) {
|
||||
if (bi->connectedBlocks().isEmpty()) continue;
|
||||
QSet<BlockItem * > bis = QList2QSet(bi->connectedBlocks());
|
||||
if ((bis - sis).isEmpty())
|
||||
ret << bi;
|
||||
QSet<BlockItem *> bis = QList2QSet(bi->connectedBlocks());
|
||||
if ((bis - sis).isEmpty()) ret << bi;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
|
||||
QList<BlockItemPin * > ret;
|
||||
QList<BlockItemPin *> BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
|
||||
QList<BlockItemPin *> ret;
|
||||
bool up = km.testFlag(Qt::ShiftModifier);
|
||||
bool down = km.testFlag(Qt::ControlModifier);
|
||||
bool ab = km.testFlag(Qt::AltModifier);
|
||||
//qDebug() << "nearPins" << km;
|
||||
// qDebug() << "nearPins" << km;
|
||||
if (!pin || (!up && !down)) return ret;
|
||||
const BlockItem * src = pin->parent();
|
||||
if (!src) return ret;
|
||||
@@ -1562,17 +1552,16 @@ QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModif
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!dirs[i]) continue;
|
||||
const BlockItem * cb = src;
|
||||
BlockItemPin * cpin = pin;
|
||||
//qDebug() << "dir" << dirs[i];
|
||||
BlockItemPin * cpin = pin;
|
||||
// qDebug() << "dir" << dirs[i];
|
||||
while (cpin) {
|
||||
//qDebug() << "cur" << cpin;
|
||||
QList<QGraphicsItem * > il = scene_->items(cpin->scenePos() + QPointF(0., dy[i] * cb->pinsMargin()));
|
||||
BlockItemPin * np = getPin(il);
|
||||
// qDebug() << "cur" << cpin;
|
||||
QList<QGraphicsItem *> il = scene_->items(cpin->scenePos() + QPointF(0., dy[i] * cb->pinsMargin()));
|
||||
BlockItemPin * np = getPin(il);
|
||||
if (np == cpin) break;
|
||||
cpin = np;
|
||||
if (cpin) {
|
||||
if (((cb != cpin->parent()) && !ab) ||
|
||||
(cpin->state() != BlockItemPin::Disconnected)) {
|
||||
if (((cb != cpin->parent()) && !ab) || (cpin->state() != BlockItemPin::Disconnected)) {
|
||||
break;
|
||||
}
|
||||
cb = cpin->parent();
|
||||
@@ -1585,20 +1574,19 @@ QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModif
|
||||
|
||||
|
||||
BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const {
|
||||
foreach (QGraphicsItem * i, list) {
|
||||
if (i->data(bvidType).toInt() == bvitPin)
|
||||
return qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
foreach(QGraphicsItem * i, list) {
|
||||
if (i->data(bvidType).toInt() == bvitPin) return qgraphicsitem_cast<BlockItemPin *>(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
|
||||
//qDebug() << "restore for" << last_multiconnect_pl.size();
|
||||
foreach (BlockItemPin * p, last_multiconnect_pl)
|
||||
// qDebug() << "restore for" << last_multiconnect_pl.size();
|
||||
foreach(BlockItemPin * p, last_multiconnect_pl)
|
||||
p->restoreState();
|
||||
QList<BlockItemPin * > pl = nearPins(pin, km);
|
||||
foreach (BlockItemPin * p, pl) {
|
||||
QList<BlockItemPin *> pl = nearPins(pin, km);
|
||||
foreach(BlockItemPin * p, pl) {
|
||||
p->saveState();
|
||||
p->setState(BlockItemPin::Hover);
|
||||
}
|
||||
@@ -1616,21 +1604,19 @@ void BlockView::hideTmpBuses(bool clear) {
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > BlockView::selectedBlocks() const {
|
||||
QList<BlockItem * > ret;
|
||||
QList<QGraphicsItem * > sil = scene()->selectedItems();
|
||||
foreach (QGraphicsItem * b, sil)
|
||||
if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool())
|
||||
ret << qgraphicsitem_cast<BlockItem*>(b);
|
||||
QList<BlockItem *> BlockView::selectedBlocks() const {
|
||||
QList<BlockItem *> ret;
|
||||
QList<QGraphicsItem *> sil = scene()->selectedItems();
|
||||
foreach(QGraphicsItem * b, sil)
|
||||
if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) ret << qgraphicsitem_cast<BlockItem *>(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<QGraphicsItem * > BlockView::selectedDecors() const {
|
||||
QList<QGraphicsItem * > ret, sil = decors();
|
||||
foreach (QGraphicsItem * b, sil)
|
||||
if (b->isSelected())
|
||||
ret << b;
|
||||
QList<QGraphicsItem *> BlockView::selectedDecors() const {
|
||||
QList<QGraphicsItem *> ret, sil = decors();
|
||||
foreach(QGraphicsItem * b, sil)
|
||||
if (b->isSelected()) ret << b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1643,7 +1629,7 @@ void BlockView::animateNav(QRectF d, double scl) {
|
||||
return;
|
||||
}
|
||||
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_grid = isGridVisible();
|
||||
setRenderHint(QPainter::Antialiasing, false);
|
||||
@@ -1667,14 +1653,11 @@ void BlockView::adjustThumb() {
|
||||
scl = thumb_size.width() / sr.width();
|
||||
else
|
||||
scl = thumb_size.height() / sr.height();
|
||||
tr = sr * scl;
|
||||
tr = sr * scl;
|
||||
int sx = 0, sy = 0;
|
||||
if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff))
|
||||
sx = verticalScrollBar()->width();
|
||||
if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff))
|
||||
sy = horizontalScrollBar()->height();
|
||||
widget_thumb.setGeometry(QRect(QPoint(width() - tr.width() - 10 - sx,
|
||||
height() - tr.height() - 10 - sy), tr.toSize()));
|
||||
if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) sx = verticalScrollBar()->width();
|
||||
if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) 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) {
|
||||
move_bus_point = true;
|
||||
prev_tcb = m_trace_with_buses;
|
||||
prev_tcb = m_trace_with_buses;
|
||||
newBusStarted(bus_type);
|
||||
markPins(bus_type);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::pinHoverInOut(BlockItemPin * pin) {
|
||||
//qDebug() << "pinHoverInOut" << pin << pin->state();
|
||||
// qDebug() << "pinHoverInOut" << pin << pin->state();
|
||||
highlightNearPins(pin, QApplication::keyboardModifiers());
|
||||
}
|
||||
|
||||
|
||||
void BlockView::checkPaste(bool queued) {
|
||||
const QMimeData * mime = QApplication::clipboard()->mimeData();
|
||||
bool ret = false;
|
||||
if (mime)
|
||||
ret = mime->hasFormat(_BlockView_Mime_);
|
||||
if (queued) QMetaObject::invokeMethod(this, [this, ret](){pasteEnabledChanged(ret);}, Qt::QueuedConnection);
|
||||
else emit pasteEnabledChanged(ret);
|
||||
bool ret = false;
|
||||
if (mime) ret = mime->hasFormat(_BlockView_Mime_);
|
||||
if (queued)
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, ret]() { pasteEnabledChanged(ret); },
|
||||
Qt::QueuedConnection);
|
||||
else
|
||||
emit pasteEnabledChanged(ret);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::setBusSquareNodes(bool yes) {
|
||||
square_node = yes;
|
||||
QList<BlockBusItem * > sbl = buses();
|
||||
foreach (BlockBusItem * b, sbl) {
|
||||
square_node = yes;
|
||||
QList<BlockBusItem *> sbl = buses();
|
||||
foreach(BlockBusItem * b, sbl) {
|
||||
b->setSquareNodes(square_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) {
|
||||
trace(item->press_pos, to, &tmp_bus);
|
||||
tmp_bus.show();
|
||||
@@ -1740,17 +1726,18 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
|
||||
tmp_bus.hide();
|
||||
if (tmp_bus.pol.size() < 2) return;
|
||||
tmp_bus.pol.pop_front();
|
||||
if ((tmp_bus.pol.size() == 1) && (tmp_bus.pol[0] == item->press_pos))
|
||||
return;
|
||||
if ((tmp_bus.pol.size() == 1) && (tmp_bus.pol[0] == item->press_pos)) return;
|
||||
int np = item->addPoint(item->press_pos);
|
||||
if (np < 0) return;
|
||||
if (match_bus) {
|
||||
if (iconnect) tmp_bus.pol.pop_back();
|
||||
else return;
|
||||
if (iconnect)
|
||||
tmp_bus.pol.pop_back();
|
||||
else
|
||||
return;
|
||||
}
|
||||
if (item == match_bus) return;
|
||||
int snp = np;
|
||||
int lp = item->pol.size();
|
||||
int lp = item->pol.size();
|
||||
if (!tmp_bus.pol.isEmpty()) {
|
||||
item->pol << tmp_bus.pol;
|
||||
item->segments << QPair<int, int>(np, lp);
|
||||
@@ -1760,8 +1747,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
|
||||
if (match_bus != 0) {
|
||||
if (!iconnect) return;
|
||||
np = match_bus->selPoint;
|
||||
if (np < 0)
|
||||
np = match_bus->addPoint(trace_to);
|
||||
if (np < 0) np = match_bus->addPoint(trace_to);
|
||||
if (np < 0) return;
|
||||
lp = item->pol.size();
|
||||
item->pol << match_bus->pol;
|
||||
@@ -1777,7 +1763,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
|
||||
}
|
||||
item->updateGeometry();
|
||||
newBusCreated(item);
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << item);
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem *>() << item);
|
||||
emit connectionsChanged();
|
||||
tmp_bus.clear();
|
||||
}
|
||||
@@ -1785,7 +1771,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
|
||||
|
||||
void BlockView::newBranchCancel() {
|
||||
unmarkPins();
|
||||
//qDebug() << "cancel";
|
||||
// qDebug() << "cancel";
|
||||
new_branch = false;
|
||||
hideTmpBuses();
|
||||
}
|
||||
@@ -1794,25 +1780,25 @@ void BlockView::newBranchCancel() {
|
||||
void BlockView::removedBus(QObject * o) {
|
||||
mm_ci = 0;
|
||||
reconnectAll();
|
||||
BlockBusItem * bus = (BlockBusItem*)o;
|
||||
BlockBusItem * bus = (BlockBusItem *)o;
|
||||
if (bus->property("_nodelete_").toBool()) return;
|
||||
emitActionEvent(BlockItemBase::BusRemove, QList<QGraphicsItem*>() << bus);
|
||||
emitActionEvent(BlockItemBase::BusRemove, QList<QGraphicsItem *>() << bus);
|
||||
emit connectionsChanged();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removedBlock(QObject * o) {
|
||||
if (o == ghost_) return;
|
||||
emit blockRemoved((BlockItem*)o);
|
||||
emitActionEvent(BlockItemBase::BlockRemove, QList<QGraphicsItem*>() << qgraphicsitem_cast<QGraphicsItem*>((BlockItem*)o));
|
||||
emit blockRemoved((BlockItem *)o);
|
||||
emitActionEvent(BlockItemBase::BlockRemove, QList<QGraphicsItem *>() << qgraphicsitem_cast<QGraphicsItem *>((BlockItem *)o));
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removeJunk() {
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidType).toInt() != bvitBus) continue;
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
if (b->pol.size() <= 1) {
|
||||
b->deleteLater();
|
||||
}
|
||||
@@ -1823,17 +1809,21 @@ void BlockView::removeJunk() {
|
||||
void BlockView::sceneSelectionChanged() {
|
||||
bool ie = scene()->selectedItems().isEmpty();
|
||||
emit copyEnabledChanged(!ie);
|
||||
if (!block_emit_selection)
|
||||
emit selectionChanged();
|
||||
if (!block_emit_selection) emit selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::_setThumb(double v) {
|
||||
_talpha = v;
|
||||
_talpha = v;
|
||||
QWidget * w = &widget_thumb;
|
||||
QMetaObject::invokeMethod(this, [w](){w->update();}, Qt::QueuedConnection);
|
||||
if (_talpha <= 0.01) widget_thumb.hide();
|
||||
else widget_thumb.show();
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[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();
|
||||
if (vw < 1. || vh < 1. || v.isEmpty()) return;
|
||||
QTransform matrix;
|
||||
double scl = qMin(vw / v.width(), vh / v.height());
|
||||
double scl = qMin(vw / v.width(), vh / v.height());
|
||||
double ascl = appScale(this);
|
||||
if (scl > 0.02 * ascl && scl < 50.0 * ascl) {
|
||||
matrix.scale(scl, scl);
|
||||
@@ -1865,23 +1855,21 @@ void BlockView::_navFinished() {
|
||||
|
||||
|
||||
void BlockView::reconnectAll() {
|
||||
//qDebug() << "reconnect";
|
||||
// qDebug() << "reconnect";
|
||||
removeJunk();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
QList<BlockItemPin * > pins;
|
||||
QList<BlockBusItem * > buses;
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidType).toInt() == bvitPin)
|
||||
pins << qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
if (i->data(bvidType).toInt() == bvitBus)
|
||||
buses << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
QList<BlockItemPin *> pins;
|
||||
QList<BlockBusItem *> buses;
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidType).toInt() == bvitPin) pins << qgraphicsitem_cast<BlockItemPin *>(i);
|
||||
if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
|
||||
}
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
foreach(BlockItemPin * p, pins) {
|
||||
p->clearStateStack();
|
||||
p->setState(BlockItemPin::Disconnected);
|
||||
p->buses_.clear();
|
||||
}
|
||||
foreach (BlockBusItem * b, buses) {
|
||||
foreach(BlockBusItem * b, buses) {
|
||||
b->connections_.clear();
|
||||
QVector<int> conns(b->endpoints());
|
||||
for (int c = 0; c < conns.size(); ++c) {
|
||||
@@ -1890,11 +1878,10 @@ void BlockView::reconnectAll() {
|
||||
if (!pins[j]->isVisible()) continue;
|
||||
QPointF pp = pins[j]->scenePos();
|
||||
if ((cp - pp).manhattanLength() <= (grid_step / 2.)) {
|
||||
//qDebug() << "found";
|
||||
// qDebug() << "found";
|
||||
if (b->busType() == pins[j]->busType()) {
|
||||
b->connections_[conns[c]] = pins[j];
|
||||
if (!pins[j]->buses_.contains(b))
|
||||
pins[j]->buses_ << b;
|
||||
if (!pins[j]->buses_.contains(b)) pins[j]->buses_ << b;
|
||||
pins[j]->setState(BlockItemPin::Connected);
|
||||
} else
|
||||
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) {
|
||||
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running))
|
||||
nav_target = _nav();
|
||||
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) nav_target = _nav();
|
||||
QRectF r = nav_target;
|
||||
QPoint mp;
|
||||
if (underMouse()) mp = mapFromGlobal(QCursor::pos());
|
||||
else mp = QPoint(viewport()->width() / 2, viewport()->height() / 2);
|
||||
if (underMouse())
|
||||
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 pw = r.width(), ph = r.height();
|
||||
r.setWidth(r.width() / factor);
|
||||
@@ -1930,11 +1918,11 @@ void BlockView::zoomReset() {
|
||||
|
||||
|
||||
void BlockView::copyToClipboard() {
|
||||
QList<BlockItem*> bll = selectedBlocks();
|
||||
QList<QGraphicsItem*> del = selectedDecors();
|
||||
//qDebug() << "copy" << bll.size() << del.size();
|
||||
QList<BlockItem *> bll = selectedBlocks();
|
||||
QList<QGraphicsItem *> del = selectedDecors();
|
||||
// qDebug() << "copy" << bll.size() << del.size();
|
||||
if (bll.isEmpty() && del.isEmpty()) return;
|
||||
QList<BlockBusItem*> bul = internalBuses(bll);
|
||||
QList<BlockBusItem *> bul = internalBuses(bll);
|
||||
QByteArray ba;
|
||||
QDataStream s(&ba, QIODevice::ReadWrite);
|
||||
s << uint(0x89abcdef) << bll << bul << del;
|
||||
@@ -1949,11 +1937,11 @@ void BlockView::pasteFromClipboard() {
|
||||
if (!mime) return;
|
||||
if (!mime->hasFormat(_BlockView_Mime_)) return;
|
||||
QByteArray ba = mime->data(_BlockView_Mime_);
|
||||
//qDebug() << "paste" << ba.size();
|
||||
// qDebug() << "paste" << ba.size();
|
||||
if (ba.size() < 4) return;
|
||||
QList<BlockItem*> bll;
|
||||
QList<BlockBusItem*> bul;
|
||||
QList<QGraphicsItem*> del, gl;
|
||||
QList<BlockItem *> bll;
|
||||
QList<BlockBusItem *> bul;
|
||||
QList<QGraphicsItem *> del, gl;
|
||||
uint hdr = 0;
|
||||
QDataStream s(ba);
|
||||
s >> hdr;
|
||||
@@ -1962,24 +1950,26 @@ void BlockView::pasteFromClipboard() {
|
||||
int all = bll.size() + bul.size() + del.size();
|
||||
if (all == 0) return;
|
||||
QRectF br;
|
||||
foreach (BlockItem * b, bll) {
|
||||
foreach(BlockItem * b, bll) {
|
||||
br |= b->boundingRect().translated(b->pos());
|
||||
gl << b;
|
||||
}
|
||||
foreach (BlockBusItem * b, bul)
|
||||
foreach(BlockBusItem * b, bul)
|
||||
gl << b;
|
||||
foreach (QGraphicsItem * b, del)
|
||||
foreach(QGraphicsItem * b, del)
|
||||
br |= b->boundingRect().translated(b->pos());
|
||||
gl << del;
|
||||
QPointF copy_dp;
|
||||
if (underMouse()) copy_dp = mapToScene(mapFromGlobal(QCursor::pos()));
|
||||
else copy_dp = mapToScene(rect().center());
|
||||
if (underMouse())
|
||||
copy_dp = mapToScene(mapFromGlobal(QCursor::pos()));
|
||||
else
|
||||
copy_dp = mapToScene(rect().center());
|
||||
copy_dp -= br.center();
|
||||
copy_dp = quantize(copy_dp, grid_step);
|
||||
copy_dp = quantize(copy_dp, grid_step);
|
||||
ae_enabled = false;
|
||||
if (!bll.isEmpty()) copyBlocks(bll, copy_dp);
|
||||
if (!bul.isEmpty()) copyBuses(bul, copy_dp);
|
||||
foreach (QGraphicsItem * i, del)
|
||||
foreach(QGraphicsItem * i, del)
|
||||
i->setPos(i->pos() + copy_dp);
|
||||
addItems(del);
|
||||
ae_enabled = true;
|
||||
@@ -1988,80 +1978,75 @@ void BlockView::pasteFromClipboard() {
|
||||
|
||||
|
||||
void BlockView::selectNone() {
|
||||
bool pb = block_emit_selection;
|
||||
block_emit_selection = true;
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
bool pb = block_emit_selection;
|
||||
block_emit_selection = true;
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
i->setSelected(false);
|
||||
block_emit_selection = pb;
|
||||
if (!block_emit_selection)
|
||||
emit selectionChanged();
|
||||
if (!block_emit_selection) emit selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::selectAll() {
|
||||
bool pb = block_emit_selection;
|
||||
block_emit_selection = true;
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable))
|
||||
i->setSelected(true);
|
||||
bool pb = block_emit_selection;
|
||||
block_emit_selection = true;
|
||||
QList<QGraphicsItem *> gi = scene_->items();
|
||||
foreach(QGraphicsItem * i, gi)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(true);
|
||||
block_emit_selection = pb;
|
||||
if (!block_emit_selection)
|
||||
emit selectionChanged();
|
||||
if (!block_emit_selection) emit selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removeSelected() {
|
||||
QList<QGraphicsItem*> gi = scene_->selectedItems(), ai;
|
||||
QList<QGraphicsItem *> gi = scene_->selectedItems(), ai;
|
||||
blockSignals(true);
|
||||
QList<BlockBusItem * > sbuses = buses(), dbuses, wbuses = wrongConnectedBuses();
|
||||
foreach (BlockBusItem * i, sbuses)
|
||||
if (i->connectedBlocks().isEmpty())
|
||||
dbuses << i;
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
QList<BlockBusItem *> sbuses = buses(), dbuses, wbuses = wrongConnectedBuses();
|
||||
foreach(BlockBusItem * i, sbuses)
|
||||
if (i->connectedBlocks().isEmpty()) dbuses << i;
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidTmpItem).toBool()) continue;
|
||||
if (i->data(bvidType).toInt() == bvitBlock)
|
||||
ai << qgraphicsitem_cast<QGraphicsItem*>(i);
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) || (i->data(bvidType).toInt() == bvitDecor)) {
|
||||
if (i->data(bvidType).toInt() == bvitBlock) ai << qgraphicsitem_cast<QGraphicsItem *>(i);
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) ||
|
||||
(i->data(bvidType).toInt() == bvitDecor)) {
|
||||
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
reconnectAll();
|
||||
foreach (BlockBusItem * i, sbuses)
|
||||
foreach(BlockBusItem * i, sbuses)
|
||||
if (i->connectedBlocks().isEmpty())
|
||||
if (!dbuses.contains(i))
|
||||
delete i;
|
||||
if (!dbuses.contains(i)) delete i;
|
||||
|
||||
blockSignals(false);
|
||||
foreach (QGraphicsItem * i, ai)
|
||||
emit blockRemoved((BlockItem*)i);
|
||||
foreach(QGraphicsItem * i, ai)
|
||||
emit blockRemoved((BlockItem *)i);
|
||||
emitActionEvent(BlockItemBase::BlockRemove, ai);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removeAll() {
|
||||
last_multiconnect_pl.clear();
|
||||
QList<QGraphicsItem*> gi = scene_->items(), ai;
|
||||
QList<QGraphicsItem *> gi = scene_->items(), ai;
|
||||
blockSignals(true);
|
||||
match_bus = bus_from = cur_bus = nullptr;
|
||||
mm_ci = nullptr;
|
||||
hpin = nullptr;
|
||||
ghost_ = nullptr;
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
mm_ci = nullptr;
|
||||
hpin = nullptr;
|
||||
ghost_ = nullptr;
|
||||
foreach(QGraphicsItem * i, gi) {
|
||||
if (i->data(bvidTmpItem).toBool()) continue;
|
||||
if (i->data(bvidType).toInt() == bvitBlock)
|
||||
ai << qgraphicsitem_cast<QGraphicsItem*>(i);
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) || (i->data(bvidType).toInt() == bvitDecor)) {
|
||||
if (i->data(bvidType).toInt() == bvitBlock) ai << qgraphicsitem_cast<QGraphicsItem *>(i);
|
||||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) ||
|
||||
(i->data(bvidType).toInt() == bvitDecor)) {
|
||||
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));
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
}
|
||||
blockSignals(false);
|
||||
foreach (QGraphicsItem * i, ai)
|
||||
emit blockRemoved((BlockItem*)i);
|
||||
foreach(QGraphicsItem * i, ai)
|
||||
emit blockRemoved((BlockItem *)i);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef 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 "blockviewwavetrace.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(BlockItem*)
|
||||
Q_DECLARE_METATYPE(BlockItemPin*)
|
||||
Q_DECLARE_METATYPE(BlockBusItem*)
|
||||
#include <QDebug>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#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_ENUMS(SelectionMode)
|
||||
|
||||
@@ -77,34 +77,37 @@ public:
|
||||
MultiSelection
|
||||
};
|
||||
|
||||
QPen gridPen() const {return grid_pen;}
|
||||
bool isGridVisible() const {return grid_visible;}
|
||||
bool isSnapToGrid() const {return grid_snap;}
|
||||
bool isPostMoveConnectEnabled() const {return pm_connect;}
|
||||
bool isNavigationEnabled() const {return navigation;}
|
||||
bool isNavigateAnimationEnabled() const {return is_nav_anim;}
|
||||
bool isBlockAnimationEnabled() const {return is_block_anim;}
|
||||
bool isConnectByMouseEnabled() const {return m_connect;}
|
||||
bool isTraceConsiderBuses() const {return m_trace_with_buses;}
|
||||
bool isPinMulticonnectEnabled() const {return m_pin_mc;}
|
||||
bool isMiniMapEnabled() const {return minimap;}
|
||||
bool isZoomWheelOnly() const {return wheel_zoom;}
|
||||
bool isBusSquareNodes() const {return square_node;}
|
||||
double gridStep() const {return grid_step;}
|
||||
double gridPointsWidth() const {return grid_points;}
|
||||
SelectionMode selectionMode() const {return smode;}
|
||||
void setSelectionMode(SelectionMode mode) {smode = mode;}
|
||||
QPen gridPen() const { return grid_pen; }
|
||||
bool isGridVisible() const { return grid_visible; }
|
||||
bool isSnapToGrid() const { return grid_snap; }
|
||||
bool isPostMoveConnectEnabled() const { return pm_connect; }
|
||||
bool isNavigationEnabled() const { return navigation; }
|
||||
bool isNavigateAnimationEnabled() const { return is_nav_anim; }
|
||||
bool isBlockAnimationEnabled() const { return is_block_anim; }
|
||||
bool isConnectByMouseEnabled() const { return m_connect; }
|
||||
bool isTraceConsiderBuses() const { return m_trace_with_buses; }
|
||||
bool isPinMulticonnectEnabled() const { return m_pin_mc; }
|
||||
bool isMiniMapEnabled() const { return minimap; }
|
||||
bool isZoomWheelOnly() const { return wheel_zoom; }
|
||||
bool isBusSquareNodes() const { return square_node; }
|
||||
double gridStep() const { return grid_step; }
|
||||
double gridPointsWidth() const { return grid_points; }
|
||||
SelectionMode selectionMode() const { return smode; }
|
||||
void setSelectionMode(SelectionMode mode) { smode = mode; }
|
||||
|
||||
void addItems(QList<QGraphicsItem * > items) {foreach (QGraphicsItem * i, items) addItem(i);}
|
||||
QList<BlockBusItem * > buses() const;
|
||||
QList<BlockBusItem * > wrongConnectedBuses() const;
|
||||
QList<BlockItem * > blocks() const;
|
||||
QList<QGraphicsItem * > decors() const;
|
||||
void addItems(QList<QGraphicsItem *> items) {
|
||||
foreach(QGraphicsItem * i, items)
|
||||
addItem(i);
|
||||
}
|
||||
QList<BlockBusItem *> buses() const;
|
||||
QList<BlockBusItem *> wrongConnectedBuses() const;
|
||||
QList<BlockItem *> blocks() const;
|
||||
QList<QGraphicsItem *> decors() 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);
|
||||
QList<BlockItem * > selectedBlocks() const;
|
||||
QList<QGraphicsItem * > selectedDecors() const;
|
||||
QList<BlockItem *> selectedBlocks() const;
|
||||
QList<QGraphicsItem *> selectedDecors() const;
|
||||
|
||||
void setTransform(const QTransform & matrix, bool combine = false);
|
||||
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 clearBusStates();
|
||||
void matchBus();
|
||||
bool connectTmpToBus(BlockBusItem* bus);
|
||||
bool connectTmpToBus(BlockBusItem * bus);
|
||||
void markPins(int bus_type);
|
||||
void unmarkPins(bool to_normal = false);
|
||||
void hoverAcceptedPin(BlockItemPin * pin, bool hover);
|
||||
void unhoverPins(BlockItemPin * excl_pin = 0);
|
||||
void simplifyBuses();
|
||||
void moveBuses(const QList<QGraphicsItem * > & items, QPointF dp);
|
||||
QList<BlockBusItem * > internalBuses(const QList<BlockItem * > & items);
|
||||
QList<BlockItemPin * > nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
|
||||
BlockItemPin * getPin(const QList<QGraphicsItem * > & list) const;
|
||||
void moveBuses(const QList<QGraphicsItem *> & items, QPointF dp);
|
||||
QList<BlockBusItem *> internalBuses(const QList<BlockItem *> & items);
|
||||
QList<BlockItemPin *> nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
|
||||
BlockItemPin * getPin(const QList<QGraphicsItem *> & list) const;
|
||||
void highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
|
||||
void hideTmpBuses(bool clear = true);
|
||||
double _thumb() const {return _talpha;}
|
||||
double _thumb() const { return _talpha; }
|
||||
QRectF _nav() const;
|
||||
void animateNav(QRectF d, double scl = 0.);
|
||||
void scrollFromThumb();
|
||||
void deleteCopyTemp();
|
||||
void emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem * > items);
|
||||
void emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem *> items);
|
||||
void setGhost(BlockItem * item);
|
||||
void clearGhost();
|
||||
BlockItem * ghost() const {return ghost_;}
|
||||
BlockItem * ghost() const { return ghost_; }
|
||||
|
||||
virtual void loadBus(BlockBusItem * bus) {}
|
||||
virtual void copyBlocks(QList<BlockItem * > items, QPointF offset) {}
|
||||
virtual void copyBuses(QList<BlockBusItem * > items, QPointF offset) {}
|
||||
virtual void copyBlocks(QList<BlockItem *> items, QPointF offset) {}
|
||||
virtual void copyBuses(QList<BlockBusItem *> items, QPointF offset) {}
|
||||
virtual void newBusStarted(int bus_type) {}
|
||||
virtual void newBusCreated(BlockBusItem * bus) {}
|
||||
|
||||
QGraphicsScene * scene_;
|
||||
QGraphicsRectItem sel_rect;
|
||||
QGraphicsItem * mm_ci;
|
||||
QList<QGraphicsItem * > sel_items;
|
||||
QList<BlockItem * > copy_items;
|
||||
QList<BlockItemPin * > last_multiconnect_pl;
|
||||
QList<BlockBusItem * > copy_buses, tmp_buses;
|
||||
BlockBusItem tmp_bus, * match_bus, * bus_from, * cur_bus;
|
||||
QList<QGraphicsItem *> sel_items;
|
||||
QList<BlockItem *> copy_items;
|
||||
QList<BlockItemPin *> last_multiconnect_pl;
|
||||
QList<BlockBusItem *> copy_buses, tmp_buses;
|
||||
BlockBusItem tmp_bus, *match_bus, *bus_from, *cur_bus;
|
||||
BlockItemPin * hpin;
|
||||
BlockItem * ghost_;
|
||||
BlockViewWavetrace wavetrace;
|
||||
@@ -200,7 +203,8 @@ protected:
|
||||
Qt::KeyboardModifiers mm_mods;
|
||||
QPropertyAnimation thumb_anim, nav_anim;
|
||||
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 nav_prev_aa, nav_prev_imaa, nav_prev_grid, square_node, block_emit_selection;
|
||||
double grid_step, grid_points, cur_scl, _talpha, thumb_scl;
|
||||
@@ -225,28 +229,41 @@ protected slots:
|
||||
void startBusPointMove(int bus_type);
|
||||
void pinHoverInOut(BlockItemPin * pin);
|
||||
void checkPaste(bool queued);
|
||||
void checkPaste() {checkPaste(false);}
|
||||
void checkPaste() { checkPaste(false); }
|
||||
|
||||
public slots:
|
||||
void setGridPen(const QPen & pen) {grid_pen = pen; _updateBack();}
|
||||
void setGridVisible(bool yes) {grid_visible = yes; _updateBack();}
|
||||
void setSnapToGrid(bool yes) {grid_snap = yes;}
|
||||
void setGridStep(double step) {grid_step = step; applyGridStep(); _updateBack();}
|
||||
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 setGridPen(const QPen & pen) {
|
||||
grid_pen = pen;
|
||||
_updateBack();
|
||||
}
|
||||
void setGridVisible(bool yes) {
|
||||
grid_visible = yes;
|
||||
_updateBack();
|
||||
}
|
||||
void setSnapToGrid(bool yes) { grid_snap = yes; }
|
||||
void setGridStep(double step) {
|
||||
grid_step = step;
|
||||
applyGridStep();
|
||||
_updateBack();
|
||||
}
|
||||
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 zoom(double factor);
|
||||
void zoomIn() {zoom(1.2);}
|
||||
void zoomOut() {zoom(1. / 1.2);}
|
||||
void zoomIn() { zoom(1.2); }
|
||||
void zoomOut() { zoom(1. / 1.2); }
|
||||
void zoomReset();
|
||||
|
||||
void copyToClipboard();
|
||||
@@ -261,17 +278,16 @@ public slots:
|
||||
void addItem(QGraphicsItem * item, bool emit_action = true);
|
||||
|
||||
signals:
|
||||
void blockDoubleClicked(BlockItem * );
|
||||
void blockHoverEnter(BlockItem * );
|
||||
void blockHoverLeave(BlockItem * );
|
||||
void busDoubleClicked(BlockBusItem * );
|
||||
void schemeAction(BlockItemBase::Action action, QList<QGraphicsItem * > items);
|
||||
void blockDoubleClicked(BlockItem *);
|
||||
void blockHoverEnter(BlockItem *);
|
||||
void blockHoverLeave(BlockItem *);
|
||||
void busDoubleClicked(BlockBusItem *);
|
||||
void schemeAction(BlockItemBase::Action action, QList<QGraphicsItem *> items);
|
||||
void blockRemoved(BlockItem * item);
|
||||
void connectionsChanged();
|
||||
void copyEnabledChanged(bool);
|
||||
void pasteEnabledChanged(bool);
|
||||
void selectionChanged();
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKVIEW_H
|
||||
|
||||
@@ -11,8 +11,7 @@ BlockViewWavetrace::BlockViewWavetrace(int width, int height) {
|
||||
void BlockViewWavetrace::resize(int width, int height) {
|
||||
wid = width;
|
||||
hei = height;
|
||||
if (field.size() != wid)
|
||||
field.resize(wid);
|
||||
if (field.size() != wid) field.resize(wid);
|
||||
for (int i = 0; i < wid; ++i) {
|
||||
if (field[i].size() != 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) {
|
||||
short p = field[px][py].value;
|
||||
if ((val == HorizontalBus && p == VerticalBus ) ||
|
||||
(val == VerticalBus && p == HorizontalBus))
|
||||
if ((val == HorizontalBus && p == VerticalBus) || (val == VerticalBus && p == HorizontalBus))
|
||||
field[px][py].value = Blocked;
|
||||
else
|
||||
field[px][py].value = val;
|
||||
@@ -54,14 +52,13 @@ bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
|
||||
st = start;
|
||||
fn = finish;
|
||||
if (dir_ == NoTrace) return true;
|
||||
//qDebug() << "trace" << start << finish;
|
||||
// qDebug() << "trace" << start << finish;
|
||||
short cl = 0;
|
||||
QRect frect(0, 0, wid - 1, hei - 1);
|
||||
QVector<QPoint> cpnts, npnts;
|
||||
fill(st, cl);
|
||||
cpnts.push_back(st);
|
||||
if (field[fn.x()][fn.y()].value == (short)Blocked)
|
||||
return false;
|
||||
if (field[fn.x()][fn.y()].value == (short)Blocked) return false;
|
||||
auto checkAndFill = [this, &npnts, &frect](int x, int y, short acc_dir, short c) {
|
||||
if (!frect.contains(x, y)) return;
|
||||
short p = field[x][y].value;
|
||||
@@ -73,18 +70,16 @@ bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
|
||||
while (cpnts.size() > 0) {
|
||||
npnts.clear();
|
||||
cl++;
|
||||
if (cl >= max_steps)
|
||||
return false;
|
||||
if (cl >= max_steps) return false;
|
||||
for (int i = 0; i < cpnts.size(); ++i) {
|
||||
if (cpnts[i] == fn)
|
||||
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() , cpnts[i].y() - 1, (short)HorizontalBus, cl);
|
||||
checkAndFill(cpnts[i].x() , cpnts[i].y() + 1, (short)HorizontalBus, cl);
|
||||
if (cpnts[i] == fn) 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(), cpnts[i].y() - 1, (short)HorizontalBus, cl);
|
||||
checkAndFill(cpnts[i].x(), cpnts[i].y() + 1, (short)HorizontalBus, cl);
|
||||
}
|
||||
cpnts = npnts;
|
||||
//qDebug() << cl << ": " << cpnts.size();
|
||||
// qDebug() << cl << ": " << cpnts.size();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -99,25 +94,22 @@ void BlockViewWavetrace::gatherPath() {
|
||||
}
|
||||
int pa = -1, ca = -1;
|
||||
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);
|
||||
QPoint cpnt = fn;
|
||||
auto checkAndStep = [this, &cpnt, &first, &frect] (int dir, short c, int & ca_, int pa_)->bool {
|
||||
QPoint cpnt = fn;
|
||||
auto checkAndStep = [this, &cpnt, &first, &frect](int dir, short c, int & ca_, int pa_) -> bool {
|
||||
int cx = cpnt.x() + dps[dir].x();
|
||||
int cy = cpnt.y() + dps[dir].y();
|
||||
if (frect.contains(cx, cy)) {
|
||||
const Cell & cell(field[cx][cy]);
|
||||
if (cell.value == c) {
|
||||
if (cell.direction == HorizontalBus || cell.direction == VerticalBus) {
|
||||
if (dps[dir].x() == 0 && cell.direction == VerticalBus)
|
||||
return false;
|
||||
if (dps[dir].y() == 0 && cell.direction == HorizontalBus)
|
||||
return false;
|
||||
if (dps[dir].x() == 0 && cell.direction == VerticalBus) return false;
|
||||
if (dps[dir].y() == 0 && cell.direction == HorizontalBus) return false;
|
||||
}
|
||||
ca_ = QLineF(QPointF(cx, cy), cpnt).angle();
|
||||
if (ca_ != pa_ && !first)
|
||||
path_.push_front(cpnt);
|
||||
cpnt = QPoint(cx, cy);
|
||||
if (ca_ != pa_ && !first) path_.push_front(cpnt);
|
||||
cpnt = QPoint(cx, cy);
|
||||
first = false;
|
||||
return true;
|
||||
}
|
||||
@@ -132,7 +124,6 @@ void BlockViewWavetrace::gatherPath() {
|
||||
if (checkAndStep(1, cl, ca, pa)) continue;
|
||||
if (checkAndStep(2, cl, ca, pa)) continue;
|
||||
if (checkAndStep(3, cl, ca, pa)) continue;
|
||||
|
||||
}
|
||||
path_.push_front(st);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKVIEWWAVETRACE_H
|
||||
@@ -27,28 +27,37 @@
|
||||
class QAD_BLOCKVIEW_EXPORT BlockViewWavetrace {
|
||||
public:
|
||||
BlockViewWavetrace(int width = 1, int height = 1);
|
||||
|
||||
enum CellState {Empty = -1, Blocked = -2, HorizontalBus = -3, VerticalBus = -4};
|
||||
enum Direction {NoTrace, Horizontal, Vertical};
|
||||
|
||||
int width() const {return wid;}
|
||||
int height() const {return hei;}
|
||||
|
||||
enum CellState {
|
||||
Empty = -1,
|
||||
Blocked = -2,
|
||||
HorizontalBus = -3,
|
||||
VerticalBus = -4
|
||||
};
|
||||
enum Direction {
|
||||
NoTrace,
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
int width() const { return wid; }
|
||||
int height() const { return hei; }
|
||||
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(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(BlockViewWavetrace::CellState val = Empty) {fill((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(int px, int py, BlockViewWavetrace::CellState val = Empty) {fill(px, py, (short)val);}
|
||||
void clear() {fill(-1);}
|
||||
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 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 clear() { fill(-1); }
|
||||
bool trace(const QPoint & start, const QPoint & finish);
|
||||
Direction preferredDirection() const {return dir_;}
|
||||
Direction preferredDirection() const { return dir_; }
|
||||
void setPreferredDirection(Direction dir);
|
||||
void setMaximumSteps(int steps) {max_steps = steps;}
|
||||
int maximumSteps() const {return max_steps;}
|
||||
void setMaximumSteps(int steps) { max_steps = steps; }
|
||||
int maximumSteps() const { return max_steps; }
|
||||
void gatherPath();
|
||||
const QVector<QPoint> & path() const;
|
||||
|
||||
@@ -61,11 +70,10 @@ private:
|
||||
|
||||
int wid, hei, max_steps;
|
||||
Direction dir_;
|
||||
QVector<QVector<Cell> > field;
|
||||
QVector<QVector<Cell>> field;
|
||||
QVector<QPoint> path_;
|
||||
QVector<QPoint> jumps;
|
||||
QPoint dps[4], st, fn;
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKVIEWWAVETRACE_H
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
#include "drawtools.h"
|
||||
#include "ui_drawtools.h"
|
||||
|
||||
#include "alignedtextitem.h"
|
||||
#include <QGraphicsLineItem>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QImageReader>
|
||||
#include <QDialogButtonBox>
|
||||
#include "ui_drawtools.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QGraphicsLineItem>
|
||||
#include <QImageReader>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMouseEvent>
|
||||
|
||||
|
||||
_DTSizeItem::_DTSizeItem(): QGraphicsObject() {
|
||||
cur_item = nullptr;
|
||||
grid = 10.;
|
||||
cur_item = nullptr;
|
||||
grid = 10.;
|
||||
in_process = can_drag = false;
|
||||
setData(bvidItemSelection, true);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
//qDebug() << &(rects[i]);
|
||||
// qDebug() << &(rects[i]);
|
||||
rects[i].setData(bvidItemSelection, true);
|
||||
rects[i].setData(bvidDTHandle, true);
|
||||
rects[i].setFlag(QGraphicsItem::ItemIgnoresTransformations);
|
||||
@@ -32,7 +34,7 @@ _DTSizeItem::_DTSizeItem(): QGraphicsObject() {
|
||||
|
||||
_DTSizeItem::~_DTSizeItem() {
|
||||
assignObject(nullptr);
|
||||
//qDebug() << "!!!";
|
||||
// qDebug() << "!!!";
|
||||
}
|
||||
|
||||
|
||||
@@ -52,15 +54,15 @@ void _DTSizeItem::assignObject(QGraphicsItem * item) {
|
||||
}
|
||||
if (cur_item->scene()) {
|
||||
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);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
if (irect || iell || iline) {
|
||||
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) {
|
||||
rects[i].setParentItem(cur_item);
|
||||
rects[i].installSceneEventFilter(this);
|
||||
@@ -78,26 +80,36 @@ void _DTSizeItem::moveRects() {
|
||||
QRectF rect = itemRect(cur_item);
|
||||
QPointF tl = rect.topLeft(), tr = rect.topRight(), bl = rect.bottomLeft(), br = rect.bottomRight();
|
||||
if (is_line) {
|
||||
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeAllCursor));
|
||||
rects[1].setPos(br); rects[1].setData(2001, int(Qt::SizeAllCursor));
|
||||
rects[0].setPos(tl);
|
||||
rects[0].setData(2001, int(Qt::SizeAllCursor));
|
||||
rects[1].setPos(br);
|
||||
rects[1].setData(2001, int(Qt::SizeAllCursor));
|
||||
} else {
|
||||
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeFDiagCursor));
|
||||
rects[1].setPos((tl + tr) / 2.); rects[1].setData(2001, int(Qt::SizeVerCursor));
|
||||
rects[2].setPos(tr); rects[2].setData(2001, int(Qt::SizeBDiagCursor));
|
||||
rects[3].setPos((tr + br) / 2.); 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));
|
||||
rects[0].setPos(tl);
|
||||
rects[0].setData(2001, int(Qt::SizeFDiagCursor));
|
||||
rects[1].setPos((tl + tr) / 2.);
|
||||
rects[1].setData(2001, int(Qt::SizeVerCursor));
|
||||
rects[2].setPos(tr);
|
||||
rects[2].setData(2001, int(Qt::SizeBDiagCursor));
|
||||
rects[3].setPos((tr + br) / 2.);
|
||||
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() {
|
||||
if (!cur_item) return;
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
if (irect) irect->setRect(nrect);
|
||||
if (iell) iell->setRect(nrect);
|
||||
if (iline) iline->setLine(QLineF(nrect.topLeft(), nrect.bottomRight()));
|
||||
@@ -105,21 +117,27 @@ void _DTSizeItem::applyRect() {
|
||||
|
||||
|
||||
void _DTSizeItem::doubleClick() {
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem*>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem*>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem*>(cur_item);
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
|
||||
if (itext || iatext) {
|
||||
QMetaObject::invokeMethod(this, [this](){textEditRequest();}, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() { textEditRequest(); },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
if (ipixmap) {
|
||||
QMetaObject::invokeMethod(this, [this](){pixmapEditRequest();}, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() { pixmapEditRequest(); },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _DTSizeItem::resizeHandles() {
|
||||
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) {
|
||||
rects[i].setRect(r);
|
||||
}
|
||||
@@ -128,9 +146,9 @@ void _DTSizeItem::resizeHandles() {
|
||||
|
||||
QRectF _DTSizeItem::itemRect(const QGraphicsItem *) const {
|
||||
if (!cur_item) return QRectF();
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
if (irect) return irect->rect();
|
||||
if (iell) return iell->rect();
|
||||
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) {
|
||||
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent * )event;
|
||||
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent *)event;
|
||||
if (watched == cur_item) {
|
||||
if (event->type() == QEvent::Close) {
|
||||
assignObject(nullptr);
|
||||
@@ -166,11 +184,13 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
|
||||
view_ = nullptr;
|
||||
switch (event->type()) {
|
||||
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()));
|
||||
break;
|
||||
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();
|
||||
break;
|
||||
case QEvent::GraphicsSceneMousePress:
|
||||
@@ -181,7 +201,7 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
|
||||
moveRects();
|
||||
}
|
||||
in_process = false;
|
||||
pp = quantize(me->scenePos(), grid);
|
||||
pp = quantize(me->scenePos(), grid);
|
||||
cur_item->setData(2000, itemRect(cur_item));
|
||||
return true;
|
||||
case QEvent::GraphicsSceneMouseMove:
|
||||
@@ -189,7 +209,7 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
|
||||
sp = quantize(me->scenePos(), grid);
|
||||
if (pp != sp && can_drag) {
|
||||
in_process = true;
|
||||
nrect = itemRect(cur_item);
|
||||
nrect = itemRect(cur_item);
|
||||
if (is_line) {
|
||||
if (watched == &(rects[0])) nrect.setTopLeft(rects[0].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:
|
||||
if (in_process) emit sizeChanged();
|
||||
in_process = false;
|
||||
can_drag = false;
|
||||
can_drag = false;
|
||||
return true;
|
||||
default: break;
|
||||
}
|
||||
@@ -221,19 +241,21 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DrawTools::DrawTools(BlockView * parent): QWidget(parent),
|
||||
actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(this) {
|
||||
DrawTools::DrawTools(BlockView * parent)
|
||||
: QWidget(parent)
|
||||
, actions_Z_up(this)
|
||||
, actions_Z_top(this)
|
||||
, actions_Z_down(this)
|
||||
, actions_Z_bottom(this) {
|
||||
widget_props = new QWidget();
|
||||
ui = new Ui::DrawTools();
|
||||
ui = new Ui::DrawTools();
|
||||
ui->setupUi(widget_props);
|
||||
ui->labelPen->setMinimumSize(preferredIconSize(1.5, widget_props));
|
||||
ui->labelPen->setMaximumSize(ui->labelPen->minimumSize());
|
||||
ui->labelBrush->setMinimumSize(ui->labelPen->minimumSize());
|
||||
ui->labelBrush->setMaximumSize(ui->labelBrush->minimumSize());
|
||||
widget_props->setEnabled(false);
|
||||
int fh = qMax<int>(fontHeight(this), 22);
|
||||
int fh = qMax<int>(fontHeight(this), 22);
|
||||
int thick = lineThickness(this);
|
||||
QSize sz(fh * 2.5, fh);
|
||||
ui->comboLineStyle->setIconSize(sz);
|
||||
@@ -251,36 +273,37 @@ actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(
|
||||
#else
|
||||
setAlignCompact(false);
|
||||
#endif
|
||||
menu_hor.addActions(QList<QAction*>() << ui->actionLeft << ui->actionHCenter << ui->actionRight);
|
||||
menu_ver.addActions(QList<QAction*>() << ui->actionTop << ui->actionVCenter << ui->actionBottom);
|
||||
menu_hor.addActions(QList<QAction *>() << ui->actionLeft << ui->actionHCenter << ui->actionRight);
|
||||
menu_ver.addActions(QList<QAction *>() << ui->actionTop << ui->actionVCenter << ui->actionBottom);
|
||||
ui->buttonAlignHor->setMenu(&menu_hor);
|
||||
ui->buttonAlignVer->setMenu(&menu_ver);
|
||||
new_type = -1;
|
||||
new_item = cur_item = nullptr;
|
||||
view_ = nullptr;
|
||||
resize_enabled = true;
|
||||
view_ = nullptr;
|
||||
resize_enabled = true;
|
||||
text_dlg.setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
|
||||
QDialogButtonBox * bbox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||
connect(bbox, SIGNAL(accepted()), &text_dlg, SLOT(accept()));
|
||||
connect(bbox, SIGNAL(rejected()), &text_dlg, SLOT(reject()));
|
||||
text_dlg.layout()->addWidget(&text_edit);
|
||||
text_dlg.layout()->addWidget(bbox);
|
||||
actions_Z_up.setIcon(QIcon(":/icons/z-up.png")); actions_Z_up.setEnabled(false);
|
||||
actions_Z_top.setIcon(QIcon(":/icons/z-top.png")); actions_Z_top.setEnabled(false);
|
||||
actions_Z_down.setIcon(QIcon(":/icons/z-down.png")); actions_Z_down.setEnabled(false);
|
||||
actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png")); 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)
|
||||
actions_Z_up.setIcon(QIcon(":/icons/z-up.png"));
|
||||
actions_Z_up.setEnabled(false);
|
||||
actions_Z_top.setIcon(QIcon(":/icons/z-top.png"));
|
||||
actions_Z_top.setEnabled(false);
|
||||
actions_Z_down.setIcon(QIcon(":/icons/z-down.png"));
|
||||
actions_Z_down.setEnabled(false);
|
||||
actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png"));
|
||||
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);
|
||||
buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR
|
||||
<< ui->buttonAlignCL << ui->buttonAlignCC << ui->buttonAlignCR
|
||||
<< ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR;
|
||||
foreach (QAction * a, actions_add) {
|
||||
buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR << ui->buttonAlignCL << ui->buttonAlignCC
|
||||
<< ui->buttonAlignCR << ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR;
|
||||
foreach(QAction * a, actions_add) {
|
||||
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(ui->buttonImage, SIGNAL(clicked(bool)), this, SLOT(buttonImage_clicked()));
|
||||
@@ -328,8 +351,7 @@ DrawTools::~DrawTools() {
|
||||
|
||||
void DrawTools::retranslate() {
|
||||
QStringList styles;
|
||||
styles << tr("NoPen") << tr("Solid") << tr("Dash")
|
||||
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
|
||||
styles << tr("NoPen") << tr("Solid") << tr("Dash") << tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
|
||||
for (int i = 0; i < styles.size(); i++) {
|
||||
ui->comboLineStyle->setItemText(i, styles[i]);
|
||||
}
|
||||
@@ -380,7 +402,7 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
|
||||
delete new_item;
|
||||
new_item = nullptr;
|
||||
if (!me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
foreach (QAction * a, actions_add) {
|
||||
foreach(QAction * a, actions_add) {
|
||||
a->setChecked(false);
|
||||
}
|
||||
new_type = -1;
|
||||
@@ -388,26 +410,21 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
}
|
||||
new_item = nullptr;
|
||||
pp = sp;
|
||||
pp = sp;
|
||||
switch (new_type) {
|
||||
case 0:
|
||||
new_item = new AlignedTextItem();
|
||||
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setText("Text");
|
||||
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp);
|
||||
break;
|
||||
case 1:
|
||||
new_item = new QGraphicsRectItem();
|
||||
break;
|
||||
case 2:
|
||||
new_item = new QGraphicsEllipseItem();
|
||||
break;
|
||||
case 1: new_item = new QGraphicsRectItem(); break;
|
||||
case 2: new_item = new QGraphicsEllipseItem(); break;
|
||||
case 3:
|
||||
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));
|
||||
break;
|
||||
case 4:
|
||||
new_item = new QGraphicsLineItem(QLineF(sp, sp));
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(
|
||||
sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
|
||||
break;
|
||||
case 4: new_item = new QGraphicsLineItem(QLineF(sp, sp)); break;
|
||||
};
|
||||
if (new_item) {
|
||||
if (new_type == 1 || new_type == 2) {
|
||||
@@ -424,21 +441,14 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
|
||||
if (new_item) {
|
||||
mr = new_item->mapRectFromScene(QRectF(pp, sp).normalized());
|
||||
switch (new_type) {
|
||||
case 0:
|
||||
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp);
|
||||
break;
|
||||
case 1:
|
||||
qgraphicsitem_cast<QGraphicsRectItem *>(new_item)->setRect(mr);
|
||||
break;
|
||||
case 2:
|
||||
qgraphicsitem_cast<QGraphicsEllipseItem *>(new_item)->setRect(mr);
|
||||
break;
|
||||
case 0: qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); break;
|
||||
case 1: qgraphicsitem_cast<QGraphicsRectItem *>(new_item)->setRect(mr); break;
|
||||
case 2: qgraphicsitem_cast<QGraphicsEllipseItem *>(new_item)->setRect(mr); break;
|
||||
case 3:
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
|
||||
break;
|
||||
case 4:
|
||||
qgraphicsitem_cast<QGraphicsLineItem *>(new_item)->setLine(QLineF(pp, sp));
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(
|
||||
sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
|
||||
break;
|
||||
case 4: qgraphicsitem_cast<QGraphicsLineItem *>(new_item)->setLine(QLineF(pp, sp)); break;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
@@ -457,7 +467,7 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
|
||||
}
|
||||
new_item = nullptr;
|
||||
if (!me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
foreach (QAction * a, actions_add) {
|
||||
foreach(QAction * a, actions_add) {
|
||||
a->setChecked(false);
|
||||
}
|
||||
new_type = -1;
|
||||
@@ -497,8 +507,8 @@ QAction * DrawTools::newAction(const QIcon & icon, int type) {
|
||||
|
||||
|
||||
void DrawTools::toggleNewItem(bool on) {
|
||||
QAction * sa = (QAction * )sender();
|
||||
foreach (QAction * a, actions_add) {
|
||||
QAction * sa = (QAction *)sender();
|
||||
foreach(QAction * a, actions_add) {
|
||||
if (a != sa) a->setChecked(false);
|
||||
}
|
||||
if (!on) {
|
||||
@@ -512,12 +522,12 @@ void DrawTools::toggleNewItem(bool on) {
|
||||
|
||||
|
||||
void DrawTools::alignClicked() {
|
||||
QToolButton * sb = (QToolButton * )sender();
|
||||
foreach (QToolButton * b, buttons_align) {
|
||||
QToolButton * sb = (QToolButton *)sender();
|
||||
foreach(QToolButton * b, buttons_align) {
|
||||
if (b != sb) b->setChecked(false);
|
||||
}
|
||||
sb->setChecked(true);
|
||||
align = Qt::Alignment();
|
||||
align = Qt::Alignment();
|
||||
QString als = sb->objectName().right(2).toLower();
|
||||
if (als[0] == 't') align |= Qt::AlignTop;
|
||||
if (als[0] == 'c') align |= Qt::AlignVCenter;
|
||||
@@ -563,7 +573,7 @@ void DrawTools::blockPropSignals(bool block_) {
|
||||
ui->actionHCenter->blockSignals(block_);
|
||||
ui->actionLeft->blockSignals(block_);
|
||||
ui->actionRight->blockSignals(block_);
|
||||
foreach (QToolButton * b, buttons_align) {
|
||||
foreach(QToolButton * b, buttons_align) {
|
||||
b->blockSignals(block_);
|
||||
}
|
||||
}
|
||||
@@ -571,8 +581,12 @@ void DrawTools::blockPropSignals(bool block_) {
|
||||
|
||||
void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
|
||||
blockPropSignals(true);
|
||||
if (vert) foreach (QAction * a, menu_ver.actions()) a->setChecked(false);
|
||||
else foreach (QAction * a, menu_hor.actions()) a->setChecked(false);
|
||||
if (vert)
|
||||
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 |= value;
|
||||
qobject_cast<QAction *>(sender())->setChecked(true);
|
||||
@@ -583,7 +597,9 @@ void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
|
||||
|
||||
void DrawTools::emitZAvailabe(QGraphicsItem * item) {
|
||||
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) {
|
||||
moveZUpAvailable(false);
|
||||
moveZDownAvailable(false);
|
||||
@@ -633,11 +649,11 @@ void DrawTools::selectionChanged() {
|
||||
return;
|
||||
}
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
blockPropSignals(true);
|
||||
if (itext) {
|
||||
ui->stackedProperties->setCurrentIndex(0);
|
||||
@@ -658,20 +674,40 @@ void DrawTools::selectionChanged() {
|
||||
font_dlg.setCurrentFont(iatext->font());
|
||||
font_dlg.blockSignals(false);
|
||||
setToolButtonsEnabled(true, false, false);
|
||||
foreach (QAction * a, menu_hor.actions()) a->setChecked(false);
|
||||
foreach (QAction * a, menu_ver.actions()) a->setChecked(false);
|
||||
foreach(QAction * a, menu_hor.actions())
|
||||
a->setChecked(false);
|
||||
foreach(QAction * a, menu_ver.actions())
|
||||
a->setChecked(false);
|
||||
align = iatext->alignment();
|
||||
QString als;
|
||||
if (align.testFlag(Qt::AlignTop)) {als += "T"; ui->actionTop->setChecked(true);}
|
||||
if (align.testFlag(Qt::AlignVCenter)) {als += "C"; 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) {
|
||||
if (align.testFlag(Qt::AlignTop)) {
|
||||
als += "T";
|
||||
ui->actionTop->setChecked(true);
|
||||
}
|
||||
if (align.testFlag(Qt::AlignVCenter)) {
|
||||
als += "C";
|
||||
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);
|
||||
}
|
||||
foreach (QToolButton * b, buttons_align) {
|
||||
foreach(QToolButton * b, buttons_align) {
|
||||
if (b->objectName().endsWith(als)) {
|
||||
b->setChecked(true);
|
||||
break;
|
||||
@@ -724,7 +760,7 @@ void DrawTools::selectionChanged() {
|
||||
|
||||
void DrawTools::sizeChanged() {
|
||||
blockPropSignals(true);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
if (irect || iell) {
|
||||
if (irect) {
|
||||
@@ -744,17 +780,17 @@ void DrawTools::sizeChanged() {
|
||||
void DrawTools::propertyChanged() {
|
||||
if (!cur_item) return;
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem *>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
if (itext) {
|
||||
QRectF obr = itext->boundingRect();
|
||||
itext->setFont(font_dlg.currentFont());
|
||||
itext->setText(ui->comboText->currentText());
|
||||
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->setBrush(ui->colorButtonPen->color());
|
||||
} else if (iatext) {
|
||||
@@ -764,8 +800,8 @@ void DrawTools::propertyChanged() {
|
||||
iatext->setAlignment(align);
|
||||
} else if (ipixmap) {
|
||||
QTransform t = ipixmap->transform();
|
||||
double det = sqrt(t.determinant());
|
||||
QSizeF os = ipixmap->boundingRect().size() * det;
|
||||
double det = sqrt(t.determinant());
|
||||
QSizeF os = ipixmap->boundingRect().size() * det;
|
||||
if (det != 0.) t.scale(1. / det, 1. / det);
|
||||
det = ui->spinScale->value();
|
||||
t.scale(det, det);
|
||||
@@ -797,9 +833,9 @@ void DrawTools::propertyChanged() {
|
||||
|
||||
void DrawTools::comboLineStyleChanged() {
|
||||
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);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem *>(cur_item);
|
||||
if (irect || iell) {
|
||||
QAbstractGraphicsShapeItem * ishape = nullptr;
|
||||
if (irect) ishape = irect;
|
||||
@@ -824,7 +860,7 @@ void DrawTools::buttonImage_clicked() {
|
||||
if (!pi) return;
|
||||
QList<QByteArray> sif(QImageReader::supportedImageFormats());
|
||||
QString f;
|
||||
foreach (const QByteArray & i, sif) {
|
||||
foreach(const QByteArray & i, sif) {
|
||||
if (!f.isEmpty()) f += " ";
|
||||
f += "*.";
|
||||
f += i;
|
||||
@@ -833,11 +869,11 @@ void DrawTools::buttonImage_clicked() {
|
||||
if (ret.isEmpty()) return;
|
||||
QImage im(ret);
|
||||
if (im.isNull()) return;
|
||||
prev_dir = ret;
|
||||
prev_dir = ret;
|
||||
QRectF obr = pi->boundingRect();
|
||||
pi->setPixmap(QPixmap::fromImage(im));
|
||||
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()));
|
||||
changeFinished();
|
||||
}
|
||||
@@ -851,7 +887,7 @@ void DrawTools::buttonImagePaste_clicked() {
|
||||
QRectF obr = pi->boundingRect();
|
||||
pi->setPixmap(pm);
|
||||
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()));
|
||||
changeFinished();
|
||||
}
|
||||
@@ -860,7 +896,7 @@ void DrawTools::buttonImagePaste_clicked() {
|
||||
void DrawTools::buttonFont_clicked() {
|
||||
if (!cur_item) return;
|
||||
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;
|
||||
QFont font_prev;
|
||||
if (ti) font_prev = ti->font();
|
||||
@@ -892,28 +928,32 @@ void DrawTools::actionZ_triggered() {
|
||||
if (!cur_item) return;
|
||||
if (cur_item->data(bvidType).toInt() == bvitDecor) {
|
||||
BlockView * view = nullptr;
|
||||
if (cur_item->scene()) if (!cur_item->scene()->views().isEmpty()) {
|
||||
view = qobject_cast<BlockView *>(cur_item->scene()->views()[0]);
|
||||
}
|
||||
if (cur_item->scene())
|
||||
if (!cur_item->scene()->views().isEmpty()) {
|
||||
view = qobject_cast<BlockView *>(cur_item->scene()->views()[0]);
|
||||
}
|
||||
if (!view) return;
|
||||
QGraphicsScene * scene = view->scene();
|
||||
QGraphicsScene * scene = view->scene();
|
||||
QList<QGraphicsItem *> dl = view->decors();
|
||||
scene->blockSignals(true);
|
||||
foreach (QGraphicsItem * d, dl) scene->removeItem(d);
|
||||
foreach(QGraphicsItem * d, dl)
|
||||
scene->removeItem(d);
|
||||
int ind = dl.indexOf(cur_item);
|
||||
dl.removeAt(ind);
|
||||
if (sender() == &actions_Z_up) dl.insert(ind + 1, 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_bottom) dl.prepend(cur_item);
|
||||
foreach (QGraphicsItem * d, dl) scene->addItem(d);
|
||||
foreach(QGraphicsItem * d, dl)
|
||||
scene->addItem(d);
|
||||
scene->blockSignals(false);
|
||||
}
|
||||
if (cur_item->data(bvidBlockDecor).toBool()) {
|
||||
BlockItem * bi = qgraphicsitem_cast<BlockItem *>(cur_item->parentItem());
|
||||
if (!bi) return;
|
||||
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);
|
||||
dl.removeAt(ind);
|
||||
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_bottom) dl.prepend(cur_item);
|
||||
bi->decors_ = dl;
|
||||
foreach (QGraphicsItem * d, dl) d->setParentItem(bi);
|
||||
foreach(QGraphicsItem * d, dl)
|
||||
d->setParentItem(bi);
|
||||
}
|
||||
size_item.assignObject(cur_item);
|
||||
emitZAvailabe(cur_item);
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DRAWTOOLS_H
|
||||
#define DRAWTOOLS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
#include <QFontDialog>
|
||||
#include <QToolButton>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QMenu>
|
||||
#include "blockview.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QFontDialog>
|
||||
#include <QMenu>
|
||||
#include <QObject>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QToolButton>
|
||||
|
||||
|
||||
class QComboBox;
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject
|
||||
{
|
||||
class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
_DTSizeItem();
|
||||
~_DTSizeItem();
|
||||
|
||||
|
||||
void assignObject(QGraphicsItem * item);
|
||||
|
||||
|
||||
protected:
|
||||
void moveRects();
|
||||
void applyRect();
|
||||
@@ -51,7 +52,7 @@ protected:
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {}
|
||||
bool sceneEventFilter(QGraphicsItem * watched, QEvent * event);
|
||||
|
||||
|
||||
QGraphicsItem * cur_item;
|
||||
QGraphicsView * view_;
|
||||
QGraphicsRectItem rects[8];
|
||||
@@ -59,55 +60,56 @@ protected:
|
||||
QRectF nrect;
|
||||
qreal grid;
|
||||
bool in_process, can_drag, is_line;
|
||||
|
||||
|
||||
signals:
|
||||
void sizeChanged();
|
||||
void textEditRequest();
|
||||
void pixmapEditRequest();
|
||||
|
||||
};
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DrawTools;
|
||||
class DrawTools;
|
||||
}
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget
|
||||
{
|
||||
class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool resizeHandlesEnabled READ isResizeHandlesEnabled WRITE setResizeHandlesEnabled)
|
||||
|
||||
public:
|
||||
explicit DrawTools(BlockView * parent = 0);
|
||||
~DrawTools();
|
||||
|
||||
|
||||
void setBlockView(BlockView * v);
|
||||
void resetSizeTool() {size_item.assignObject(0);}
|
||||
bool isResizeHandlesEnabled() const {return resize_enabled;}
|
||||
void resetSizeTool() { size_item.assignObject(0); }
|
||||
bool isResizeHandlesEnabled() const { return resize_enabled; }
|
||||
void setAlignCompact(bool yes);
|
||||
|
||||
|
||||
QComboBox * textEditCombo() const;
|
||||
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;}
|
||||
QWidget * propertyWidget() const {return widget_props;}
|
||||
|
||||
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;
|
||||
}
|
||||
QWidget * propertyWidget() const { return widget_props; }
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
|
||||
QAction * newAction(const QIcon & icon, int type);
|
||||
void setToolButtonsEnabled(bool pen, bool brush, bool wid_hei);
|
||||
void blockPropSignals(bool block_);
|
||||
void actionAlignTrigger(bool vert, Qt::AlignmentFlag value);
|
||||
void emitZAvailabe(QGraphicsItem * item = 0);
|
||||
|
||||
|
||||
QWidget * widget_props;
|
||||
Ui::DrawTools * ui;
|
||||
BlockView * view_;
|
||||
QList<QAction * > actions_add;
|
||||
QList<QAction *> actions_add;
|
||||
mutable QAction actions_Z_up, actions_Z_top, actions_Z_down, actions_Z_bottom;
|
||||
QList<QToolButton * > buttons_align;
|
||||
QGraphicsItem * new_item, * cur_item;
|
||||
QList<QToolButton *> buttons_align;
|
||||
QGraphicsItem *new_item, *cur_item;
|
||||
QFontDialog font_dlg;
|
||||
QPointF pp;
|
||||
QDialog text_dlg;
|
||||
@@ -118,7 +120,7 @@ protected:
|
||||
int new_type;
|
||||
bool resize_enabled;
|
||||
QString prev_dir;
|
||||
|
||||
|
||||
private slots:
|
||||
void toggleNewItem(bool on);
|
||||
void alignClicked();
|
||||
@@ -126,32 +128,40 @@ private slots:
|
||||
void sizeChanged();
|
||||
void propertyChanged();
|
||||
void comboLineStyleChanged();
|
||||
void changeFinished() {if (cur_item) emit itemEdited(cur_item);}
|
||||
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 changeFinished() {
|
||||
if (cur_item) emit itemEdited(cur_item);
|
||||
}
|
||||
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 buttonImagePaste_clicked();
|
||||
void buttonFont_clicked();
|
||||
void buttonTextEdit_clicked();
|
||||
|
||||
void actionTop_triggered(bool on) {actionAlignTrigger(true, Qt::AlignTop);}
|
||||
void actionVCenter_triggered(bool on) {actionAlignTrigger(true, Qt::AlignVCenter);}
|
||||
void actionBottom_triggered(bool on) {actionAlignTrigger(true, Qt::AlignBottom);}
|
||||
void actionLeft_triggered(bool on) {actionAlignTrigger(false, Qt::AlignLeft);}
|
||||
void actionHCenter_triggered(bool on) {actionAlignTrigger(false, Qt::AlignHCenter);}
|
||||
void actionRight_triggered(bool on) {actionAlignTrigger(false, Qt::AlignRight);}
|
||||
|
||||
void actionTop_triggered(bool on) { actionAlignTrigger(true, Qt::AlignTop); }
|
||||
void actionVCenter_triggered(bool on) { actionAlignTrigger(true, Qt::AlignVCenter); }
|
||||
void actionBottom_triggered(bool on) { actionAlignTrigger(true, Qt::AlignBottom); }
|
||||
void actionLeft_triggered(bool on) { actionAlignTrigger(false, Qt::AlignLeft); }
|
||||
void actionHCenter_triggered(bool on) { actionAlignTrigger(false, Qt::AlignHCenter); }
|
||||
void actionRight_triggered(bool on) { actionAlignTrigger(false, Qt::AlignRight); }
|
||||
void actionZ_triggered();
|
||||
|
||||
|
||||
public slots:
|
||||
void setResizeHandlesEnabled(bool on);
|
||||
|
||||
|
||||
signals:
|
||||
void itemCreated(QGraphicsItem * item);
|
||||
void itemAddConfirm(QGraphicsItem * item);
|
||||
void itemEdited(QGraphicsItem * item);
|
||||
void itemZChanged(QGraphicsItem * item);
|
||||
|
||||
|
||||
private:
|
||||
void retranslate();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "blockview.h"
|
||||
#include "blockviewplugin.h"
|
||||
|
||||
#include "blockview.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
@@ -9,8 +11,7 @@ BlockViewPlugin::BlockViewPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
|
||||
void BlockViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -66,4 +67,3 @@ QString BlockViewPlugin::domXml() const {
|
||||
QString BlockViewPlugin::includeFile() const {
|
||||
return QLatin1String("blockview.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class BlockViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class BlockViewPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKVIEWPLUGIN_H
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "qad_blockview.h"
|
||||
|
||||
#include "blockviewplugin.h"
|
||||
|
||||
QADBlockView::QADBlockView(QObject * parent): QObject(parent)
|
||||
{
|
||||
QADBlockView::QADBlockView(QObject * parent): QObject(parent) {
|
||||
m_widgets.append(new BlockViewPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QADBlockView::customWidgets() const {
|
||||
QList<QDesignerCustomWidgetInterface *> QADBlockView::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
#ifndef QAD_BLOCKVIEW_H
|
||||
#define QAD_BLOCKVIEW_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
#include <QtDesigner/QtDesigner>
|
||||
|
||||
class QADBlockView: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
class QADBlockView
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetCollectionInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "qad.blockview")
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit QADBlockView(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
QList<QDesignerCustomWidgetInterface *> m_widgets;
|
||||
};
|
||||
|
||||
#endif // QAD_BLOCKVIEW_H
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
#include "markdown.h"
|
||||
#include <QIODevice>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QIODevice>
|
||||
#ifndef NO_MARKDOWN
|
||||
extern "C" {
|
||||
#include MARKDOWN_HEADER
|
||||
# include MARKDOWN_HEADER
|
||||
}
|
||||
#ifndef mkd_flags_are
|
||||
# ifndef MKD_DLEXTRA
|
||||
# define MKD_DLEXTRA 0x01000000
|
||||
# ifndef mkd_flags_are
|
||||
# ifndef MKD_DLEXTRA
|
||||
# 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
|
||||
# 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; }"
|
||||
"table tr { background-color: white; }"
|
||||
"table td { vertical-align: middle; padding: 5px;}"
|
||||
"table th { padding: 5px; };"
|
||||
;
|
||||
static QString markdown_css = "table { margin: 5px; background-color: #cccccc; }"
|
||||
"table tr { background-color: white; }"
|
||||
"table td { vertical-align: middle; padding: 5px;}"
|
||||
"table th { padding: 5px; };";
|
||||
|
||||
QString md2html(const QByteArray & src) {
|
||||
static bool _is_mkd_init = false;
|
||||
@@ -39,34 +39,34 @@ QString md2html(const QByteArray & src) {
|
||||
_is_mkd_init = true;
|
||||
mkd_initialize();
|
||||
}
|
||||
#ifdef _MARKDOWN_D
|
||||
# ifdef _MARKDOWN_D
|
||||
DWORD flagm = (MKD_DLEXTRA | MKD_FENCEDCODE);
|
||||
Document
|
||||
#endif
|
||||
#ifdef _MKDIO_D
|
||||
#ifdef mkd_flags_are
|
||||
mkd_flag_t * flagm = mkd_flags();
|
||||
mkd_set_flag_num(flagm, MKD_DLEXTRA);
|
||||
mkd_set_flag_num(flagm, MKD_FENCEDCODE);
|
||||
#else
|
||||
mkd_flag_t flagm = (MKD_DLEXTRA | MKD_FENCEDCODE | MKD_GITHUBTAGS | MKD_AUTOLINK);
|
||||
#endif
|
||||
# endif
|
||||
# ifdef _MKDIO_D
|
||||
# ifdef mkd_flags_are
|
||||
mkd_flag_t * flagm = mkd_flags();
|
||||
mkd_set_flag_num(flagm, MKD_DLEXTRA);
|
||||
mkd_set_flag_num(flagm, MKD_FENCEDCODE);
|
||||
# else
|
||||
mkd_flag_t flagm = (MKD_DLEXTRA | MKD_FENCEDCODE | MKD_GITHUBTAGS | MKD_AUTOLINK);
|
||||
# endif
|
||||
MMIOT
|
||||
#endif
|
||||
* doc = mkd_string(src.constData(), src.size(), 0);
|
||||
# endif
|
||||
*doc = mkd_string(src.constData(), src.size(), 0);
|
||||
if (!doc) return QString();
|
||||
mkd_compile(doc, flagm);
|
||||
char * html = 0;
|
||||
int len = mkd_document(doc, &html);
|
||||
int len = mkd_document(doc, &html);
|
||||
if (!html) {
|
||||
mkd_cleanup(doc);
|
||||
return QString();
|
||||
}
|
||||
QString ret = QString::fromUtf8(html, len);
|
||||
mkd_cleanup(doc);
|
||||
QString title = QTextStream(&ret, QIODevice::ReadOnly).readLine();
|
||||
title = title.mid(title.indexOf(">")+1);
|
||||
title = title.left(title.indexOf("<"));
|
||||
QString title = QTextStream(&ret, QIODevice::ReadOnly).readLine();
|
||||
title = title.mid(title.indexOf(">") + 1);
|
||||
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"
|
||||
"<html>\n<head>\n"
|
||||
"<meta name=\"qrichtext\" content=\"1\" />\n"
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QAD_MARKDOWN_H
|
||||
#define QAD_MARKDOWN_H
|
||||
|
||||
#include <QString>
|
||||
#include "qad_doc_export.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
QAD_DOC_EXPORT QString md2html(const QByteArray & src);
|
||||
|
||||
|
||||
1165
libs/graphic/gif.h
1165
libs/graphic/gif.h
@@ -29,10 +29,10 @@
|
||||
#ifndef gif_h
|
||||
#define gif_h
|
||||
|
||||
#include <stdbool.h> // for bool macros
|
||||
#include <stdint.h> // for integer typedefs
|
||||
#include <stdio.h> // for FILE*
|
||||
#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.
|
||||
// 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.)
|
||||
|
||||
#ifndef GIF_TEMP_MALLOC
|
||||
#include <stdlib.h>
|
||||
#define GIF_TEMP_MALLOC malloc
|
||||
# include <stdlib.h>
|
||||
# define GIF_TEMP_MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef GIF_TEMP_FREE
|
||||
#include <stdlib.h>
|
||||
#define GIF_TEMP_FREE free
|
||||
# include <stdlib.h>
|
||||
# define GIF_TEMP_FREE free
|
||||
#endif
|
||||
|
||||
#ifndef GIF_MALLOC
|
||||
#include <stdlib.h>
|
||||
#define GIF_MALLOC malloc
|
||||
# include <stdlib.h>
|
||||
# define GIF_MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef GIF_FREE
|
||||
#include <stdlib.h>
|
||||
#define GIF_FREE free
|
||||
# include <stdlib.h>
|
||||
# define GIF_FREE free
|
||||
#endif
|
||||
|
||||
const int kGifTransIndex = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int bitDepth;
|
||||
typedef struct {
|
||||
int bitDepth;
|
||||
|
||||
uint8_t r[256];
|
||||
uint8_t g[256];
|
||||
uint8_t b[256];
|
||||
uint8_t r[256];
|
||||
uint8_t g[256];
|
||||
uint8_t b[256];
|
||||
|
||||
// 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
|
||||
// nodes 256-511 are implicitly the leaves, containing a color
|
||||
uint8_t treeSplitElt[256];
|
||||
uint8_t treeSplit[256];
|
||||
// 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
|
||||
// nodes 256-511 are implicitly the leaves, containing a color
|
||||
uint8_t treeSplitElt[256];
|
||||
uint8_t treeSplit[256];
|
||||
} GifPalette;
|
||||
|
||||
// max, min, and abs functions
|
||||
int GifIMax(int l, int r) { return l>r?l:r; }
|
||||
int GifIMin(int l, int r) { return l<r?l:r; }
|
||||
int GifIAbs(int i) { return i<0?-i:i; }
|
||||
int GifIMax(int l, int r) {
|
||||
return l > r ? l : r;
|
||||
}
|
||||
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.
|
||||
// Takes as in/out parameters the current best color and its error -
|
||||
// only changes them if it finds a better color in its subtree.
|
||||
// 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 )
|
||||
{
|
||||
// base case, reached the bottom of the tree
|
||||
if(treeRoot > (1<<pPal->bitDepth)-1)
|
||||
{
|
||||
int ind = treeRoot-(1<<pPal->bitDepth);
|
||||
if(ind == kGifTransIndex) return;
|
||||
void GifGetClosestPaletteColor(GifPalette * pPal, int r, int g, int b, int * bestInd, int * bestDiff, int treeRoot) {
|
||||
// base case, reached the bottom of the tree
|
||||
if (treeRoot > (1 << pPal->bitDepth) - 1) {
|
||||
int ind = treeRoot - (1 << pPal->bitDepth);
|
||||
if (ind == kGifTransIndex) return;
|
||||
|
||||
// check whether this color is better than the current winner
|
||||
int r_err = r - ((int32_t)pPal->r[ind]);
|
||||
int g_err = g - ((int32_t)pPal->g[ind]);
|
||||
int b_err = b - ((int32_t)pPal->b[ind]);
|
||||
int diff = GifIAbs(r_err)+GifIAbs(g_err)+GifIAbs(b_err);
|
||||
// check whether this color is better than the current winner
|
||||
int r_err = r - ((int32_t)pPal->r[ind]);
|
||||
int g_err = g - ((int32_t)pPal->g[ind]);
|
||||
int b_err = b - ((int32_t)pPal->b[ind]);
|
||||
int diff = GifIAbs(r_err) + GifIAbs(g_err) + GifIAbs(b_err);
|
||||
|
||||
if(diff < *bestDiff)
|
||||
{
|
||||
*bestInd = ind;
|
||||
*bestDiff = diff;
|
||||
}
|
||||
if (diff < *bestDiff) {
|
||||
*bestInd = ind;
|
||||
*bestDiff = diff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 splitComp = comps[pPal->treeSplitElt[treeRoot]];
|
||||
// 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 splitComp = comps[pPal->treeSplitElt[treeRoot]];
|
||||
|
||||
int splitPos = pPal->treeSplit[treeRoot];
|
||||
if(splitPos > splitComp)
|
||||
{
|
||||
// check the left subtree
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2+1);
|
||||
if( *bestDiff > splitComp - splitPos )
|
||||
{
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2);
|
||||
}
|
||||
}
|
||||
int splitPos = pPal->treeSplit[treeRoot];
|
||||
if (splitPos > splitComp) {
|
||||
// check the left subtree
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
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)
|
||||
{
|
||||
uint8_t rA = image[pixA*4];
|
||||
uint8_t gA = image[pixA*4+1];
|
||||
uint8_t bA = image[pixA*4+2];
|
||||
uint8_t aA = image[pixA*4+3];
|
||||
void GifSwapPixels(uint8_t * image, int pixA, int pixB) {
|
||||
uint8_t rA = image[pixA * 4];
|
||||
uint8_t gA = image[pixA * 4 + 1];
|
||||
uint8_t bA = image[pixA * 4 + 2];
|
||||
uint8_t aA = image[pixA * 4 + 3];
|
||||
|
||||
uint8_t rB = image[pixB*4];
|
||||
uint8_t gB = image[pixB*4+1];
|
||||
uint8_t bB = image[pixB*4+2];
|
||||
uint8_t aB = image[pixA*4+3];
|
||||
uint8_t rB = image[pixB * 4];
|
||||
uint8_t gB = image[pixB * 4 + 1];
|
||||
uint8_t bB = image[pixB * 4 + 2];
|
||||
uint8_t aB = image[pixA * 4 + 3];
|
||||
|
||||
image[pixA*4] = rB;
|
||||
image[pixA*4+1] = gB;
|
||||
image[pixA*4+2] = bB;
|
||||
image[pixA*4+3] = aB;
|
||||
image[pixA * 4] = rB;
|
||||
image[pixA * 4 + 1] = gB;
|
||||
image[pixA * 4 + 2] = bB;
|
||||
image[pixA * 4 + 3] = aB;
|
||||
|
||||
image[pixB*4] = rA;
|
||||
image[pixB*4+1] = gA;
|
||||
image[pixB*4+2] = bA;
|
||||
image[pixB*4+3] = aA;
|
||||
image[pixB * 4] = rA;
|
||||
image[pixB * 4 + 1] = gA;
|
||||
image[pixB * 4 + 2] = bA;
|
||||
image[pixB * 4 + 3] = aA;
|
||||
}
|
||||
|
||||
// just the partition operation from quicksort
|
||||
int GifPartition(uint8_t* image, const int left, const int right, const int elt, int pivotIndex)
|
||||
{
|
||||
const int pivotValue = image[(pivotIndex)*4+elt];
|
||||
GifSwapPixels(image, pivotIndex, right-1);
|
||||
int storeIndex = left;
|
||||
bool split = 0;
|
||||
for(int ii=left; ii<right-1; ++ii)
|
||||
{
|
||||
int arrayVal = image[ii*4+elt];
|
||||
if( arrayVal < pivotValue )
|
||||
{
|
||||
GifSwapPixels(image, ii, storeIndex);
|
||||
++storeIndex;
|
||||
}
|
||||
else if( arrayVal == pivotValue )
|
||||
{
|
||||
if(split)
|
||||
{
|
||||
GifSwapPixels(image, ii, storeIndex);
|
||||
++storeIndex;
|
||||
}
|
||||
split = !split;
|
||||
}
|
||||
}
|
||||
GifSwapPixels(image, storeIndex, right-1);
|
||||
return storeIndex;
|
||||
int GifPartition(uint8_t * image, const int left, const int right, const int elt, int pivotIndex) {
|
||||
const int pivotValue = image[(pivotIndex)*4 + elt];
|
||||
GifSwapPixels(image, pivotIndex, right - 1);
|
||||
int storeIndex = left;
|
||||
bool split = 0;
|
||||
for (int ii = left; ii < right - 1; ++ii) {
|
||||
int arrayVal = image[ii * 4 + elt];
|
||||
if (arrayVal < pivotValue) {
|
||||
GifSwapPixels(image, ii, storeIndex);
|
||||
++storeIndex;
|
||||
} else if (arrayVal == pivotValue) {
|
||||
if (split) {
|
||||
GifSwapPixels(image, ii, storeIndex);
|
||||
++storeIndex;
|
||||
}
|
||||
split = !split;
|
||||
}
|
||||
}
|
||||
GifSwapPixels(image, storeIndex, right - 1);
|
||||
return storeIndex;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
if(left < right-1)
|
||||
{
|
||||
int pivotIndex = left + (right-left)/2;
|
||||
void GifPartitionByMedian(uint8_t * image, int left, int right, int com, int neededCenter) {
|
||||
if (left < right - 1) {
|
||||
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
|
||||
if(pivotIndex > neededCenter)
|
||||
GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
|
||||
// Only "sort" the section of the array that contains the median
|
||||
if (pivotIndex > neededCenter) GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
|
||||
|
||||
if(pivotIndex < neededCenter)
|
||||
GifPartitionByMedian(image, pivotIndex+1, right, com, neededCenter);
|
||||
}
|
||||
if (pivotIndex < neededCenter) GifPartitionByMedian(image, pivotIndex + 1, right, com, neededCenter);
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
if(lastElt <= firstElt || numPixels == 0)
|
||||
return;
|
||||
void GifSplitPalette(uint8_t * image,
|
||||
int numPixels,
|
||||
int firstElt,
|
||||
int lastElt,
|
||||
int splitElt,
|
||||
int splitDist,
|
||||
int treeNode,
|
||||
bool buildForDither,
|
||||
GifPalette * pal) {
|
||||
if (lastElt <= firstElt || numPixels == 0) return;
|
||||
|
||||
// base case, bottom of the tree
|
||||
if(lastElt == firstElt+1)
|
||||
{
|
||||
if(buildForDither)
|
||||
{
|
||||
// Dithering needs at least one color as dark as anything
|
||||
// in the image and at least one brightest color -
|
||||
// otherwise it builds up error and produces strange artifacts
|
||||
if( firstElt == 1 )
|
||||
{
|
||||
// special case: the darkest color in the image
|
||||
uint32_t r=255, g=255, b=255;
|
||||
for(int ii=0; ii<numPixels; ++ii)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
// base case, bottom of the tree
|
||||
if (lastElt == firstElt + 1) {
|
||||
if (buildForDither) {
|
||||
// Dithering needs at least one color as dark as anything
|
||||
// in the image and at least one brightest color -
|
||||
// otherwise it builds up error and produces strange artifacts
|
||||
if (firstElt == 1) {
|
||||
// special case: the darkest color in the image
|
||||
uint32_t r = 255, g = 255, b = 255;
|
||||
for (int ii = 0; ii < numPixels; ++ii) {
|
||||
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->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( firstElt == (1 << pal->bitDepth)-1 )
|
||||
{
|
||||
// special case: the lightest color in the image
|
||||
uint32_t r=0, g=0, b=0;
|
||||
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]);
|
||||
b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]);
|
||||
}
|
||||
if (firstElt == (1 << pal->bitDepth) - 1) {
|
||||
// special case: the lightest color in the image
|
||||
uint32_t r = 0, g = 0, b = 0;
|
||||
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]);
|
||||
b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]);
|
||||
}
|
||||
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, take the average of all colors in this subcube
|
||||
uint64_t r=0, g=0, b=0;
|
||||
for(int ii=0; ii<numPixels; ++ii)
|
||||
{
|
||||
r += image[ii*4+0];
|
||||
g += image[ii*4+1];
|
||||
b += image[ii*4+2];
|
||||
}
|
||||
// otherwise, take the average of all colors in this subcube
|
||||
uint64_t r = 0, g = 0, b = 0;
|
||||
for (int ii = 0; ii < numPixels; ++ii) {
|
||||
r += image[ii * 4 + 0];
|
||||
g += image[ii * 4 + 1];
|
||||
b += image[ii * 4 + 2];
|
||||
}
|
||||
|
||||
r += (uint64_t)numPixels / 2; // round to nearest
|
||||
g += (uint64_t)numPixels / 2;
|
||||
b += (uint64_t)numPixels / 2;
|
||||
r += (uint64_t)numPixels / 2; // round to nearest
|
||||
g += (uint64_t)numPixels / 2;
|
||||
b += (uint64_t)numPixels / 2;
|
||||
|
||||
r /= (uint64_t)numPixels;
|
||||
g /= (uint64_t)numPixels;
|
||||
b /= (uint64_t)numPixels;
|
||||
r /= (uint64_t)numPixels;
|
||||
g /= (uint64_t)numPixels;
|
||||
b /= (uint64_t)numPixels;
|
||||
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the axis with the largest range
|
||||
int minR = 255, maxR = 0;
|
||||
int minG = 255, maxG = 0;
|
||||
int minB = 255, maxB = 0;
|
||||
for(int ii=0; ii<numPixels; ++ii)
|
||||
{
|
||||
int r = image[ii*4+0];
|
||||
int g = image[ii*4+1];
|
||||
int b = image[ii*4+2];
|
||||
// Find the axis with the largest range
|
||||
int minR = 255, maxR = 0;
|
||||
int minG = 255, maxG = 0;
|
||||
int minB = 255, maxB = 0;
|
||||
for (int ii = 0; ii < numPixels; ++ii) {
|
||||
int r = image[ii * 4 + 0];
|
||||
int g = image[ii * 4 + 1];
|
||||
int b = image[ii * 4 + 2];
|
||||
|
||||
if(r > maxR) maxR = r;
|
||||
if(r < minR) minR = r;
|
||||
if (r > maxR) maxR = r;
|
||||
if (r < minR) minR = r;
|
||||
|
||||
if(g > maxG) maxG = g;
|
||||
if(g < minG) minG = g;
|
||||
if (g > maxG) maxG = g;
|
||||
if (g < minG) minG = g;
|
||||
|
||||
if(b > maxB) maxB = b;
|
||||
if(b < minB) minB = b;
|
||||
}
|
||||
if (b > maxB) maxB = b;
|
||||
if (b < minB) minB = b;
|
||||
}
|
||||
|
||||
int rRange = maxR - minR;
|
||||
int gRange = maxG - minG;
|
||||
int bRange = maxB - minB;
|
||||
int rRange = maxR - minR;
|
||||
int gRange = maxG - minG;
|
||||
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)
|
||||
int splitCom = 1;
|
||||
if(bRange > gRange) splitCom = 2;
|
||||
if(rRange > bRange && rRange > gRange) splitCom = 0;
|
||||
// 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;
|
||||
if (bRange > gRange) splitCom = 2;
|
||||
if (rRange > bRange && rRange > gRange) splitCom = 0;
|
||||
|
||||
int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt);
|
||||
int subPixelsB = numPixels-subPixelsA;
|
||||
int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt);
|
||||
int subPixelsB = numPixels - subPixelsA;
|
||||
|
||||
GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA);
|
||||
GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA);
|
||||
|
||||
pal->treeSplitElt[treeNode] = (uint8_t)splitCom;
|
||||
pal->treeSplit[treeNode] = image[subPixelsA*4+splitCom];
|
||||
pal->treeSplitElt[treeNode] = (uint8_t)splitCom;
|
||||
pal->treeSplit[treeNode] = image[subPixelsA * 4 + splitCom];
|
||||
|
||||
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, 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);
|
||||
}
|
||||
|
||||
// Finds all pixels that have changed from the previous image and
|
||||
// moves them to the fromt of th buffer.
|
||||
// This allows us to build a palette optimized for the colors of the
|
||||
// changed pixels only.
|
||||
int GifPickChangedPixels( const uint8_t* lastFrame, uint8_t* frame, int numPixels )
|
||||
{
|
||||
int numChanged = 0;
|
||||
uint8_t* writeIter = frame;
|
||||
int GifPickChangedPixels(const uint8_t * lastFrame, uint8_t * frame, int numPixels) {
|
||||
int numChanged = 0;
|
||||
uint8_t * writeIter = frame;
|
||||
|
||||
for (int ii=0; ii<numPixels; ++ii)
|
||||
{
|
||||
if(lastFrame[0] != frame[0] ||
|
||||
lastFrame[1] != frame[1] ||
|
||||
lastFrame[2] != frame[2])
|
||||
{
|
||||
writeIter[0] = frame[0];
|
||||
writeIter[1] = frame[1];
|
||||
writeIter[2] = frame[2];
|
||||
++numChanged;
|
||||
writeIter += 4;
|
||||
}
|
||||
lastFrame += 4;
|
||||
frame += 4;
|
||||
}
|
||||
for (int ii = 0; ii < numPixels; ++ii) {
|
||||
if (lastFrame[0] != frame[0] || lastFrame[1] != frame[1] || lastFrame[2] != frame[2]) {
|
||||
writeIter[0] = frame[0];
|
||||
writeIter[1] = frame[1];
|
||||
writeIter[2] = frame[2];
|
||||
++numChanged;
|
||||
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.
|
||||
// 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 )
|
||||
{
|
||||
pPal->bitDepth = bitDepth;
|
||||
void GifMakePalette(const uint8_t * lastFrame,
|
||||
const uint8_t * nextFrame,
|
||||
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
|
||||
// we must create a copy of the image for it to destroy
|
||||
size_t imageSize = (size_t)(width * height * 4 * sizeof(uint8_t));
|
||||
uint8_t* destroyableImage = (uint8_t*)GIF_TEMP_MALLOC(imageSize);
|
||||
memcpy(destroyableImage, nextFrame, imageSize);
|
||||
// SplitPalette is destructive (it sorts the pixels by color) so
|
||||
// we must create a copy of the image for it to destroy
|
||||
size_t imageSize = (size_t)(width * height * 4 * sizeof(uint8_t));
|
||||
uint8_t * destroyableImage = (uint8_t *)GIF_TEMP_MALLOC(imageSize);
|
||||
memcpy(destroyableImage, nextFrame, imageSize);
|
||||
|
||||
int numPixels = (int)(width * height);
|
||||
if(lastFrame)
|
||||
numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
|
||||
int numPixels = (int)(width * height);
|
||||
if (lastFrame) numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
|
||||
|
||||
const int lastElt = 1 << bitDepth;
|
||||
const int splitElt = lastElt/2;
|
||||
const int splitDist = splitElt/2;
|
||||
const int lastElt = 1 << bitDepth;
|
||||
const int splitElt = lastElt / 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
|
||||
pPal->treeSplit[1 << (bitDepth-1)] = 0;
|
||||
pPal->treeSplitElt[1 << (bitDepth-1)] = 0;
|
||||
// add the bottom node for the transparency index
|
||||
pPal->treeSplit[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
|
||||
void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal )
|
||||
{
|
||||
int numPixels = (int)(width * height);
|
||||
void GifDitherImage(const uint8_t * lastFrame,
|
||||
const uint8_t * nextFrame,
|
||||
uint8_t * outFrame,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
GifPalette * pPal) {
|
||||
int numPixels = (int)(width * height);
|
||||
|
||||
// quantPixels initially holds color*256 for all pixels
|
||||
// The extra 8 bits of precision allow for sub-single-color error values
|
||||
// to be propagated
|
||||
int32_t *quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4);
|
||||
// quantPixels initially holds color*256 for all pixels
|
||||
// The extra 8 bits of precision allow for sub-single-color error values
|
||||
// to be propagated
|
||||
int32_t * quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4);
|
||||
|
||||
for( int ii=0; ii<numPixels*4; ++ii )
|
||||
{
|
||||
uint8_t pix = nextFrame[ii];
|
||||
int32_t pix16 = (int32_t)(pix) * 256;
|
||||
quantPixels[ii] = pix16;
|
||||
}
|
||||
for (int ii = 0; ii < numPixels * 4; ++ii) {
|
||||
uint8_t pix = nextFrame[ii];
|
||||
int32_t pix16 = (int32_t)(pix)*256;
|
||||
quantPixels[ii] = pix16;
|
||||
}
|
||||
|
||||
for( uint32_t yy=0; yy<height; ++yy )
|
||||
{
|
||||
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;
|
||||
for (uint32_t yy = 0; yy < height; ++yy) {
|
||||
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;
|
||||
|
||||
// Compute the colors we want (rounding to nearest)
|
||||
int32_t rr = (nextPix[0] + 127) / 256;
|
||||
int32_t gg = (nextPix[1] + 127) / 256;
|
||||
int32_t bb = (nextPix[2] + 127) / 256;
|
||||
// Compute the colors we want (rounding to nearest)
|
||||
int32_t rr = (nextPix[0] + 127) / 256;
|
||||
int32_t gg = (nextPix[1] + 127) / 256;
|
||||
int32_t bb = (nextPix[2] + 127) / 256;
|
||||
|
||||
// if it happens that we want the color from last frame, then just write out
|
||||
// a transparent pixel
|
||||
if( lastFrame &&
|
||||
lastPix[0] == rr &&
|
||||
lastPix[1] == gg &&
|
||||
lastPix[2] == bb )
|
||||
{
|
||||
nextPix[0] = rr;
|
||||
nextPix[1] = gg;
|
||||
nextPix[2] = bb;
|
||||
nextPix[3] = kGifTransIndex;
|
||||
continue;
|
||||
}
|
||||
// if it happens that we want the color from last frame, then just write out
|
||||
// a transparent pixel
|
||||
if (lastFrame && lastPix[0] == rr && lastPix[1] == gg && lastPix[2] == bb) {
|
||||
nextPix[0] = rr;
|
||||
nextPix[1] = gg;
|
||||
nextPix[2] = bb;
|
||||
nextPix[3] = kGifTransIndex;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t bestDiff = 1000000;
|
||||
int32_t bestInd = kGifTransIndex;
|
||||
int32_t bestDiff = 1000000;
|
||||
int32_t bestInd = kGifTransIndex;
|
||||
|
||||
// Search the palete
|
||||
GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1);
|
||||
// Search the palete
|
||||
GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1);
|
||||
|
||||
// Write the result to the temp buffer
|
||||
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 b_err = nextPix[2] - (int32_t)(pPal->b[bestInd]) * 256;
|
||||
// Write the result to the temp buffer
|
||||
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 b_err = nextPix[2] - (int32_t)(pPal->b[bestInd]) * 256;
|
||||
|
||||
nextPix[0] = pPal->r[bestInd];
|
||||
nextPix[1] = pPal->g[bestInd];
|
||||
nextPix[2] = pPal->b[bestInd];
|
||||
nextPix[3] = bestInd;
|
||||
nextPix[0] = pPal->r[bestInd];
|
||||
nextPix[1] = pPal->g[bestInd];
|
||||
nextPix[2] = pPal->b[bestInd];
|
||||
nextPix[3] = bestInd;
|
||||
|
||||
// Propagate the error to the four adjacent locations
|
||||
// that we haven't touched yet
|
||||
int quantloc_7 = (int)(yy * width + xx + 1);
|
||||
int quantloc_3 = (int)(yy * width + width + xx - 1);
|
||||
int quantloc_5 = (int)(yy * width + width + xx);
|
||||
int quantloc_1 = (int)(yy * width + width + xx + 1);
|
||||
// Propagate the error to the four adjacent locations
|
||||
// that we haven't touched yet
|
||||
int quantloc_7 = (int)(yy * width + xx + 1);
|
||||
int quantloc_3 = (int)(yy * width + width + xx - 1);
|
||||
int quantloc_5 = (int)(yy * width + width + xx);
|
||||
int quantloc_1 = (int)(yy * width + width + xx + 1);
|
||||
|
||||
if(quantloc_7 < numPixels)
|
||||
{
|
||||
int32_t* pix7 = quantPixels+4*quantloc_7;
|
||||
pix7[0] += GifIMax( -pix7[0], r_err * 7 / 16 );
|
||||
pix7[1] += GifIMax( -pix7[1], g_err * 7 / 16 );
|
||||
pix7[2] += GifIMax( -pix7[2], b_err * 7 / 16 );
|
||||
}
|
||||
if (quantloc_7 < numPixels) {
|
||||
int32_t * pix7 = quantPixels + 4 * quantloc_7;
|
||||
pix7[0] += GifIMax(-pix7[0], r_err * 7 / 16);
|
||||
pix7[1] += GifIMax(-pix7[1], g_err * 7 / 16);
|
||||
pix7[2] += GifIMax(-pix7[2], b_err * 7 / 16);
|
||||
}
|
||||
|
||||
if(quantloc_3 < numPixels)
|
||||
{
|
||||
int32_t* pix3 = quantPixels+4*quantloc_3;
|
||||
pix3[0] += GifIMax( -pix3[0], r_err * 3 / 16 );
|
||||
pix3[1] += GifIMax( -pix3[1], g_err * 3 / 16 );
|
||||
pix3[2] += GifIMax( -pix3[2], b_err * 3 / 16 );
|
||||
}
|
||||
if (quantloc_3 < numPixels) {
|
||||
int32_t * pix3 = quantPixels + 4 * quantloc_3;
|
||||
pix3[0] += GifIMax(-pix3[0], r_err * 3 / 16);
|
||||
pix3[1] += GifIMax(-pix3[1], g_err * 3 / 16);
|
||||
pix3[2] += GifIMax(-pix3[2], b_err * 3 / 16);
|
||||
}
|
||||
|
||||
if(quantloc_5 < numPixels)
|
||||
{
|
||||
int32_t* pix5 = quantPixels+4*quantloc_5;
|
||||
pix5[0] += GifIMax( -pix5[0], r_err * 5 / 16 );
|
||||
pix5[1] += GifIMax( -pix5[1], g_err * 5 / 16 );
|
||||
pix5[2] += GifIMax( -pix5[2], b_err * 5 / 16 );
|
||||
}
|
||||
if (quantloc_5 < numPixels) {
|
||||
int32_t * pix5 = quantPixels + 4 * quantloc_5;
|
||||
pix5[0] += GifIMax(-pix5[0], r_err * 5 / 16);
|
||||
pix5[1] += GifIMax(-pix5[1], g_err * 5 / 16);
|
||||
pix5[2] += GifIMax(-pix5[2], b_err * 5 / 16);
|
||||
}
|
||||
|
||||
if(quantloc_1 < numPixels)
|
||||
{
|
||||
int32_t* pix1 = quantPixels+4*quantloc_1;
|
||||
pix1[0] += GifIMax( -pix1[0], r_err / 16 );
|
||||
pix1[1] += GifIMax( -pix1[1], g_err / 16 );
|
||||
pix1[2] += GifIMax( -pix1[2], b_err / 16 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (quantloc_1 < numPixels) {
|
||||
int32_t * pix1 = quantPixels + 4 * quantloc_1;
|
||||
pix1[0] += GifIMax(-pix1[0], r_err / 16);
|
||||
pix1[1] += GifIMax(-pix1[1], g_err / 16);
|
||||
pix1[2] += GifIMax(-pix1[2], b_err / 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the palettized result to the output buffer
|
||||
for( int ii=0; ii<numPixels*4; ++ii )
|
||||
{
|
||||
outFrame[ii] = (uint8_t)quantPixels[ii];
|
||||
}
|
||||
// Copy the palettized result to the output buffer
|
||||
for (int ii = 0; ii < numPixels * 4; ++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
|
||||
void GifThresholdImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal )
|
||||
{
|
||||
uint32_t numPixels = width*height;
|
||||
for( uint32_t ii=0; ii<numPixels; ++ii )
|
||||
{
|
||||
// if a previous color is available, and it matches the current color,
|
||||
// set the pixel to transparent
|
||||
if(lastFrame &&
|
||||
lastFrame[0] == nextFrame[0] &&
|
||||
lastFrame[1] == nextFrame[1] &&
|
||||
lastFrame[2] == nextFrame[2])
|
||||
{
|
||||
outFrame[0] = lastFrame[0];
|
||||
outFrame[1] = lastFrame[1];
|
||||
outFrame[2] = lastFrame[2];
|
||||
outFrame[3] = kGifTransIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
// palettize the pixel
|
||||
int32_t bestDiff = 1000000;
|
||||
int32_t bestInd = 1;
|
||||
GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], &bestInd, &bestDiff, 1);
|
||||
void GifThresholdImage(const uint8_t * lastFrame,
|
||||
const uint8_t * nextFrame,
|
||||
uint8_t * outFrame,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
GifPalette * pPal) {
|
||||
uint32_t numPixels = width * height;
|
||||
for (uint32_t ii = 0; ii < numPixels; ++ii) {
|
||||
// if a previous color is available, and it matches the current color,
|
||||
// set the pixel to transparent
|
||||
if (lastFrame && lastFrame[0] == nextFrame[0] && lastFrame[1] == nextFrame[1] && lastFrame[2] == nextFrame[2]) {
|
||||
outFrame[0] = lastFrame[0];
|
||||
outFrame[1] = lastFrame[1];
|
||||
outFrame[2] = lastFrame[2];
|
||||
outFrame[3] = kGifTransIndex;
|
||||
} else {
|
||||
// palettize the pixel
|
||||
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
|
||||
outFrame[0] = pPal->r[bestInd];
|
||||
outFrame[1] = pPal->g[bestInd];
|
||||
outFrame[2] = pPal->b[bestInd];
|
||||
outFrame[3] = (uint8_t)bestInd;
|
||||
}
|
||||
// Write the resulting color to the output buffer
|
||||
outFrame[0] = pPal->r[bestInd];
|
||||
outFrame[1] = pPal->g[bestInd];
|
||||
outFrame[2] = pPal->b[bestInd];
|
||||
outFrame[3] = (uint8_t)bestInd;
|
||||
}
|
||||
|
||||
if(lastFrame) lastFrame += 4;
|
||||
outFrame += 4;
|
||||
nextFrame += 4;
|
||||
}
|
||||
if (lastFrame) lastFrame += 4;
|
||||
outFrame += 4;
|
||||
nextFrame += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Simple structure to write out the LZW-compressed portion of the image
|
||||
// one bit at a time
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bitIndex; // how many bits in the partial byte written so far
|
||||
uint8_t byte; // current partial byte
|
||||
typedef struct {
|
||||
uint8_t bitIndex; // how many bits in the partial byte written so far
|
||||
uint8_t byte; // current partial byte
|
||||
|
||||
uint32_t chunkIndex;
|
||||
uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file
|
||||
uint32_t chunkIndex;
|
||||
uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file
|
||||
} GifBitStatus;
|
||||
|
||||
// insert a single bit
|
||||
void GifWriteBit( GifBitStatus* stat, uint32_t bit )
|
||||
{
|
||||
bit = bit & 1;
|
||||
bit = bit << stat->bitIndex;
|
||||
stat->byte |= bit;
|
||||
void GifWriteBit(GifBitStatus * stat, uint32_t bit) {
|
||||
bit = bit & 1;
|
||||
bit = bit << stat->bitIndex;
|
||||
stat->byte |= bit;
|
||||
|
||||
++stat->bitIndex;
|
||||
if( stat->bitIndex > 7 )
|
||||
{
|
||||
// move the newly-finished byte to the chunk buffer
|
||||
stat->chunk[stat->chunkIndex++] = stat->byte;
|
||||
// and start a new byte
|
||||
stat->bitIndex = 0;
|
||||
stat->byte = 0;
|
||||
}
|
||||
++stat->bitIndex;
|
||||
if (stat->bitIndex > 7) {
|
||||
// move the newly-finished byte to the chunk buffer
|
||||
stat->chunk[stat->chunkIndex++] = stat->byte;
|
||||
// and start a new byte
|
||||
stat->bitIndex = 0;
|
||||
stat->byte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// write all bytes so far to the file
|
||||
void GifWriteChunk( FILE* f, GifBitStatus* stat )
|
||||
{
|
||||
fputc((int)stat->chunkIndex, f);
|
||||
fwrite(stat->chunk, 1, stat->chunkIndex, f);
|
||||
void GifWriteChunk(FILE * f, GifBitStatus * stat) {
|
||||
fputc((int)stat->chunkIndex, f);
|
||||
fwrite(stat->chunk, 1, stat->chunkIndex, f);
|
||||
|
||||
stat->bitIndex = 0;
|
||||
stat->byte = 0;
|
||||
stat->chunkIndex = 0;
|
||||
stat->bitIndex = 0;
|
||||
stat->byte = 0;
|
||||
stat->chunkIndex = 0;
|
||||
}
|
||||
|
||||
void GifWriteCode( FILE* f, GifBitStatus* stat, uint32_t code, uint32_t length )
|
||||
{
|
||||
for( uint32_t ii=0; ii<length; ++ii )
|
||||
{
|
||||
GifWriteBit(stat, code);
|
||||
code = code >> 1;
|
||||
void GifWriteCode(FILE * f, GifBitStatus * stat, uint32_t code, uint32_t length) {
|
||||
for (uint32_t ii = 0; ii < length; ++ii) {
|
||||
GifWriteBit(stat, code);
|
||||
code = code >> 1;
|
||||
|
||||
if( stat->chunkIndex == 255 )
|
||||
{
|
||||
GifWriteChunk(f, stat);
|
||||
}
|
||||
}
|
||||
if (stat->chunkIndex == 255) {
|
||||
GifWriteChunk(f, stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The LZW dictionary is a 256-ary tree constructed as the file is encoded,
|
||||
// this is one node
|
||||
typedef struct
|
||||
{
|
||||
uint16_t m_next[256];
|
||||
typedef struct {
|
||||
uint16_t m_next[256];
|
||||
} GifLzwNode;
|
||||
|
||||
// write a 256-color (8-bit) image palette to the file
|
||||
void GifWritePalette( const GifPalette* pPal, FILE* f )
|
||||
{
|
||||
fputc(0, f); // first color: transparency
|
||||
fputc(0, f);
|
||||
fputc(0, f);
|
||||
void GifWritePalette(const GifPalette * pPal, FILE * f) {
|
||||
fputc(0, f); // first color: transparency
|
||||
fputc(0, f);
|
||||
fputc(0, f);
|
||||
|
||||
for(int ii=1; ii<(1 << pPal->bitDepth); ++ii)
|
||||
{
|
||||
uint32_t r = pPal->r[ii];
|
||||
uint32_t g = pPal->g[ii];
|
||||
uint32_t b = pPal->b[ii];
|
||||
for (int ii = 1; ii < (1 << pPal->bitDepth); ++ii) {
|
||||
uint32_t r = pPal->r[ii];
|
||||
uint32_t g = pPal->g[ii];
|
||||
uint32_t b = pPal->b[ii];
|
||||
|
||||
fputc((int)r, f);
|
||||
fputc((int)g, f);
|
||||
fputc((int)b, f);
|
||||
}
|
||||
fputc((int)r, f);
|
||||
fputc((int)g, f);
|
||||
fputc((int)b, f);
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// graphics control extension
|
||||
fputc(0x21, 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);
|
||||
void GifWriteLzwImage(FILE * f,
|
||||
uint8_t * image,
|
||||
uint32_t left,
|
||||
uint32_t top,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t delay,
|
||||
GifPalette * pPal) {
|
||||
// graphics control extension
|
||||
fputc(0x21, 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 >> 8) & 0xff, f);
|
||||
fputc(top & 0xff, f);
|
||||
fputc((top >> 8) & 0xff, f);
|
||||
fputc(left & 0xff, f); // corner of image in canvas space
|
||||
fputc((left >> 8) & 0xff, f);
|
||||
fputc(top & 0xff, f);
|
||||
fputc((top >> 8) & 0xff, f);
|
||||
|
||||
fputc(width & 0xff, f); // width and height of image
|
||||
fputc((width >> 8) & 0xff, f);
|
||||
fputc(height & 0xff, f);
|
||||
fputc((height >> 8) & 0xff, f);
|
||||
fputc(width & 0xff, f); // width and height of image
|
||||
fputc((width >> 8) & 0xff, f);
|
||||
fputc(height & 0xff, f);
|
||||
fputc((height >> 8) & 0xff, f);
|
||||
|
||||
//fputc(0, f); // no local color table, no transparency
|
||||
//fputc(0x80, f); // no local color table, but transparency
|
||||
// fputc(0, f); // no local color table, no transparency
|
||||
// fputc(0x80, f); // no local color table, but transparency
|
||||
|
||||
fputc(0x80 + pPal->bitDepth-1, f); // local color table present, 2 ^ bitDepth entries
|
||||
GifWritePalette(pPal, f);
|
||||
fputc(0x80 + pPal->bitDepth - 1, f); // local color table present, 2 ^ bitDepth entries
|
||||
GifWritePalette(pPal, f);
|
||||
|
||||
const int minCodeSize = pPal->bitDepth;
|
||||
const uint32_t clearCode = 1 << pPal->bitDepth;
|
||||
const int minCodeSize = 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);
|
||||
int32_t curCode = -1;
|
||||
uint32_t codeSize = (uint32_t)minCodeSize + 1;
|
||||
uint32_t maxCode = clearCode+1;
|
||||
memset(codetree, 0, sizeof(GifLzwNode) * 4096);
|
||||
int32_t curCode = -1;
|
||||
uint32_t codeSize = (uint32_t)minCodeSize + 1;
|
||||
uint32_t maxCode = clearCode + 1;
|
||||
|
||||
GifBitStatus stat;
|
||||
stat.byte = 0;
|
||||
stat.bitIndex = 0;
|
||||
stat.chunkIndex = 0;
|
||||
GifBitStatus stat;
|
||||
stat.byte = 0;
|
||||
stat.bitIndex = 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 xx=0; xx<width; ++xx)
|
||||
{
|
||||
#ifdef GIF_FLIP_VERT
|
||||
// bottom-left origin image (such as an OpenGL capture)
|
||||
uint8_t nextValue = image[((height-1-yy)*width+xx)*4+3];
|
||||
#else
|
||||
// top-left origin
|
||||
uint8_t nextValue = image[(yy*width+xx)*4+3];
|
||||
#endif
|
||||
for (uint32_t yy = 0; yy < height; ++yy) {
|
||||
for (uint32_t xx = 0; xx < width; ++xx) {
|
||||
#ifdef GIF_FLIP_VERT
|
||||
// bottom-left origin image (such as an OpenGL capture)
|
||||
uint8_t nextValue = image[((height - 1 - yy) * width + xx) * 4 + 3];
|
||||
#else
|
||||
// top-left origin
|
||||
uint8_t nextValue = image[(yy * width + xx) * 4 + 3];
|
||||
#endif
|
||||
|
||||
// "loser mode" - no compression, every single code is followed immediately by a clear
|
||||
//WriteCode( f, stat, nextValue, codeSize );
|
||||
//WriteCode( f, stat, 256, codeSize );
|
||||
// "loser mode" - no compression, every single code is followed immediately by a clear
|
||||
// WriteCode( f, stat, nextValue, codeSize );
|
||||
// WriteCode( f, stat, 256, codeSize );
|
||||
|
||||
if( curCode < 0 )
|
||||
{
|
||||
// first value in a new run
|
||||
curCode = nextValue;
|
||||
}
|
||||
else if( codetree[curCode].m_next[nextValue] )
|
||||
{
|
||||
// current run already in the dictionary
|
||||
curCode = codetree[curCode].m_next[nextValue];
|
||||
}
|
||||
else
|
||||
{
|
||||
// finish the current run, write a code
|
||||
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
|
||||
if (curCode < 0) {
|
||||
// first value in a new run
|
||||
curCode = nextValue;
|
||||
} else if (codetree[curCode].m_next[nextValue]) {
|
||||
// current run already in the dictionary
|
||||
curCode = codetree[curCode].m_next[nextValue];
|
||||
} else {
|
||||
// finish the current run, write a code
|
||||
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
|
||||
|
||||
// insert the new run into the dictionary
|
||||
codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode;
|
||||
// insert the new run into the dictionary
|
||||
codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode;
|
||||
|
||||
if( maxCode >= (1ul << codeSize) )
|
||||
{
|
||||
// dictionary entry count has broken a size barrier,
|
||||
// we need more bits for codes
|
||||
codeSize++;
|
||||
}
|
||||
if( maxCode == 4095 )
|
||||
{
|
||||
// the dictionary is full, clear it out and begin anew
|
||||
GifWriteCode(f, &stat, clearCode, codeSize); // clear tree
|
||||
if (maxCode >= (1ul << codeSize)) {
|
||||
// dictionary entry count has broken a size barrier,
|
||||
// we need more bits for codes
|
||||
codeSize++;
|
||||
}
|
||||
if (maxCode == 4095) {
|
||||
// the dictionary is full, clear it out and begin anew
|
||||
GifWriteCode(f, &stat, clearCode, codeSize); // clear tree
|
||||
|
||||
memset(codetree, 0, sizeof(GifLzwNode)*4096);
|
||||
codeSize = (uint32_t)(minCodeSize + 1);
|
||||
maxCode = clearCode+1;
|
||||
}
|
||||
memset(codetree, 0, sizeof(GifLzwNode) * 4096);
|
||||
codeSize = (uint32_t)(minCodeSize + 1);
|
||||
maxCode = clearCode + 1;
|
||||
}
|
||||
|
||||
curCode = nextValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
curCode = nextValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compression footer
|
||||
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
|
||||
GifWriteCode(f, &stat, clearCode, codeSize);
|
||||
GifWriteCode(f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1);
|
||||
// compression footer
|
||||
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
|
||||
GifWriteCode(f, &stat, clearCode, codeSize);
|
||||
GifWriteCode(f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1);
|
||||
|
||||
// write out the last partial chunk
|
||||
while( stat.bitIndex ) GifWriteBit(&stat, 0);
|
||||
if( stat.chunkIndex ) GifWriteChunk(f, &stat);
|
||||
// write out the last partial chunk
|
||||
while (stat.bitIndex)
|
||||
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
|
||||
{
|
||||
FILE* f;
|
||||
uint8_t* oldImage;
|
||||
bool firstFrame;
|
||||
typedef struct {
|
||||
FILE * f;
|
||||
uint8_t * oldImage;
|
||||
bool firstFrame;
|
||||
} GifWriter;
|
||||
|
||||
// Creates a gif file.
|
||||
// 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.
|
||||
bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth = 8, bool dither = false )
|
||||
{
|
||||
(void)bitDepth; (void)dither; // Mute "Unused argument" warnings
|
||||
bool GifBegin(GifWriter * writer,
|
||||
const char * filename,
|
||||
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)
|
||||
writer->f = 0;
|
||||
fopen_s(&writer->f, filename, "wb");
|
||||
fopen_s(&writer->f, filename, "wb");
|
||||
#else
|
||||
writer->f = fopen(filename, "wb");
|
||||
writer->f = fopen(filename, "wb");
|
||||
#endif
|
||||
if(!writer->f) return false;
|
||||
if (!writer->f) return false;
|
||||
|
||||
writer->firstFrame = true;
|
||||
writer->firstFrame = true;
|
||||
|
||||
// allocate
|
||||
writer->oldImage = (uint8_t*)GIF_MALLOC(width*height*4);
|
||||
// allocate
|
||||
writer->oldImage = (uint8_t *)GIF_MALLOC(width * height * 4);
|
||||
|
||||
fputs("GIF89a", writer->f);
|
||||
fputs("GIF89a", writer->f);
|
||||
|
||||
// screen descriptor
|
||||
fputc(width & 0xff, writer->f);
|
||||
fputc((width >> 8) & 0xff, writer->f);
|
||||
fputc(height & 0xff, writer->f);
|
||||
fputc((height >> 8) & 0xff, writer->f);
|
||||
// screen descriptor
|
||||
fputc(width & 0xff, writer->f);
|
||||
fputc((width >> 8) & 0xff, writer->f);
|
||||
fputc(height & 0xff, writer->f);
|
||||
fputc((height >> 8) & 0xff, writer->f);
|
||||
|
||||
fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries
|
||||
fputc(0, writer->f); // background color
|
||||
fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989)
|
||||
fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries
|
||||
fputc(0, writer->f); // background color
|
||||
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)
|
||||
// color 0: black
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
// color 1: also black
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
// now the "global" palette (really just a dummy palette)
|
||||
// color 0: black
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
// color 1: also black
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
|
||||
if( delay != 0 )
|
||||
{
|
||||
// animation header
|
||||
fputc(0x21, writer->f); // extension
|
||||
fputc(0xff, writer->f); // application specific
|
||||
fputc(11, writer->f); // length 11
|
||||
fputs("NETSCAPE2.0", writer->f); // yes, really
|
||||
fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data
|
||||
if (delay != 0) {
|
||||
// animation header
|
||||
fputc(0x21, writer->f); // extension
|
||||
fputc(0xff, writer->f); // application specific
|
||||
fputc(11, writer->f); // length 11
|
||||
fputs("NETSCAPE2.0", writer->f); // yes, really
|
||||
fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data
|
||||
|
||||
fputc(1, writer->f); // JUST BECAUSE
|
||||
fputc(0, writer->f); // loop infinitely (byte 0)
|
||||
fputc(0, writer->f); // loop infinitely (byte 1)
|
||||
fputc(1, writer->f); // JUST BECAUSE
|
||||
fputc(0, writer->f); // loop infinitely (byte 0)
|
||||
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.
|
||||
// The GIFWriter should have been created by GIFBegin.
|
||||
// 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.
|
||||
bool GifWriteFrame( GifWriter* writer, const uint8_t* image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth = 8, bool dither = false )
|
||||
{
|
||||
if(!writer->f) return false;
|
||||
bool GifWriteFrame(GifWriter * writer,
|
||||
const uint8_t * image,
|
||||
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;
|
||||
writer->firstFrame = false;
|
||||
const uint8_t * oldImage = writer->firstFrame ? NULL : writer->oldImage;
|
||||
writer->firstFrame = false;
|
||||
|
||||
GifPalette pal;
|
||||
GifMakePalette((dither? NULL : oldImage), image, width, height, bitDepth, dither, &pal);
|
||||
GifPalette pal;
|
||||
GifMakePalette((dither ? NULL : oldImage), image, width, height, bitDepth, dither, &pal);
|
||||
|
||||
if(dither)
|
||||
GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal);
|
||||
else
|
||||
GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal);
|
||||
if (dither)
|
||||
GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal);
|
||||
else
|
||||
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.
|
||||
// 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.
|
||||
bool GifEnd( GifWriter* writer )
|
||||
{
|
||||
if(!writer->f) return false;
|
||||
bool GifEnd(GifWriter * writer) {
|
||||
if (!writer->f) return false;
|
||||
|
||||
fputc(0x3b, writer->f); // end of file
|
||||
fclose(writer->f);
|
||||
GIF_FREE(writer->oldImage);
|
||||
fputc(0x3b, writer->f); // end of file
|
||||
fclose(writer->f);
|
||||
GIF_FREE(writer->oldImage);
|
||||
|
||||
writer->f = NULL;
|
||||
writer->oldImage = NULL;
|
||||
writer->f = NULL;
|
||||
writer->oldImage = NULL;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
#include "graphic.h"
|
||||
|
||||
#include "gif.h"
|
||||
#include "qad_types.h"
|
||||
#include "uglwidget.h"
|
||||
#include "ui_graphic.h"
|
||||
#include "ui_graphic_conf.h"
|
||||
#include <float.h>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include <QActionGroup>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QTapAndHoldGesture>
|
||||
#include <QMetaObject>
|
||||
#include <QPanGesture>
|
||||
#include <QPinchGesture>
|
||||
#include <QActionGroup>
|
||||
#include <QScrollArea>
|
||||
#include <QTapAndHoldGesture>
|
||||
#include <QTimer>
|
||||
#include <QInputDialog>
|
||||
#include "gif.h"
|
||||
#include <float.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
# include <QRandomGenerator>
|
||||
#endif
|
||||
@@ -21,12 +23,12 @@
|
||||
# define NO_BUTTONS
|
||||
#else
|
||||
# ifndef FORCE_NO_GL
|
||||
# define HAS_GL
|
||||
# define HAS_GL
|
||||
# endif
|
||||
#endif
|
||||
#ifdef HAS_GL
|
||||
# ifndef GL_MULTISAMPLE
|
||||
# define GL_MULTISAMPLE 0x809D
|
||||
# define GL_MULTISAMPLE 0x809D
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -42,7 +44,7 @@ enum DateComponent {
|
||||
};
|
||||
|
||||
const char _button_prop_name_[] = "_button_";
|
||||
const double rad2deg_qpie = 45. / atan(1.);
|
||||
const double rad2deg_qpie = 45. / atan(1.);
|
||||
|
||||
__GraphicRegistrator__ __graphic_registrator__;
|
||||
|
||||
@@ -61,6 +63,7 @@ public:
|
||||
w->setAutoFillBackground(false);
|
||||
}
|
||||
int minimum_hei;
|
||||
|
||||
protected:
|
||||
virtual QSize sizeHint() const {
|
||||
QSize ret;
|
||||
@@ -68,26 +71,24 @@ protected:
|
||||
ret = widget()->sizeHint();
|
||||
return ret;
|
||||
}
|
||||
virtual QSize minimumSizeHint() const {
|
||||
return QSize(1, minimum_hei);
|
||||
}
|
||||
virtual QSize minimumSizeHint() const { 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) {
|
||||
canvas_gl = 0;
|
||||
canvas_gl = 0;
|
||||
timer_pause = timer_record = 0;
|
||||
gesture_angle = 45.;
|
||||
leg_update = true;
|
||||
gesture_angle = 45.;
|
||||
leg_update = true;
|
||||
visible_update = fullscr = need_mouse_pan = m_fakeGL = false;
|
||||
gestures =
|
||||
#ifdef Q_OS_ANDROID
|
||||
true;
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
false;
|
||||
#endif
|
||||
func_gridMarkX = func_gridMarkY = nullptr;
|
||||
ui = new Ui::Graphic();
|
||||
ui = new Ui::Graphic();
|
||||
ui->setupUi(this);
|
||||
ui->scrollLegend->layout()->addWidget(new LegendScrollArea(ui->widgetLegend));
|
||||
ui->scrollLegend->hide();
|
||||
@@ -95,21 +96,20 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
|
||||
#ifdef NO_BUTTONS
|
||||
ui->widgetLeft->hide();
|
||||
ui->widgetRight->hide();
|
||||
QList<QToolButton*> btnlist = {
|
||||
ui->graphic_buttonAutofit,
|
||||
ui->graphic_checkGrid,
|
||||
ui->graphic_checkGuides,
|
||||
ui->graphic_buttonFullscreen,
|
||||
ui->graphic_checkBorderInputs,
|
||||
ui->graphic_checkLegend,
|
||||
ui->graphic_checkPause,
|
||||
ui->graphic_buttonConfigure,
|
||||
ui->graphic_buttonSave,
|
||||
ui->graphic_buttonExport,
|
||||
ui->graphic_buttonRecord,
|
||||
ui->graphic_buttonClear,
|
||||
ui->graphic_buttonClose};
|
||||
buttons_menu = new QMenu(this);
|
||||
QList<QToolButton *> btnlist = {ui->graphic_buttonAutofit,
|
||||
ui->graphic_checkGrid,
|
||||
ui->graphic_checkGuides,
|
||||
ui->graphic_buttonFullscreen,
|
||||
ui->graphic_checkBorderInputs,
|
||||
ui->graphic_checkLegend,
|
||||
ui->graphic_checkPause,
|
||||
ui->graphic_buttonConfigure,
|
||||
ui->graphic_buttonSave,
|
||||
ui->graphic_buttonExport,
|
||||
ui->graphic_buttonRecord,
|
||||
ui->graphic_buttonClear,
|
||||
ui->graphic_buttonClose};
|
||||
buttons_menu = new QMenu(this);
|
||||
for (auto * b: btnlist) {
|
||||
auto * a = new QAction(this);
|
||||
connect(a, SIGNAL(triggered()), b, SLOT(click()));
|
||||
@@ -120,31 +120,31 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
|
||||
}
|
||||
#endif
|
||||
QActionGroup * agroup = new QActionGroup(this);
|
||||
agroup->addAction(ui->graphic_actionGuidesFree );
|
||||
agroup->addAction(ui->graphic_actionGuidesTrace );
|
||||
agroup->addAction(ui->graphic_actionGuidesFree);
|
||||
agroup->addAction(ui->graphic_actionGuidesTrace);
|
||||
agroup->addAction(ui->graphic_actionGuidesTraceX);
|
||||
agroup->addAction(ui->graphic_actionGuidesTraceY);
|
||||
ui->graphic_actionGuidesFree ->setProperty("_value", (int)Free );
|
||||
ui->graphic_actionGuidesTrace ->setProperty("_value", (int)TraceXY);
|
||||
ui->graphic_actionGuidesTraceX->setProperty("_value", (int)TraceX );
|
||||
ui->graphic_actionGuidesTraceY->setProperty("_value", (int)TraceY );
|
||||
ui->graphic_actionGuidesFree->setProperty("_value", (int)Free);
|
||||
ui->graphic_actionGuidesTrace->setProperty("_value", (int)TraceXY);
|
||||
ui->graphic_actionGuidesTraceX->setProperty("_value", (int)TraceX);
|
||||
ui->graphic_actionGuidesTraceY->setProperty("_value", (int)TraceY);
|
||||
ui->graphic_actionGuidesFree->setChecked(true);
|
||||
connect(agroup, SIGNAL(triggered(QAction*)), this, SLOT(actionGuidesTriggered(QAction*)));
|
||||
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesFree );
|
||||
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesTrace );
|
||||
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesTraceX);
|
||||
ui->graphic_checkGuides ->addAction(ui->graphic_actionGuidesTraceY);
|
||||
connect(agroup, SIGNAL(triggered(QAction *)), this, SLOT(actionGuidesTriggered(QAction *)));
|
||||
ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesFree);
|
||||
ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesTrace);
|
||||
ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesTraceX);
|
||||
ui->graphic_checkGuides->addAction(ui->graphic_actionGuidesTraceY);
|
||||
ui->graphic_buttonAutofit->addAction(ui->graphic_actionExpandX);
|
||||
ui->graphic_buttonAutofit->addAction(ui->graphic_actionExpandY);
|
||||
line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
line_x_max.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
((QBoxLayout * )ui->widgetLY->layout())->insertWidget(0, &line_y_min);
|
||||
((QBoxLayout * )ui->widgetLY->layout())->addWidget(&line_y_max);
|
||||
((QBoxLayout * )ui->widgetLX->layout())->insertWidget(0, &line_x_min);
|
||||
((QBoxLayout * )ui->widgetLX->layout())->addWidget(&line_x_max);
|
||||
((QBoxLayout *)ui->widgetLY->layout())->insertWidget(0, &line_y_min);
|
||||
((QBoxLayout *)ui->widgetLY->layout())->addWidget(&line_y_max);
|
||||
((QBoxLayout *)ui->widgetLX->layout())->insertWidget(0, &line_x_min);
|
||||
((QBoxLayout *)ui->widgetLX->layout())->addWidget(&line_x_max);
|
||||
tm.restart();
|
||||
grid_numbers_x = grid_numbers_y = 1;
|
||||
LN10 = qLn(10.);
|
||||
LN10 = qLn(10.);
|
||||
line_x_min.setClearButtonVisible(true);
|
||||
line_x_max.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_y_min, SIGNAL(valueChanged(double)), this, SLOT(lineYMinChanged(double)));
|
||||
connect(&line_y_max, SIGNAL(valueChanged(double)), this, SLOT(lineYMaxChanged(double)));
|
||||
connect(ui->canvas_raster, SIGNAL(paintEvent(QPaintEvent * )), this, SLOT(canvasPaintEvent()));
|
||||
connect(ui->canvas_raster, SIGNAL(paintEvent(QPaintEvent *)), this, SLOT(canvasPaintEvent()));
|
||||
prepareCanvas(ui->canvas_raster);
|
||||
icon_exp_x = QIcon(":/icons/expand_x.png");
|
||||
icon_exp_y = QIcon(":/icons/expand_y.png");
|
||||
icon_exp_sx = QIcon(":/icons/expand_s_x.png");
|
||||
icon_exp_sy = QIcon(":/icons/expand_s_y.png");
|
||||
icon_exp_x = QIcon(":/icons/expand_x.png");
|
||||
icon_exp_y = QIcon(":/icons/expand_y.png");
|
||||
icon_exp_sx = QIcon(":/icons/expand_s_x.png");
|
||||
icon_exp_sy = QIcon(":/icons/expand_s_y.png");
|
||||
icon_pause_b = QImage(":/icons/pause-back.png");
|
||||
icon_pause_f = QImage(":/icons/pause-front.png");
|
||||
aupdate = grid = isFit = navigation = true;
|
||||
@@ -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);
|
||||
eminx = eminy = DBL_MAX;
|
||||
emaxx = emaxy = DBL_MIN;
|
||||
grad_x = grad_y = Auto;
|
||||
axis_type_x = Numeric;
|
||||
grad_x = grad_y = Auto;
|
||||
axis_type_x = Numeric;
|
||||
floating_axis_type = Free;
|
||||
min_repaint_int = 25;
|
||||
min_repaint_int = 25;
|
||||
lastw = lasth = 0;
|
||||
inc_x = 1.;
|
||||
//buffer = 0;
|
||||
inc_x = 1.;
|
||||
// buffer = 0;
|
||||
gridx = gridy = 1.;
|
||||
history = 5.;
|
||||
visible_time = -1.;
|
||||
thick = lineThickness(this);
|
||||
history = 5.;
|
||||
visible_time = -1.;
|
||||
thick = lineThickness(this);
|
||||
#if QT_VERSION_MAJOR >= 5
|
||||
thick *= devicePixelRatio();
|
||||
#endif
|
||||
@@ -189,13 +189,13 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
|
||||
selbrush.setStyle(Qt::SolidPattern);
|
||||
selbrush.setColor(QColor(60, 175, 255, 100));
|
||||
text_color = palette().color(QPalette::WindowText);
|
||||
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine);
|
||||
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine);
|
||||
graphics.append(GraphicType());
|
||||
curGraphic = curTrace = 0;
|
||||
selpen = palette().color(QPalette::WindowText);
|
||||
selpen = palette().color(QPalette::WindowText);
|
||||
selpen.setStyle(Qt::DashLine);
|
||||
back_color = palette().color(QPalette::Base);
|
||||
buttons_ = AllButtons;
|
||||
buttons_ = AllButtons;
|
||||
setOpenGL(false);
|
||||
setButtonsPosition(Graphic::Left);
|
||||
setAntialiasing(false);
|
||||
@@ -215,7 +215,7 @@ Graphic::~Graphic() {
|
||||
delete buttons_menu;
|
||||
#endif
|
||||
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 *) {
|
||||
if (leg_update)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
QTimer::singleShot(0, this, [this](){updateLegend(false);});
|
||||
QTimer::singleShot(0, this, [this]() { updateLegend(false); });
|
||||
#else
|
||||
updateLegend(false);
|
||||
#endif
|
||||
@@ -241,7 +241,7 @@ void Graphic::resizeEvent(QResizeEvent *) {
|
||||
|
||||
void Graphic::showEvent(QShowEvent *) {
|
||||
if (need_createGL && !canvas_gl) {
|
||||
//qDebug() << "create GL on show";
|
||||
// qDebug() << "create GL on show";
|
||||
canvas_gl = new UGLWidget();
|
||||
ui->layoutCanvas->addWidget(canvas_gl);
|
||||
connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent()));
|
||||
@@ -257,8 +257,7 @@ void Graphic::showEvent(QShowEvent *) {
|
||||
void Graphic::timerEvent(QTimerEvent * e) {
|
||||
if (e->timerId() == timer_pause) {
|
||||
pause_phase += 0.02;
|
||||
if (pause_phase > 1.)
|
||||
pause_phase -= 1.;
|
||||
if (pause_phase > 1.) pause_phase -= 1.;
|
||||
update();
|
||||
}
|
||||
if (e->timerId() == timer_record) {
|
||||
@@ -274,16 +273,16 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
|
||||
switch (e->type()) {
|
||||
case QEvent::Gesture:
|
||||
if (!navigation || !gestures) break;
|
||||
foreach (QGesture * g, ((QGestureEvent*)e)->gestures())
|
||||
foreach(QGesture * g, ((QGestureEvent *)e)->gestures())
|
||||
procGesture(g);
|
||||
break;
|
||||
case QEvent::KeyPress: {
|
||||
int k = ((QKeyEvent*)e)->key();
|
||||
int k = ((QKeyEvent *)e)->key();
|
||||
if ((k == Qt::Key_Back || k == Qt::Key_Escape) && fullscr) {
|
||||
leaveFullscreen();
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
} break;
|
||||
case QEvent::TouchBegin:
|
||||
if (!navigation || !gestures) break;
|
||||
need_mouse_pan = true;
|
||||
@@ -292,9 +291,9 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
|
||||
if (!navigation || !gestures) break;
|
||||
QList<QTouchEvent::TouchPoint> tpl =
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
((QTouchEvent*)e)->touchPoints();
|
||||
((QTouchEvent *)e)->touchPoints();
|
||||
#else
|
||||
((QTouchEvent*)e)->points();
|
||||
((QTouchEvent *)e)->points();
|
||||
#endif
|
||||
if (tpl.size() == 2) {
|
||||
need_mouse_pan = false;
|
||||
@@ -306,7 +305,7 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
|
||||
#endif
|
||||
gesture_angle = rad2deg_qpie * qAtan2(qAbs(dp.y()), qAbs(dp.x()));
|
||||
}
|
||||
} break;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -315,13 +314,13 @@ bool Graphic::eventFilter(QObject * o, QEvent * e) {
|
||||
|
||||
|
||||
void Graphic::prepareCanvas(QWidget * w) {
|
||||
connect(w, SIGNAL(mouseMoveEvent(QMouseEvent * )), this, SLOT(canvasMouseMoveEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(mousePressEvent(QMouseEvent * )), this, SLOT(canvasMousePressEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(mouseReleaseEvent(QMouseEvent * )), this, SLOT(canvasMouseReleaseEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(mouseDoubleClickEvent(QMouseEvent*)), this, SLOT(canvasMouseDoubleClickEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(wheelEvent(QWheelEvent * )), this, SLOT(canvasWheelEvent(QWheelEvent * )));
|
||||
connect(w, SIGNAL(leaveEvent(QEvent * )), this, SLOT(canvasLeaveEvent(QEvent * )));
|
||||
connect(w, SIGNAL(keyPressEvent(QKeyEvent * )), this, SLOT(canvasKeyPressEvent(QKeyEvent * )));
|
||||
connect(w, SIGNAL(mouseMoveEvent(QMouseEvent *)), this, SLOT(canvasMouseMoveEvent(QMouseEvent *)));
|
||||
connect(w, SIGNAL(mousePressEvent(QMouseEvent *)), this, SLOT(canvasMousePressEvent(QMouseEvent *)));
|
||||
connect(w, SIGNAL(mouseReleaseEvent(QMouseEvent *)), this, SLOT(canvasMouseReleaseEvent(QMouseEvent *)));
|
||||
connect(w, SIGNAL(mouseDoubleClickEvent(QMouseEvent *)), this, SLOT(canvasMouseDoubleClickEvent(QMouseEvent *)));
|
||||
connect(w, SIGNAL(wheelEvent(QWheelEvent *)), this, SLOT(canvasWheelEvent(QWheelEvent *)));
|
||||
connect(w, SIGNAL(leaveEvent(QEvent *)), this, SLOT(canvasLeaveEvent(QEvent *)));
|
||||
connect(w, SIGNAL(keyPressEvent(QKeyEvent *)), this, SLOT(canvasKeyPressEvent(QKeyEvent *)));
|
||||
w->grabGesture(Qt::TapAndHoldGesture);
|
||||
w->grabGesture(Qt::PanGesture);
|
||||
w->grabGesture(Qt::PinchGesture);
|
||||
@@ -335,15 +334,15 @@ void Graphic::procGesture(QGesture * g) {
|
||||
switch (g->gestureType()) {
|
||||
case Qt::PanGesture: {
|
||||
if (need_mouse_pan) break;
|
||||
QPanGesture * pg = (QPanGesture*)g;
|
||||
QPointF dp = -pg->delta();
|
||||
QPanGesture * pg = (QPanGesture *)g;
|
||||
QPointF dp = -pg->delta();
|
||||
dp.rx() /= getScaleX();
|
||||
dp.ry() /= getScaleY();
|
||||
selrect.translate(dp);
|
||||
totalUpdate();
|
||||
} break;
|
||||
} break;
|
||||
case Qt::PinchGesture: {
|
||||
QPinchGesture * pg = (QPinchGesture*)g;
|
||||
QPinchGesture * pg = (QPinchGesture *)g;
|
||||
Qt::KeyboardModifiers km = Qt::NoModifier;
|
||||
if (gesture_angle <= 20.) km = Qt::ControlModifier;
|
||||
if (gesture_angle >= 70.) km = Qt::ShiftModifier;
|
||||
@@ -351,33 +350,33 @@ void Graphic::procGesture(QGesture * g) {
|
||||
if (!fullscr) cp = mapFromGlobal(cp);
|
||||
procZoom(cp, (pg->scaleFactor() - 1.) * 500., km);
|
||||
totalUpdate();
|
||||
} break;
|
||||
} break;
|
||||
case Qt::TapAndHoldGesture: {
|
||||
QTapAndHoldGesture * pg = (QTapAndHoldGesture*)g;
|
||||
QTapAndHoldGesture * pg = (QTapAndHoldGesture *)g;
|
||||
if (pg->state() == Qt::GestureStarted)
|
||||
QMetaObject::invokeMethod(this, [this](){showMenu();}, Qt::QueuedConnection);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() { showMenu(); },
|
||||
Qt::QueuedConnection);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km) {
|
||||
double scl, wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
|
||||
double scl, wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(),
|
||||
hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
|
||||
double px = view_center.x() - gridborder.x() - margins_.left(), py = hei - view_center.y() + margins_.height();
|
||||
px = px / wid * selrect.width() + selrect.x();
|
||||
py = py / hei * selrect.height() + selrect.y();
|
||||
px = px / wid * selrect.width() + selrect.x();
|
||||
py = py / hei * selrect.height() + selrect.y();
|
||||
scl = 1. - dzoom / 500.;
|
||||
if (km == Qt::NoModifier)
|
||||
selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl);
|
||||
else {
|
||||
if (km == Qt::ControlModifier)
|
||||
selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height());
|
||||
if (km == Qt::ShiftModifier)
|
||||
selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
|
||||
if (km == Qt::AltModifier)
|
||||
selrect.translate((dzoom > 0. ? 1. : -1.) * selrect.width() / 2., 0.);
|
||||
if (km == Qt::ControlModifier) selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height());
|
||||
if (km == Qt::ShiftModifier) selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
|
||||
if (km == Qt::AltModifier) selrect.translate((dzoom > 0. ? 1. : -1.) * selrect.width() / 2., 0.);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,23 +391,22 @@ void Graphic::totalUpdate() {
|
||||
|
||||
void Graphic::canvasPaintEvent() {
|
||||
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 (!buffer.isNull()) {
|
||||
if (lastw != wid || lasth != hei)
|
||||
buffer = QPixmap();
|
||||
if (lastw != wid || lasth != hei) buffer = QPixmap();
|
||||
}
|
||||
if (buffer.isNull()) {
|
||||
#if QT_VERSION_MAJOR >= 5
|
||||
const qreal dpr = canvas->devicePixelRatio();
|
||||
buffer = QPixmap(canvas->size() * dpr);
|
||||
buffer = QPixmap(canvas->size() * dpr);
|
||||
buffer.setDevicePixelRatio(dpr);
|
||||
#else
|
||||
buffer = QPixmap(canvas->size());
|
||||
#endif
|
||||
}
|
||||
lastw = wid;
|
||||
lasth = hei;
|
||||
lastw = wid;
|
||||
lasth = hei;
|
||||
font_sz = fontMetrics().size(0, "0");
|
||||
font_sz.setHeight(font_sz.height() * 1.);
|
||||
#ifdef Q_OS_ANDROID
|
||||
@@ -452,13 +450,14 @@ void Graphic::canvasPaintEvent() {
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
emit beforeGraphicPaintEvent(painter);
|
||||
painter->setClipping(false);
|
||||
if (grid)
|
||||
drawGrid();
|
||||
if (grid) drawGrid();
|
||||
p.setRenderHint(QPainter::Antialiasing, aalias);
|
||||
#ifdef HAS_GL
|
||||
if (isOGL && !m_fakeGL) {
|
||||
if (aalias) glEnable(GL_MULTISAMPLE);
|
||||
else glDisable(GL_MULTISAMPLE);
|
||||
if (aalias)
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
#endif
|
||||
fp_size.clear();
|
||||
@@ -476,8 +475,8 @@ void Graphic::canvasPaintEvent() {
|
||||
|
||||
|
||||
void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
|
||||
isHover = true;
|
||||
curpos = e->pos();
|
||||
isHover = true;
|
||||
curpos = e->pos();
|
||||
curpos_r = canvas2real(curpos);
|
||||
QPointF dp;
|
||||
QString cursorstr = tr("Cursor: ") + pointCoords(curpos_r);
|
||||
@@ -491,38 +490,34 @@ void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
|
||||
if (gestures) {
|
||||
if (!need_mouse_pan) return;
|
||||
curaction = gaMove;
|
||||
} else
|
||||
if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton) return;
|
||||
} else if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton)
|
||||
return;
|
||||
switch (curaction) {
|
||||
case gaZoomInRect:
|
||||
ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " +
|
||||
pointCoords(curpos_r) + ", " + tr("Size") + ": " + pointCoords(absPoint(curpos_r - startpos_r)));
|
||||
repaintCanvas(true);
|
||||
case gaZoomInRect:
|
||||
ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " + pointCoords(curpos_r) + ", " + tr("Size") + ": " +
|
||||
pointCoords(absPoint(curpos_r - startpos_r)));
|
||||
repaintCanvas(true);
|
||||
break;
|
||||
case gaZoomRangeX:
|
||||
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) +
|
||||
" -> " + QString::number(curpos_r.x(), 'f', 3) + ", " + tr("Length") + ": " +
|
||||
QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
|
||||
repaintCanvas(true);
|
||||
case gaZoomRangeX:
|
||||
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) + " -> " + QString::number(curpos_r.x(), 'f', 3) +
|
||||
", " + tr("Length") + ": " + QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
|
||||
repaintCanvas(true);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) +
|
||||
" -> " + QString::number(curpos_r.y(), 'f', 3) + ", " + tr("Length") + ": " +
|
||||
QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
|
||||
repaintCanvas(true);
|
||||
case gaZoomRangeY:
|
||||
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) + " -> " + QString::number(curpos_r.y(), 'f', 3) +
|
||||
", " + tr("Length") + ": " + QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
|
||||
repaintCanvas(true);
|
||||
break;
|
||||
case gaMove:
|
||||
dp = e->pos() - prevpos;
|
||||
dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw);
|
||||
dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5);
|
||||
if (e->modifiers() == Qt::ControlModifier)
|
||||
dp.setY(0.);
|
||||
if (e->modifiers() == Qt::ShiftModifier)
|
||||
dp.setX(0.);
|
||||
selrect.translate(dp);
|
||||
totalUpdate();
|
||||
case gaMove:
|
||||
dp = e->pos() - prevpos;
|
||||
dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw);
|
||||
dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5);
|
||||
if (e->modifiers() == Qt::ControlModifier) dp.setY(0.);
|
||||
if (e->modifiers() == Qt::ShiftModifier) dp.setX(0.);
|
||||
selrect.translate(dp);
|
||||
totalUpdate();
|
||||
break;
|
||||
default: break;
|
||||
default: break;
|
||||
}
|
||||
prevpos = e->pos();
|
||||
}
|
||||
@@ -533,14 +528,14 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) {
|
||||
if (!navigation) return;
|
||||
if (gestures && !need_mouse_pan) return;
|
||||
setGuidesCursor();
|
||||
prevpos = e->pos();
|
||||
startpos = prevpos;
|
||||
prevpos = e->pos();
|
||||
startpos = prevpos;
|
||||
startpos_r = canvas2real(startpos);
|
||||
if (cancel || gestures) return;
|
||||
if (e->button() == QT_MID_BUTTON) curaction = gaMove;
|
||||
if (e->button() == Qt::RightButton) {
|
||||
if (bufferActive) {
|
||||
curpos = startpos;
|
||||
curpos = startpos;
|
||||
curpos_r = canvas2real(curpos);
|
||||
repaintCanvas(true);
|
||||
swapToNormal();
|
||||
@@ -553,16 +548,17 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) {
|
||||
}
|
||||
}
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
if (e->modifiers() == Qt::ControlModifier) curaction = gaZoomRangeX;
|
||||
else if (e->modifiers() == Qt::ShiftModifier) curaction = gaZoomRangeY;
|
||||
else curaction = gaZoomInRect;
|
||||
if (e->modifiers() == Qt::ControlModifier)
|
||||
curaction = gaZoomRangeX;
|
||||
else if (e->modifiers() == Qt::ShiftModifier)
|
||||
curaction = gaZoomRangeY;
|
||||
else
|
||||
curaction = gaZoomInRect;
|
||||
switch (curaction) {
|
||||
case gaZoomInRect:
|
||||
case gaZoomRangeX:
|
||||
case gaZoomRangeY:
|
||||
swapToBuffer();
|
||||
break;
|
||||
default: break;
|
||||
case gaZoomInRect:
|
||||
case gaZoomRangeX:
|
||||
case gaZoomRangeY: swapToBuffer(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
setCurrentAction(curaction);
|
||||
@@ -588,24 +584,24 @@ void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) {
|
||||
}
|
||||
if (e->button() == Qt::LeftButton && (e->buttons() & Qt::RightButton) != Qt::RightButton) {
|
||||
if (curpos != startpos) {
|
||||
tlp = canvas2real(sr.topLeft());
|
||||
brp = canvas2real(sr.bottomRight());
|
||||
tlp = canvas2real(sr.topLeft());
|
||||
brp = canvas2real(sr.bottomRight());
|
||||
isFit = false;
|
||||
switch (curaction) {
|
||||
case gaZoomInRect:
|
||||
if (sr.width() <= 1 || sr.height() <= 1) break;
|
||||
selrect.setCoords(tlp.x(), brp.y(), brp.x(), tlp.y());
|
||||
setRectToLines();
|
||||
case gaZoomInRect:
|
||||
if (sr.width() <= 1 || sr.height() <= 1) break;
|
||||
selrect.setCoords(tlp.x(), brp.y(), brp.x(), tlp.y());
|
||||
setRectToLines();
|
||||
break;
|
||||
case gaZoomRangeX:
|
||||
if (sr.width() <= 1) break;
|
||||
findGraphicsRect(tlp.x(), brp.x());
|
||||
case gaZoomRangeX:
|
||||
if (sr.width() <= 1) break;
|
||||
findGraphicsRect(tlp.x(), brp.x());
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
if (sr.height() <= 1) break;
|
||||
findGraphicsRect(0., 0., brp.y(), tlp.y());
|
||||
case gaZoomRangeY:
|
||||
if (sr.height() <= 1) break;
|
||||
findGraphicsRect(0., 0., brp.y(), tlp.y());
|
||||
break;
|
||||
default: return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
swapToNormal();
|
||||
@@ -617,7 +613,7 @@ void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) {
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasMouseDoubleClickEvent(QMouseEvent * ) {
|
||||
void Graphic::canvasMouseDoubleClickEvent(QMouseEvent *) {
|
||||
if (!navigation) return;
|
||||
autofit();
|
||||
}
|
||||
@@ -641,11 +637,15 @@ void Graphic::canvasWheelEvent(QWheelEvent * e) {
|
||||
|
||||
|
||||
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;
|
||||
px = px / wid * selrect.width() + selrect.x();
|
||||
py = py / hei * selrect.height() + selrect.y();
|
||||
selrect.setRect(px - (px - selrect.x()) * factor, py - (py - selrect.y()) * factor, selrect.width() * factor, selrect.height() * factor);
|
||||
selrect.setRect(px - (px - selrect.x()) * factor,
|
||||
py - (py - selrect.y()) * factor,
|
||||
selrect.width() * factor,
|
||||
selrect.height() * factor);
|
||||
isFit = false;
|
||||
update(true);
|
||||
setRectToLines();
|
||||
@@ -653,12 +653,14 @@ void Graphic::zoom(float factor) {
|
||||
|
||||
|
||||
void Graphic::fullscreen() {
|
||||
if (fullscr) leaveFullscreen();
|
||||
else enterFullscreen();
|
||||
if (fullscr)
|
||||
leaveFullscreen();
|
||||
else
|
||||
enterFullscreen();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasLeaveEvent(QEvent * ) {
|
||||
void Graphic::canvasLeaveEvent(QEvent *) {
|
||||
isHover = false;
|
||||
if (guides) update(true);
|
||||
ui->status->setText(tr("Cursor") + ": ( ; )");
|
||||
@@ -668,8 +670,8 @@ void Graphic::canvasLeaveEvent(QEvent * ) {
|
||||
|
||||
void Graphic::canvasKeyPressEvent(QKeyEvent * e) {
|
||||
switch (e->key()) {
|
||||
case Qt::Key_Escape: leaveFullscreen();
|
||||
default: break;
|
||||
case Qt::Key_Escape: leaveFullscreen();
|
||||
default: break;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -680,7 +682,7 @@ void Graphic::clear() {
|
||||
graphics[i].polyline_pause.clear();
|
||||
graphics[i]._lod.clear();
|
||||
graphics[i]._lod_pause.clear();
|
||||
graphics[i].max_x = 0.;
|
||||
graphics[i].max_x = 0.;
|
||||
graphics[i].cvrect = QRectF();
|
||||
}
|
||||
if (isFit) on_graphic_buttonAutofit_clicked();
|
||||
@@ -725,8 +727,8 @@ void Graphic::setHistorySize(double val) {
|
||||
QPolygonF & pol(graphics[i].polyline);
|
||||
if (pol.isEmpty() || history <= 0.) continue;
|
||||
graphics[i].cvrect = QRectF();
|
||||
x = pol.back().x() - history;
|
||||
for (int j = pol.size() - 2; j >= 0 ; --j)
|
||||
x = pol.back().x() - history;
|
||||
for (int j = pol.size() - 2; j >= 0; --j)
|
||||
if (pol[j].x() < x) {
|
||||
pol.erase(pol.begin(), pol.begin() + j);
|
||||
break;
|
||||
@@ -813,8 +815,8 @@ void Graphic::setButtons(Graphic::Buttons b) {
|
||||
ui->graphic_buttonClose->setVisible(b.testFlag(Close));
|
||||
ui->graphic_checkPause->setVisible(b.testFlag(Pause));
|
||||
ui->graphic_buttonRecord->setVisible(b.testFlag(Record));
|
||||
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())
|
||||
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->verticalSpacer->changeSize(0, 30, QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
else
|
||||
ui->verticalSpacer->changeSize(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
@@ -830,13 +832,13 @@ void Graphic::setButtonsPosition(Graphic::Alignment a) {
|
||||
return;
|
||||
#endif
|
||||
switch (a) {
|
||||
case Graphic::Left:
|
||||
ui->widgetLeft->setLayout(ui->layoutButtons);
|
||||
ui->widgetLeft->show();
|
||||
case Graphic::Left:
|
||||
ui->widgetLeft->setLayout(ui->layoutButtons);
|
||||
ui->widgetLeft->show();
|
||||
break;
|
||||
case Graphic::Right:
|
||||
ui->widgetRight->setLayout(ui->layoutButtons);
|
||||
ui->widgetRight->show();
|
||||
case Graphic::Right:
|
||||
ui->widgetRight->setLayout(ui->layoutButtons);
|
||||
ui->widgetRight->show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -862,7 +864,7 @@ void Graphic::addPoints(const QPolygonF & pts, int graphic, bool update_) {
|
||||
if (graphic >= graphics.size() || graphic < 0 || pts.isEmpty()) return;
|
||||
GraphicType & t(graphics[graphic]);
|
||||
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.bottom() > p.y()) t.cvrect.setBottom(p.y());
|
||||
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();
|
||||
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;
|
||||
tick(graphic, true, update_);
|
||||
}
|
||||
@@ -881,7 +884,8 @@ void Graphic::addPoints(const QVector<double> & pts, int graphic, bool update_)
|
||||
ps.reserve(pts.size());
|
||||
double stx = 0;
|
||||
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_);
|
||||
}
|
||||
|
||||
@@ -899,13 +903,17 @@ void Graphic::setGraphicData(const QVector<QPointF> & g, int graphic, bool updat
|
||||
}
|
||||
t.max_x = t.polyline[0].x();
|
||||
for (int i = 1; i < t.polyline.size(); ++i)
|
||||
if (t.max_x < t.polyline[i].x())
|
||||
t.max_x = t.polyline[i].x();
|
||||
if (t.max_x < t.polyline[i].x()) t.max_x = t.polyline[i].x();
|
||||
tick(graphic, false, update_);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGraphicProperties(int graphic, const QString & name, const QColor& color, Qt::PenStyle style, double width, bool visible) {
|
||||
void Graphic::setGraphicProperties(int graphic,
|
||||
const QString & name,
|
||||
const QColor & color,
|
||||
Qt::PenStyle style,
|
||||
double width,
|
||||
bool visible) {
|
||||
if (graphic < 0 || graphic >= graphics.size()) return;
|
||||
graphics[graphic].name = name;
|
||||
graphics[graphic].pen.setColor(color);
|
||||
@@ -924,7 +932,7 @@ void Graphic::addGraphic(const QString & name, const QColor & color, Qt::PenStyl
|
||||
|
||||
void Graphic::setVisualRect(const QRectF & rect) {
|
||||
selrect = rect;
|
||||
isFit = false;
|
||||
isFit = false;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -962,7 +970,7 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
|
||||
}
|
||||
ts << "\n";
|
||||
bool has_data = true;
|
||||
int ind = 0;
|
||||
int ind = 0;
|
||||
QString line;
|
||||
while (has_data) {
|
||||
has_data = false;
|
||||
@@ -991,8 +999,7 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
|
||||
}
|
||||
++ind;
|
||||
line += "\n";
|
||||
if (has_data)
|
||||
ts << line;
|
||||
if (has_data) ts << line;
|
||||
}
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
@@ -1000,14 +1007,14 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
|
||||
|
||||
void Graphic::setOpenGL(bool on) {
|
||||
#ifdef HAS_GL
|
||||
isOGL = on;
|
||||
isOGL = on;
|
||||
need_createGL = false;
|
||||
if (on && !m_fakeGL) {
|
||||
if (!canvas_gl) {
|
||||
if (!isVisible())
|
||||
need_createGL = true;
|
||||
else {
|
||||
//qDebug() << "create GL on setter";
|
||||
// qDebug() << "create GL on setter";
|
||||
canvas_gl = new UGLWidget();
|
||||
ui->layoutCanvas->addWidget(canvas_gl);
|
||||
connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent()));
|
||||
@@ -1020,8 +1027,7 @@ void Graphic::setOpenGL(bool on) {
|
||||
canvas = canvas_gl;
|
||||
}
|
||||
} else {
|
||||
if (canvas_gl)
|
||||
canvas_gl->hide();
|
||||
if (canvas_gl) canvas_gl->hide();
|
||||
ui->canvas_raster->show();
|
||||
canvas = ui->canvas_raster;
|
||||
}
|
||||
@@ -1043,7 +1049,9 @@ void Graphic::setGraphicsCount(int arg, bool update) {
|
||||
if (arg < 0) return;
|
||||
while (graphics.size() < arg) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115)));
|
||||
graphics.append(
|
||||
GraphicType(tr("y(x)"),
|
||||
QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115)));
|
||||
#else
|
||||
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115)));
|
||||
#endif
|
||||
@@ -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_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) {
|
||||
double cx, cy, maxX, minX, maxY, minY, vx;
|
||||
bool isRangeX = (start_x != end_x), isRangeY = (start_y != end_y);
|
||||
bool can_fast = (start_x == 0 && end_x == 0 && start_y == 0 && end_y == 0);
|
||||
bool can_fast = (start_x == 0 && end_x == 0 && start_y == 0 && end_y == 0);
|
||||
bool anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY);
|
||||
vx = -DBL_MAX;
|
||||
vx = -DBL_MAX;
|
||||
minY = minX = DBL_MAX;
|
||||
maxY = maxX = -DBL_MAX;
|
||||
foreach (const GraphicType & t, graphics) {
|
||||
foreach(const GraphicType & t, graphics) {
|
||||
if (!t.visible) continue;
|
||||
if (vx < (pause_ ? t.max_x_pause : t.max_x)) vx = (pause_ ? t.max_x_pause : t.max_x);
|
||||
}
|
||||
@@ -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 (minX > maxX) qSwap<double>(minX, maxX);
|
||||
if (minY > maxY) qSwap<double>(minY, maxY);
|
||||
if (qAbs<double>(minX - maxX) < 1E-60) {minX -= defaultRect().width()/2; maxX += defaultRect().width()/2;}
|
||||
if (qAbs<double>(minY - maxY) < 1E-60) {minY -= defaultRect().height()/2; maxY += defaultRect().height()/2;}
|
||||
if (qAbs<double>(minX - maxX) < 1E-60) {
|
||||
minX -= defaultRect().width() / 2;
|
||||
maxX += defaultRect().width() / 2;
|
||||
}
|
||||
if (qAbs<double>(minY - maxY) < 1E-60) {
|
||||
minY -= defaultRect().height() / 2;
|
||||
maxY += defaultRect().height() / 2;
|
||||
}
|
||||
if (only_expand_x) {
|
||||
if (minX > eminx) minX = eminx;
|
||||
if (maxX < emaxx) maxX = emaxx;
|
||||
@@ -1140,16 +1154,20 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
|
||||
if (minY > eminy) minY = eminy;
|
||||
if (maxY < emaxy) maxY = emaxy;
|
||||
}
|
||||
eminx = minX; emaxx = maxX;
|
||||
eminy = minY; emaxy = maxY;
|
||||
if (isRangeX) selrect.setRect(start_x, minY, end_x - start_x, maxY - minY);
|
||||
else if (isRangeY) selrect.setRect(minX, start_y, maxX - minX, end_y - start_y);
|
||||
else grect.setRect(minX, minY, maxX - minX, maxY - minY);
|
||||
eminx = minX;
|
||||
emaxx = maxX;
|
||||
eminy = minY;
|
||||
emaxy = maxY;
|
||||
if (isRangeX)
|
||||
selrect.setRect(start_x, minY, end_x - start_x, maxY - minY);
|
||||
else if (isRangeY)
|
||||
selrect.setRect(minX, start_y, maxX - minX, end_y - start_y);
|
||||
else
|
||||
grect.setRect(minX, minY, maxX - minX, maxY - minY);
|
||||
grect = grect.normalized();
|
||||
if (isFit) {
|
||||
if (visible_time > 0.) {
|
||||
if (grect.width() > visible_time)
|
||||
grect.setLeft(grect.right() - visible_time);
|
||||
if (grect.width() > visible_time) grect.setLeft(grect.right() - visible_time);
|
||||
}
|
||||
selrect = grect;
|
||||
}
|
||||
@@ -1158,28 +1176,29 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
|
||||
|
||||
|
||||
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->setBrush(selbrush);
|
||||
switch (curaction) {
|
||||
case gaZoomInRect: {
|
||||
QSizeF rsz = QRectF(startpos_r, curpos_r).normalized().size();
|
||||
painter->drawRect(QRect(startpos, curpos));
|
||||
fp_size = " x " + pointCoords(QPointF(rsz.width(), rsz.height()));
|
||||
} break;
|
||||
case gaZoomRangeX:
|
||||
painter->drawLine(sx, hei, sx, 0);
|
||||
painter->drawLine(cx, hei, cx, 0);
|
||||
painter->fillRect(sx, 0, cx - sx, hei, selbrush);
|
||||
fp_size = " x " + pointCoords(QPointF(qAbs(startpos_r.x() - curpos_r.x()), 0.), true, false);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
painter->drawLine(gridborder.x(), sy, wid, sy);
|
||||
painter->drawLine(gridborder.x(), cy, wid, cy);
|
||||
painter->fillRect(gridborder.x(), sy, wid - gridborder.x(), cy - sy, selbrush);
|
||||
fp_size = " x " + pointCoords(QPointF(0., qAbs(startpos_r.y() - curpos_r.y())), false, true);
|
||||
break;
|
||||
default: break;
|
||||
case gaZoomInRect: {
|
||||
QSizeF rsz = QRectF(startpos_r, curpos_r).normalized().size();
|
||||
painter->drawRect(QRect(startpos, curpos));
|
||||
fp_size = " x " + pointCoords(QPointF(rsz.width(), rsz.height()));
|
||||
} break;
|
||||
case gaZoomRangeX:
|
||||
painter->drawLine(sx, hei, sx, 0);
|
||||
painter->drawLine(cx, hei, cx, 0);
|
||||
painter->fillRect(sx, 0, cx - sx, hei, selbrush);
|
||||
fp_size = " x " + pointCoords(QPointF(qAbs(startpos_r.x() - curpos_r.x()), 0.), true, false);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
painter->drawLine(gridborder.x(), sy, wid, sy);
|
||||
painter->drawLine(gridborder.x(), cy, wid, cy);
|
||||
painter->fillRect(gridborder.x(), sy, wid - gridborder.x(), cy - sy, selbrush);
|
||||
fp_size = " x " + pointCoords(QPointF(0., qAbs(startpos_r.y() - curpos_r.y())), false, true);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1192,12 +1211,14 @@ void Graphic::drawGrid() {
|
||||
QPair<QString, QString> str;
|
||||
|
||||
range = selrect.bottom() - selrect.top();
|
||||
if (grad_y == Graphic::Auto) step = splitRange(range, hei / gridy / font_sz.height() / 1.4);
|
||||
else step = gridy;
|
||||
if (grad_y == Graphic::Auto)
|
||||
step = splitRange(range, hei / gridy / font_sz.height() / 1.4);
|
||||
else
|
||||
step = gridy;
|
||||
start = roundTo(canvas2realY(-hei), step) - step;
|
||||
py = start + step;
|
||||
cy = 0;
|
||||
cx = gbx - 5;
|
||||
py = start + step;
|
||||
cy = 0;
|
||||
cx = gbx - 5;
|
||||
grid_pen.setWidth(qMax<int>(qMax<int>(qRound(thick / 1.4), 1), grid_pen.width()));
|
||||
#if QT_VERSION_MAJOR >= 5
|
||||
grid_pen.setCosmetic(true);
|
||||
@@ -1257,10 +1278,12 @@ void Graphic::drawGrid() {
|
||||
range = selrect.right() - selrect.left();
|
||||
QString df;
|
||||
if (axis_type_x == Graphic::Numeric) {
|
||||
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
|
||||
else step = gridx;
|
||||
if (grad_x == Graphic::Auto)
|
||||
step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
|
||||
else
|
||||
step = gridx;
|
||||
start = roundTo(canvas2realX(right), step);
|
||||
px = start + step;
|
||||
px = start + step;
|
||||
if (step > 0.) {
|
||||
cnt = 1000;
|
||||
while (cnt-- > 0) {
|
||||
@@ -1300,10 +1323,12 @@ void Graphic::drawGrid() {
|
||||
} else {
|
||||
int dt_add[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;
|
||||
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();
|
||||
if (step > 0.) {
|
||||
int up_y = cy - font_sz.height() * 2;
|
||||
@@ -1312,7 +1337,7 @@ void Graphic::drawGrid() {
|
||||
int ddx = 0, pcx = 0;
|
||||
QDateTime cd = QDateTime::fromMSecsSinceEpoch(canvas2realX(gbx) * grid_numbers_x), cdp, cdc, cdl, cdlp;
|
||||
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) {
|
||||
roundDateTime(cd, dt_add);
|
||||
cdp = cdl = cdlp = cd;
|
||||
@@ -1322,13 +1347,13 @@ void Graphic::drawGrid() {
|
||||
cd.setTime(QTime(0, 0, 0));
|
||||
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 {
|
||||
int x_start, x_end;
|
||||
QDateTime date;
|
||||
};
|
||||
QVector<Anchor> areas_ce, areas_lo;
|
||||
cnt = 1000;
|
||||
cnt = 1000;
|
||||
int area_start = gbx, area_start_lo = gbx;
|
||||
pcx = real2canvasX(cd.toMSecsSinceEpoch() / grid_numbers_x);
|
||||
while (cnt-- > 0) {
|
||||
@@ -1341,16 +1366,16 @@ void Graphic::drawGrid() {
|
||||
if (cx < gbx) continue;
|
||||
if (cdp != cdc) {
|
||||
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;
|
||||
areas_ce << Anchor{area_start, qMin(cxc, right), cdp};
|
||||
area_start = areas_ce.back().x_end;
|
||||
cd = cdl = cdp = cdc;
|
||||
cx = cxc;
|
||||
cx = cxc;
|
||||
roundDateTime(cdl, dt_add_lo);
|
||||
if (cdlp != cdl) {
|
||||
areas_lo << Anchor{area_start_lo, qMin(cxc, right), cdlp};
|
||||
cdlp = cdl;
|
||||
cdlp = cdl;
|
||||
area_start_lo = areas_lo.back().x_end;
|
||||
}
|
||||
} else {
|
||||
@@ -1372,11 +1397,9 @@ void Graphic::drawGrid() {
|
||||
}
|
||||
}
|
||||
if (!is_years) {
|
||||
if (area_start < right)
|
||||
areas_ce << Anchor{area_start, right, cdc};
|
||||
if (area_start_lo < right)
|
||||
areas_lo << Anchor{area_start_lo, right, cdl};
|
||||
//qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date;
|
||||
if (area_start < right) areas_ce << Anchor{area_start, right, cdc};
|
||||
if (area_start_lo < right) areas_lo << Anchor{area_start_lo, right, cdl};
|
||||
// qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date;
|
||||
painter->setPen(grid_pen);
|
||||
for (const auto & a: areas_ce) {
|
||||
painter->drawLine(a.x_start, hei + 5, a.x_start, ce_y);
|
||||
@@ -1389,12 +1412,12 @@ void Graphic::drawGrid() {
|
||||
painter->setFont(nf);
|
||||
auto pfm = painter->fontMetrics();
|
||||
for (const auto & a: areas_ce) {
|
||||
ds = a.date.toString(formats.center);
|
||||
ds = a.date.toString(formats.center);
|
||||
auto str_rect = pfm.boundingRect(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) {
|
||||
ds = a.date.toString(formats.lower);
|
||||
ds = a.date.toString(formats.lower);
|
||||
auto str_rect = pfm.boundingRect(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.;
|
||||
p += 1;
|
||||
}
|
||||
ret.first = QString::fromUtf8("%1·10").arg(v);
|
||||
ret.first = QString::fromUtf8("%1·10").arg(v);
|
||||
ret.second = QString::number(p);
|
||||
} else
|
||||
ret.first = QString::number(v, 'g', 8);
|
||||
@@ -1437,31 +1460,30 @@ QPair<QString, QString> Graphic::gridMark(double v) const {
|
||||
void Graphic::fillDateFormats() {
|
||||
date_formats.clear();
|
||||
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;
|
||||
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.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;
|
||||
};
|
||||
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{"mm '%3'" , "h '%4'" , "yyyy MMM dd(ddd)"});
|
||||
date_formats << trFunc(DateFormats{"h '%4'" , "dd(ddd)" , "yyyy MMM" });
|
||||
date_formats << trFunc(DateFormats{"dd(ddd)" , "MMM" , "yyyy" });
|
||||
date_formats << trFunc(DateFormats{"MMM" , "yyyy" , "" });
|
||||
date_formats << trFunc(DateFormats{"yyyy" , "" , "" });
|
||||
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{"h '%4'", "dd(ddd)", "yyyy MMM"});
|
||||
date_formats << trFunc(DateFormats{"dd(ddd)", "MMM", "yyyy"});
|
||||
date_formats << trFunc(DateFormats{"MMM", "yyyy", ""});
|
||||
date_formats << trFunc(DateFormats{"yyyy", "", ""});
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawGraphics() {
|
||||
if (isHover)
|
||||
ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
|
||||
if (isHover) ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
|
||||
QPointF srp = -selrect.topLeft();
|
||||
double sclx, scly, wid = canvas->width(), hei = canvas->height();
|
||||
int cwid = (wid - gridborder.x() - margins_.left() - margins_.width());
|
||||
sclx = cwid / selrect.width();
|
||||
scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height();
|
||||
sclx = cwid / selrect.width();
|
||||
scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height();
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
painter->translate(gridborder.x() + margins_.left(), hei - gridborder.y() - margins_.top());
|
||||
@@ -1478,23 +1500,23 @@ void Graphic::drawGraphics() {
|
||||
QVector<QPolygonF> & src_lod(pause_ ? t._lod_pause : t._lod);
|
||||
int lod = 0;
|
||||
if (m_LODOptimization) {
|
||||
int gpcnt = src_pol.size();
|
||||
int gpcnt = src_pol.size();
|
||||
qreal range = src_pol.back().x() - src_pol.front().x();
|
||||
qreal ppp = (gpcnt * selrect.width() / qMax(range, 1.E-9) / cwid);
|
||||
lod = qBound<int>(0, qFloor(log2(ppp) - 1), src_lod.size());
|
||||
//qDebug() << "draw lod" << lod << src_lod[lod - 1].size();
|
||||
qreal ppp = (gpcnt * selrect.width() / qMax(range, 1.E-9) / cwid);
|
||||
lod = qBound<int>(0, qFloor(log2(ppp) - 1), src_lod.size());
|
||||
// qDebug() << "draw lod" << lod << src_lod[lod - 1].size();
|
||||
}
|
||||
t.last_lod = lod;
|
||||
QPolygonF & rpol(lod == 0 ? src_pol : src_lod[lod - 1]);
|
||||
int ind_start = -1, ind_end = -1;
|
||||
if (m_LODOptimization) {
|
||||
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) {
|
||||
qreal px = rpol[i].x();
|
||||
if (px < xs) continue;
|
||||
if (ind_start < 0)
|
||||
ind_start = qMax(0, i - 1);
|
||||
if (ind_start < 0) ind_start = qMax(0, i - 1);
|
||||
if (px > xe && ind_end < 0) {
|
||||
ind_end = qMin(rpol.size(), i + 1);
|
||||
break;
|
||||
@@ -1502,10 +1524,10 @@ void Graphic::drawGraphics() {
|
||||
}
|
||||
if (ind_start < 0) ind_start = 0;
|
||||
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 {
|
||||
ind_start = 0;
|
||||
ind_end = rpol.size();
|
||||
ind_end = rpol.size();
|
||||
}
|
||||
int polsize = ind_end - ind_start;
|
||||
if (polsize > 0) {
|
||||
@@ -1513,13 +1535,15 @@ void Graphic::drawGraphics() {
|
||||
if (m_LODOptimization && polsize < rpol.size()) {
|
||||
cpol.resize(polsize);
|
||||
memcpy(cpol.data(), &(rpol[ind_start]), polsize * sizeof(QPointF));
|
||||
//qDebug() << "copy" << polsize;
|
||||
// qDebug() << "copy" << polsize;
|
||||
} else {
|
||||
cpol = rpol;
|
||||
}
|
||||
pen = t.pen;
|
||||
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick);
|
||||
else pen.setWidthF(pen.widthF()*thick);
|
||||
if (qRound(pen.widthF()) == pen.widthF())
|
||||
pen.setWidth(pen.width() * thick);
|
||||
else
|
||||
pen.setWidthF(pen.widthF() * thick);
|
||||
pen.setCosmetic(true);
|
||||
if (t.lines) {
|
||||
painter->setPen(pen);
|
||||
@@ -1530,8 +1554,10 @@ void Graphic::drawGraphics() {
|
||||
painter->drawPolyline(mat.map(cpol));
|
||||
}
|
||||
if (t.points) {
|
||||
if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick));
|
||||
else pen.setWidthF(t.pointWidth*thick);
|
||||
if (qRound(t.pointWidth) == t.pointWidth)
|
||||
pen.setWidth(qRound(t.pointWidth * thick));
|
||||
else
|
||||
pen.setWidthF(t.pointWidth * thick);
|
||||
painter->setPen(pen);
|
||||
painter->drawPoints(mat.map(cpol));
|
||||
}
|
||||
@@ -1549,9 +1575,9 @@ QString Graphic::pointCoords(QPointF point, bool x, bool y) {
|
||||
else
|
||||
ret +=
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
QDateTime::fromMSecsSinceEpoch(point.x()).toString(Qt::SystemLocaleShortDate);
|
||||
QDateTime::fromMSecsSinceEpoch(point.x()).toString(Qt::SystemLocaleShortDate);
|
||||
#else
|
||||
locale().toString(QDateTime::fromMSecsSinceEpoch(point.x()), QLocale::ShortFormat);
|
||||
locale().toString(QDateTime::fromMSecsSinceEpoch(point.x()), QLocale::ShortFormat);
|
||||
#endif
|
||||
}
|
||||
if (y) {
|
||||
@@ -1575,11 +1601,11 @@ void Graphic::drawGuides() {
|
||||
painter->resetTransform();
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
QPoint apos = curpos;
|
||||
QPoint apos = curpos;
|
||||
QPointF rpos = canvas2real(apos);
|
||||
QString str;
|
||||
str = pointCoords(rpos) + fp_size;
|
||||
bool trace_found = false;
|
||||
str = pointCoords(rpos) + fp_size;
|
||||
bool trace_found = false;
|
||||
auto trace_axis_func = [&](bool on_x, double cursor) {
|
||||
if (curTrace >= 0 && curTrace < graphics.size()) {
|
||||
auto & t(graphics[curTrace]);
|
||||
@@ -1594,13 +1620,13 @@ void Graphic::drawGuides() {
|
||||
dist = qAbs<double>((on_x ? pol[i].x() : pol[i].y()) - cursor);
|
||||
if (min_dist > dist || min_dist < 0) {
|
||||
min_dist = dist;
|
||||
index = i;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
if (index >= 0) {
|
||||
rpos = pol[index];
|
||||
apos = real2canvas(rpos).toPoint();
|
||||
str = pointCoords(pol[index]) + fp_size;
|
||||
rpos = pol[index];
|
||||
apos = real2canvas(rpos).toPoint();
|
||||
str = pointCoords(pol[index]) + fp_size;
|
||||
trace_found = true;
|
||||
emit graphicTraceEvent(curTrace, rpos);
|
||||
}
|
||||
@@ -1610,7 +1636,7 @@ void Graphic::drawGuides() {
|
||||
auto trace_free_func = [&](QPointF cursor) {
|
||||
double min_dist = -1;
|
||||
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) {
|
||||
auto & t(graphics[g]);
|
||||
if (t.visible) {
|
||||
@@ -1627,34 +1653,27 @@ void Graphic::drawGuides() {
|
||||
dist = QVector2D(dp).lengthSquared();
|
||||
if (min_dist > dist || min_dist < 0) {
|
||||
min_dist = dist;
|
||||
gr = g;
|
||||
rpos = point;
|
||||
gr = g;
|
||||
rpos = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gr >= 0) {
|
||||
apos = real2canvas(rpos).toPoint();
|
||||
str = " " + graphics[gr].name + ": " + pointCoords(rpos) + fp_size;
|
||||
apos = real2canvas(rpos).toPoint();
|
||||
str = " " + graphics[gr].name + ": " + pointCoords(rpos) + fp_size;
|
||||
trace_found = true;
|
||||
emit graphicTraceEvent(gr, rpos);
|
||||
}
|
||||
};
|
||||
switch (floating_axis_type) {
|
||||
case TraceXY:
|
||||
trace_free_func(rpos);
|
||||
break;
|
||||
case TraceX:
|
||||
trace_axis_func(true, rpos.x());
|
||||
break;
|
||||
case TraceY:
|
||||
trace_axis_func(false, rpos.y());
|
||||
break;
|
||||
case TraceXY: trace_free_func(rpos); break;
|
||||
case TraceX: trace_axis_func(true, rpos.x()); break;
|
||||
case TraceY: trace_axis_func(false, rpos.y()); break;
|
||||
default: break;
|
||||
}
|
||||
if (was_trace && !trace_found)
|
||||
emit graphicTraceEvent(-1, QPointF());
|
||||
if (was_trace && !trace_found) emit graphicTraceEvent(-1, QPointF());
|
||||
was_trace = trace_found;
|
||||
painter->drawLine(0, apos.y(), wid, apos.y());
|
||||
painter->drawLine(apos.x(), 0, apos.x(), hei);
|
||||
@@ -1678,7 +1697,7 @@ void Graphic::drawPause() {
|
||||
painter->resetTransform();
|
||||
painter->translate(canvas->width() - icon_pause_b.width() - 6, 6);
|
||||
double o = (0.5 - pause_phase) * 2;
|
||||
painter->setOpacity(o*o);
|
||||
painter->setOpacity(o * o);
|
||||
painter->drawImage(0, 0, icon_pause_b);
|
||||
painter->setOpacity(1.);
|
||||
painter->drawImage(0, 0, icon_pause_f);
|
||||
@@ -1689,11 +1708,11 @@ void Graphic::drawPause() {
|
||||
double roundToSteps(double value, const QVector<double> & steps) {
|
||||
double ret = value, min_err = -1.;
|
||||
for (double v: steps) {
|
||||
double sv = qRound64(value / v) * v;
|
||||
double sv = qRound64(value / v) * v;
|
||||
double err = qAbs<double>(value - sv);
|
||||
if (min_err < 0 || min_err > err) {
|
||||
min_err = err;
|
||||
ret = sv;
|
||||
ret = sv;
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (min_err < 0 || min_err > err) {
|
||||
min_err = err;
|
||||
ret = v;
|
||||
ret = v;
|
||||
}
|
||||
}
|
||||
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 digits, step, tln;
|
||||
range = qAbs<double>(range);
|
||||
tln = qFloor(qLn(range) / LN10);
|
||||
tln = qFloor(qLn(range) / LN10);
|
||||
for (int i = 0; i <= 5; ++i) {
|
||||
digits = qPow(10., tln - i);
|
||||
step = qRound(range / count / digits);
|
||||
step = qRound(range / count / digits);
|
||||
if (step > 0.) {
|
||||
digits = qPow(10., tln - i - 1);
|
||||
step = qRound(range / count / digits);
|
||||
step = qRound(range / count / digits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1733,22 +1752,32 @@ double Graphic::splitRange(double range, int count) {
|
||||
|
||||
|
||||
double Graphic::splitRangeDate(double range, int count, DateFormats & formats, int step[7]) {
|
||||
static const qint64
|
||||
to_sec = 1000LL,
|
||||
to_min = 1000LL * 60,
|
||||
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);
|
||||
static const qint64 to_sec = 1000LL, to_min = 1000LL * 60, 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;
|
||||
if (ret < to_sec / 1 ) {format_index = DateMSecs ; step[DateMSecs ] = qRound64(ret);}
|
||||
else if (ret < to_min / 2 ) {format_index = DateSecs ; step[DateSecs ] = roundToNearest(ret / to_sec , {1, 2, 5, 10, 15, 20, 30});}
|
||||
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);}
|
||||
if (ret < to_sec / 1) {
|
||||
format_index = DateMSecs;
|
||||
step[DateMSecs] = qRound64(ret);
|
||||
} else if (ret < to_min / 2) {
|
||||
format_index = DateSecs;
|
||||
step[DateSecs] = roundToNearest(ret / to_sec, {1, 2, 5, 10, 15, 20, 30});
|
||||
} 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];
|
||||
return ret;
|
||||
}
|
||||
@@ -1761,25 +1790,35 @@ double Graphic::roundTo(double value, double round_to) {
|
||||
|
||||
|
||||
void Graphic::roundDateTime(QDateTime & dt, int * c) {
|
||||
QDate d(dt.date()); QTime t(dt.time());
|
||||
if (c[DateMSecs ] != 0) t.setHMS(t.hour(), t.minute(), t.second());
|
||||
if (c[DateSecs ] != 0) t.setHMS(t.hour(), t.minute(), 0);
|
||||
QDate d(dt.date());
|
||||
QTime t(dt.time());
|
||||
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[DateHours ] != 0) {t.setHMS(0, 0, 0); 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);}
|
||||
if (c[DateHours] != 0) {
|
||||
t.setHMS(0, 0, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::addDateTime(QDateTime & dt, int * c, qint64 mul) {
|
||||
if (c[DateMSecs ] != 0) dt = dt.addMSecs (mul * c[DateMSecs ]);
|
||||
if (c[DateSecs ] != 0) dt = dt.addSecs (mul * c[DateSecs ]);
|
||||
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[DateDays ] != 0) dt = dt.addDays (mul * c[DateDays ]);
|
||||
if (c[DateMonths ] != 0) dt = dt.addMonths(mul * c[DateMonths ]);
|
||||
if (c[DateYears ] != 0) dt = dt.addYears (mul * c[DateYears ]);
|
||||
if (c[DateMSecs] != 0) dt = dt.addMSecs(mul * c[DateMSecs]);
|
||||
if (c[DateSecs] != 0) dt = dt.addSecs(mul * c[DateSecs]);
|
||||
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[DateDays] != 0) dt = dt.addDays(mul * c[DateDays]);
|
||||
if (c[DateMonths] != 0) dt = dt.addMonths(mul * c[DateMonths]);
|
||||
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 ret;
|
||||
for (int i=0; i<real_polygon.size(); ++i)
|
||||
for (int i = 0; i < real_polygon.size(); ++i)
|
||||
ret << real2canvas(real_polygon[i]);
|
||||
return ret;
|
||||
}
|
||||
@@ -1821,7 +1860,7 @@ QPolygonF Graphic::real2canvas(const QPolygonF & real_polygon) const {
|
||||
|
||||
QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
|
||||
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]);
|
||||
return ret;
|
||||
}
|
||||
@@ -1830,21 +1869,11 @@ QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
|
||||
void Graphic::setCurrentAction(GraphicAction action) {
|
||||
curaction = action;
|
||||
switch (action) {
|
||||
case gaNone:
|
||||
setGuidesCursor();
|
||||
break;
|
||||
case gaZoomInRect:
|
||||
setCanvasCursor(Qt::CrossCursor);
|
||||
break;
|
||||
case gaZoomRangeX:
|
||||
setCanvasCursor(Qt::SplitHCursor);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
setCanvasCursor(Qt::SplitVCursor);
|
||||
break;
|
||||
case gaMove:
|
||||
setCanvasCursor(Qt::SizeAllCursor);
|
||||
break;
|
||||
case gaNone: setGuidesCursor(); break;
|
||||
case gaZoomInRect: setCanvasCursor(Qt::CrossCursor); break;
|
||||
case gaZoomRangeX: setCanvasCursor(Qt::SplitHCursor); break;
|
||||
case gaZoomRangeY: setCanvasCursor(Qt::SplitVCursor); break;
|
||||
case gaMove: setCanvasCursor(Qt::SizeAllCursor); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1852,8 +1881,7 @@ void Graphic::setCurrentAction(GraphicAction action) {
|
||||
void Graphic::setCanvasCursor(QCursor cursor) {
|
||||
ui->canvas_raster->setCursor(cursor);
|
||||
#ifdef HAS_GL
|
||||
if (canvas_gl)
|
||||
canvas_gl->setCursor(cursor);
|
||||
if (canvas_gl) canvas_gl->setCursor(cursor);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1883,28 +1911,42 @@ void Graphic::swapToBuffer() {
|
||||
void Graphic::setRectToLines() {
|
||||
is_lines_update = true;
|
||||
if (line_x_min.isVisible() && line_x_max.isVisible() && line_y_min.isVisible() && line_y_max.isVisible()) {
|
||||
line_x_min.blockSignals(true); line_x_max.blockSignals(true); line_y_min.blockSignals(true); line_y_max.blockSignals(true);
|
||||
line_x_min.blockSignals(true);
|
||||
line_x_max.blockSignals(true);
|
||||
line_y_min.blockSignals(true);
|
||||
line_y_max.blockSignals(true);
|
||||
if (!line_x_min.hasFocus()) {
|
||||
if (isFit) line_x_min.setValue(grect.left());
|
||||
else line_x_min.setValue(selrect.left());
|
||||
if (isFit)
|
||||
line_x_min.setValue(grect.left());
|
||||
else
|
||||
line_x_min.setValue(selrect.left());
|
||||
}
|
||||
if (!line_x_max.hasFocus()) {
|
||||
if(isFit) line_x_max.setValue(grect.right());
|
||||
else line_x_max.setValue(selrect.right());
|
||||
if (isFit)
|
||||
line_x_max.setValue(grect.right());
|
||||
else
|
||||
line_x_max.setValue(selrect.right());
|
||||
}
|
||||
if (!line_y_min.hasFocus()) {
|
||||
if(isFit) line_y_min.setValue(grect.bottom());
|
||||
else line_y_min.setValue(selrect.bottom());
|
||||
if (isFit)
|
||||
line_y_min.setValue(grect.bottom());
|
||||
else
|
||||
line_y_min.setValue(selrect.bottom());
|
||||
}
|
||||
if (!line_y_max.hasFocus()) {
|
||||
if(isFit) line_y_max.setValue(grect.top());
|
||||
else line_y_max.setValue(selrect.top());
|
||||
if (isFit)
|
||||
line_y_max.setValue(grect.top());
|
||||
else
|
||||
line_y_max.setValue(selrect.top());
|
||||
}
|
||||
line_x_min.setDefaultText(QString::number(grect.left()).toUpper());
|
||||
line_x_max.setDefaultText(QString::number(grect.right()).toUpper());
|
||||
line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper());
|
||||
line_y_max.setDefaultText(QString::number(grect.top()).toUpper());
|
||||
line_x_min.blockSignals(false); line_x_max.blockSignals(false); line_y_min.blockSignals(false); line_y_max.blockSignals(false);
|
||||
line_x_min.blockSignals(false);
|
||||
line_x_max.blockSignals(false);
|
||||
line_y_min.blockSignals(false);
|
||||
line_y_max.blockSignals(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, ...)
|
||||
if (!t.cvrect.isNull()) {
|
||||
QPointF fp(t.polyline.first());
|
||||
if (qFuzzyCompare(t.cvrect.left(), fp.x()) ||
|
||||
qFuzzyCompare(t.cvrect.right(), fp.x()) ||
|
||||
qFuzzyCompare(t.cvrect.top(), fp.y()) ||
|
||||
qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
|
||||
if (qFuzzyCompare(t.cvrect.left(), fp.x()) || qFuzzyCompare(t.cvrect.right(), fp.x()) ||
|
||||
qFuzzyCompare(t.cvrect.top(), fp.y()) || qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
|
||||
t.cvrect = QRectF();
|
||||
}
|
||||
}
|
||||
@@ -1955,48 +1995,51 @@ void Graphic::calcLOD(int index) {
|
||||
GraphicType & t(graphics[index]);
|
||||
t._lod.clear();
|
||||
int pcnt = t.polyline.size();
|
||||
//qDebug() << "calcLOD" << index;
|
||||
// qDebug() << "calcLOD" << index;
|
||||
while (pcnt >= 10) {
|
||||
QPolygonF & pl(t._lod.isEmpty() ? t.polyline : t._lod.back());
|
||||
t._lod.append(QPolygonF());
|
||||
QPolygonF & cl(t._lod.back());
|
||||
cl << pl.front();
|
||||
int qcnt = (pl.size() + 1) / 4;
|
||||
pcnt = qcnt * 2 + 2;
|
||||
int pc = 4;
|
||||
int qcnt = (pl.size() + 1) / 4;
|
||||
pcnt = qcnt * 2 + 2;
|
||||
int pc = 4;
|
||||
qreal mx[2] = {0., 0.}, my[2] = {0., 0.}, my_x[2] = {0., 0.}, px, py;
|
||||
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;
|
||||
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) {
|
||||
px = pl[j + k].x(); py = pl[j + k].y();
|
||||
mx[0] = qMin(mx[0], px); mx[1] = qMax(mx[1], px);
|
||||
px = pl[j + k].x();
|
||||
py = pl[j + k].y();
|
||||
mx[0] = qMin(mx[0], px);
|
||||
mx[1] = qMax(mx[1], px);
|
||||
if (my[0] > py) {
|
||||
my[0] = py;
|
||||
my[0] = py;
|
||||
my_x[0] = px;
|
||||
}
|
||||
if (my[1] < py) {
|
||||
my[1] = py;
|
||||
my[1] = py;
|
||||
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])
|
||||
cl << QPointF(cx - dx, my[0]) << QPointF(cx + dx, my[1]);
|
||||
else
|
||||
cl << QPointF(cx - dx, my[1]) << QPointF(cx + dx, my[0]);
|
||||
}
|
||||
cl << pl.back();
|
||||
//qDebug() << "lod" << t._lod.size() << "->" << cl.size();
|
||||
// qDebug() << "lod" << t._lod.size() << "->" << cl.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_graphic_buttonAutofit_clicked() {
|
||||
isFit = true;
|
||||
isFit = true;
|
||||
bool isEmpty = true;
|
||||
foreach (const GraphicType & t, graphics) {
|
||||
foreach(const GraphicType & t, graphics) {
|
||||
const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline);
|
||||
if (!pol.isEmpty()) {
|
||||
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());
|
||||
back_color = conf->ui->colorBackground->color();
|
||||
text_color = conf->ui->colorText->color();
|
||||
grad_x = conf->ui->checkGridAutoX->isChecked() ? Auto : Fixed;
|
||||
grad_y = conf->ui->checkGridAutoY->isChecked() ? Auto : Fixed;
|
||||
gridx = conf->ui->spinGridStepX->value();
|
||||
gridy = conf->ui->spinGridStepY->value();
|
||||
grad_x = conf->ui->checkGridAutoX->isChecked() ? Auto : Fixed;
|
||||
grad_y = conf->ui->checkGridAutoY->isChecked() ? Auto : Fixed;
|
||||
gridx = conf->ui->spinGridStepX->value();
|
||||
gridy = conf->ui->spinGridStepY->value();
|
||||
setOpenGL(conf->ui->checkOGL->isChecked());
|
||||
setAntialiasing(conf->ui->checkAAlias->isChecked());
|
||||
setBorderInputsVisible(conf->ui->checkInputs->isChecked());
|
||||
setStatusVisible(conf->ui->checkStatus->isChecked());
|
||||
setLegendVisible(conf->ui->checkLegend->isChecked());
|
||||
setMargins(conf->ui->spinMarginL->value(), conf->ui->spinMarginR->value(), conf->ui->spinMarginT->value(), conf->ui->spinMarginB->value());
|
||||
setMargins(conf->ui->spinMarginL->value(),
|
||||
conf->ui->spinMarginR->value(),
|
||||
conf->ui->spinMarginT->value(),
|
||||
conf->ui->spinMarginB->value());
|
||||
updateLegend();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
saveImage(f);
|
||||
}
|
||||
@@ -2072,7 +2121,8 @@ void Graphic::on_graphic_buttonExport_clicked() {
|
||||
QString f = QFileDialog::getSaveFileName(this, tr("Export graphics"), ppath, "CSV(*.csv)");
|
||||
if (f.isEmpty()) return;
|
||||
QStringList items;
|
||||
items << "." << ",";
|
||||
items << "."
|
||||
<< ",";
|
||||
bool 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());
|
||||
@@ -2092,15 +2142,17 @@ void Graphic::on_graphic_buttonRecord_clicked(bool checked) {
|
||||
qApp->setOverrideCursor(Qt::BusyCursor);
|
||||
GifWriter gif_writer;
|
||||
int frame_delay = 10;
|
||||
if (GifBegin(&gif_writer, f.toUtf8(), static_cast<uint32_t>(record_imgs.first().width()),
|
||||
static_cast<uint32_t>(record_imgs.first().height()),
|
||||
static_cast<uint32_t>(frame_delay))) {
|
||||
for (const QImage & im : record_imgs) {
|
||||
if (GifBegin(&gif_writer,
|
||||
f.toUtf8(),
|
||||
static_cast<uint32_t>(record_imgs.first().width()),
|
||||
static_cast<uint32_t>(record_imgs.first().height()),
|
||||
static_cast<uint32_t>(frame_delay))) {
|
||||
for (const QImage & im: record_imgs) {
|
||||
if (!GifWriteFrame(&gif_writer,
|
||||
im.convertToFormat(QImage::Format_RGBA8888).constBits(),
|
||||
static_cast<uint32_t>(im.width()),
|
||||
static_cast<uint32_t>(im.height()),
|
||||
static_cast<uint32_t>(frame_delay))) {
|
||||
im.convertToFormat(QImage::Format_RGBA8888).constBits(),
|
||||
static_cast<uint32_t>(im.width()),
|
||||
static_cast<uint32_t>(im.height()),
|
||||
static_cast<uint32_t>(frame_delay))) {
|
||||
GifEnd(&gif_writer);
|
||||
qDebug() << "GifWriteFrame ERROR";
|
||||
}
|
||||
@@ -2127,8 +2179,10 @@ void Graphic::updateLegend(bool es) {
|
||||
pix.fill(back_color);
|
||||
QPainter p(&pix);
|
||||
QPen pen = graphics[i].pen;
|
||||
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick);
|
||||
else pen.setWidthF(pen.widthF()*thick);
|
||||
if (qRound(pen.widthF()) == pen.widthF())
|
||||
pen.setWidth(pen.width() * thick);
|
||||
else
|
||||
pen.setWidthF(pen.widthF() * thick);
|
||||
p.setPen(pen);
|
||||
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
|
||||
p.end();
|
||||
@@ -2139,7 +2193,7 @@ void Graphic::updateLegend(bool es) {
|
||||
return;
|
||||
}
|
||||
leg_update = false;
|
||||
int ps = 100;
|
||||
int ps = 100;
|
||||
for (int r = 0; r < ui->layoutLegend->rowCount(); ++r)
|
||||
for (int c = 0; c < ui->layoutLegend->columnCount(); ++c) {
|
||||
QLayoutItem * li = ui->layoutLegend->itemAtPosition(r, c);
|
||||
@@ -2167,33 +2221,36 @@ void Graphic::updateLegend(bool es) {
|
||||
if (cps > ps) ps = cps;
|
||||
}
|
||||
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;
|
||||
bool lv = ui->scrollLegend->isVisibleTo(this);
|
||||
ui->scrollLegend->hide();
|
||||
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;
|
||||
check->show();
|
||||
if (leg_sa->minimum_hei == 0) {
|
||||
leg_sa->minimum_hei = ui->widgetLegend->sizeHint().height();
|
||||
/*#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
QTimer::singleShot(0, this, [this,leg_sa,check](){
|
||||
leg_sa->minimum_hei = check->sizeHint().height();
|
||||
leg_sa->updateGeometry();
|
||||
qDebug() << leg_sa->minimum_hei << ui->widgetLegend->sizeHint();
|
||||
});
|
||||
#else
|
||||
leg_sa->minimum_hei = check->sizeHint().height();
|
||||
#endif*/
|
||||
/*#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
QTimer::singleShot(0, this, [this,leg_sa,check](){
|
||||
leg_sa->minimum_hei = check->sizeHint().height();
|
||||
leg_sa->updateGeometry();
|
||||
qDebug() << leg_sa->minimum_hei << ui->widgetLegend->sizeHint();
|
||||
});
|
||||
#else
|
||||
leg_sa->minimum_hei = check->sizeHint().height();
|
||||
#endif*/
|
||||
}
|
||||
col++;
|
||||
if (col > maxcol) {col = 0; row++;}
|
||||
if (col > maxcol) {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
ui->gridLayout->invalidate();
|
||||
ui->scrollLegend->setVisible(lv);
|
||||
leg_sa->updateGeometry();
|
||||
//ui->gridLayout->invalidate();
|
||||
// ui->gridLayout->invalidate();
|
||||
leg_update = true;
|
||||
if (es) emit graphicSettingsChanged();
|
||||
}
|
||||
@@ -2212,24 +2269,30 @@ void Graphic::updateLegendChecks() {
|
||||
|
||||
void Graphic::graphicVisibleChange(bool checked) {
|
||||
if (visible_update) return;
|
||||
QCheckBox * cb = qobject_cast<QCheckBox*>(sender());
|
||||
int i = cb->property("graphic_num").toInt();
|
||||
QCheckBox * cb = qobject_cast<QCheckBox *>(sender());
|
||||
int i = cb->property("graphic_num").toInt();
|
||||
graphics[i].visible = checked;
|
||||
if (isFit) on_graphic_buttonAutofit_clicked();
|
||||
else {update();}
|
||||
if (isFit)
|
||||
on_graphic_buttonAutofit_clicked();
|
||||
else {
|
||||
update();
|
||||
}
|
||||
emit graphicSettingsChanged();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::graphicAllVisibleChange(bool checked) {
|
||||
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].pb->setChecked(checked);
|
||||
}
|
||||
visible_update = false;
|
||||
if (isFit) on_graphic_buttonAutofit_clicked();
|
||||
else {update();}
|
||||
if (isFit)
|
||||
on_graphic_buttonAutofit_clicked();
|
||||
else {
|
||||
update();
|
||||
}
|
||||
emit graphicSettingsChanged();
|
||||
}
|
||||
|
||||
@@ -2319,23 +2382,22 @@ bool Graphic::legendVisible() const {
|
||||
|
||||
|
||||
QByteArray Graphic::save() {
|
||||
// QByteArray ba;
|
||||
// QDataStream s(&ba, QIODevice::ReadWrite);
|
||||
// s << openGL() << antialiasing() << borderInputsVisible() << statusVisible() << legendVisible();
|
||||
// s << graphics;
|
||||
// return ba;
|
||||
// QByteArray ba;
|
||||
// QDataStream s(&ba, QIODevice::ReadWrite);
|
||||
// s << openGL() << antialiasing() << borderInputsVisible() << statusVisible() << legendVisible();
|
||||
// s << graphics;
|
||||
// return ba;
|
||||
|
||||
// version '2':
|
||||
// version '2':
|
||||
ChunkStream cs;
|
||||
cs.add(1, antialiasing()).add(2, openGL()).add(3, borderInputsVisible()).add(4, statusVisible()).add(5, legendVisible());
|
||||
cs.add(6, backgroundColor()).add(7, textColor()).add(8, margins());
|
||||
cs.add(9, gridPen()).add(10, graduationX()).add(11, graduationY()).add(12, graduationStepX()).add(13, graduationStepY());
|
||||
cs.add(14, graphics);
|
||||
cs.add(15, isFit).add(16, visualRect());
|
||||
if (backgroundColor() == palette().color(QPalette::Base) &&
|
||||
textColor() == palette().color(QPalette::WindowText) &&
|
||||
gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText))
|
||||
cs.add(17, true);
|
||||
if (backgroundColor() == palette().color(QPalette::Base) && textColor() == palette().color(QPalette::WindowText) &&
|
||||
gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText))
|
||||
cs.add(17, true);
|
||||
return cs.data().prepend('2');
|
||||
}
|
||||
|
||||
@@ -2343,8 +2405,8 @@ QByteArray Graphic::save() {
|
||||
void Graphic::load(QByteArray ba) {
|
||||
if (ba.isEmpty()) return;
|
||||
char ver = ba[0];
|
||||
switch(ver) {
|
||||
case '2': {// version '2':
|
||||
switch (ver) {
|
||||
case '2': { // version '2':
|
||||
ba.remove(0, 1);
|
||||
QRectF vrect;
|
||||
ChunkStream cs(ba);
|
||||
@@ -2356,35 +2418,47 @@ void Graphic::load(QByteArray ba) {
|
||||
case 3: setBorderInputsVisible(cs.getData<bool>()); break;
|
||||
case 4: setStatusVisible(cs.getData<bool>()); break;
|
||||
case 5: setLegendVisible(cs.getData<bool>()); break;
|
||||
case 6: if (!def_colors) setBackgroundColor(cs.getData<QColor>()); break;
|
||||
case 7: if (!def_colors) setTextColor(cs.getData<QColor>()); break;
|
||||
case 6:
|
||||
if (!def_colors) setBackgroundColor(cs.getData<QColor>());
|
||||
break;
|
||||
case 7:
|
||||
if (!def_colors) setTextColor(cs.getData<QColor>());
|
||||
break;
|
||||
case 8: setMargins(cs.getData<QRect>()); break;
|
||||
case 9: if (!def_colors) setGridPen(cs.getData<QPen>()); break;
|
||||
case 9:
|
||||
if (!def_colors) setGridPen(cs.getData<QPen>());
|
||||
break;
|
||||
case 10: setGraduationX(cs.getData<Graduation>()); break;
|
||||
case 11: setGraduationY(cs.getData<Graduation>()); break;
|
||||
case 12: setGraduationStepX(cs.getData<double>()); break;
|
||||
case 13: setGraduationStepY(cs.getData<double>()); break;
|
||||
case 14: graphics = cs.getData<QVector<GraphicType> >(); break;
|
||||
case 14: graphics = cs.getData<QVector<GraphicType>>(); break;
|
||||
case 15: isFit = cs.getData<bool>(); break;
|
||||
case 16: vrect = cs.getData<QRectF>(); break;
|
||||
case 17: if(cs.getData<bool>()) {
|
||||
setTextColor(palette().color(QPalette::WindowText));
|
||||
setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine));
|
||||
setBackgroundColor(palette().color(QPalette::Base));
|
||||
def_colors = true;
|
||||
} break;
|
||||
case 17:
|
||||
if (cs.getData<bool>()) {
|
||||
setTextColor(palette().color(QPalette::WindowText));
|
||||
setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine));
|
||||
setBackgroundColor(palette().color(QPalette::Base));
|
||||
def_colors = true;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (!isFit) setVisualRect(vrect);
|
||||
} break;
|
||||
default: {// old version 0:
|
||||
default: { // old version 0:
|
||||
QDataStream s(ba);
|
||||
bool a;
|
||||
s >> a; setOpenGL(a);
|
||||
s >> a; setAntialiasing(a);
|
||||
s >> a; setBorderInputsVisible(a);
|
||||
s >> a; setStatusVisible(a);
|
||||
s >> a;
|
||||
setOpenGL(a);
|
||||
s >> a;
|
||||
setAntialiasing(a);
|
||||
s >> a;
|
||||
setBorderInputsVisible(a);
|
||||
s >> a;
|
||||
setStatusVisible(a);
|
||||
s >> a;
|
||||
s >> graphics;
|
||||
setLegendVisible(a);
|
||||
@@ -2403,7 +2477,8 @@ void Graphic::setCaption(const QString & str) {
|
||||
void Graphic::setGraphicVisible(bool visible, int index) {
|
||||
graphics[index].visible = visible;
|
||||
updateLegendChecks();
|
||||
if (isFit) on_graphic_buttonAutofit_clicked();
|
||||
if (isFit)
|
||||
on_graphic_buttonAutofit_clicked();
|
||||
else if (aupdate)
|
||||
update();
|
||||
}
|
||||
@@ -2431,7 +2506,7 @@ void Graphic::setLegendVisible(bool visible) {
|
||||
ui->scrollLegend->setVisible(visible);
|
||||
ui->graphic_checkLegend->setChecked(visible);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
QTimer::singleShot(0, this, [this](){updateLegend();});
|
||||
QTimer::singleShot(0, this, [this]() { updateLegend(); });
|
||||
#else
|
||||
updateLegend();
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHIC_H
|
||||
#define GRAPHIC_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QMouseEvent>
|
||||
#include "evalspinbox.h"
|
||||
#include "graphic_conf.h"
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QGridLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QElapsedTimer>
|
||||
#include <QTranslator>
|
||||
#include <QFileDialog>
|
||||
#include <QGestureEvent>
|
||||
#include <QGridLayout>
|
||||
#include <QMenu>
|
||||
#include <qmath.h>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QTranslator>
|
||||
#include <QWidget>
|
||||
#include <float.h>
|
||||
#include "graphic_conf.h"
|
||||
#include "evalspinbox.h"
|
||||
#include "qad_graphic_export.h"
|
||||
#include <qmath.h>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class Graphic;
|
||||
class Graphic;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +52,7 @@ class GraphicPlugin;
|
||||
Q_DECLARE_METATYPE(QVector<QPointF>)
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT Graphic: public QFrame
|
||||
{
|
||||
class QAD_GRAPHIC_EXPORT Graphic: public QFrame {
|
||||
Q_OBJECT
|
||||
Q_FLAGS(Buttons)
|
||||
Q_ENUMS(Alignment Graduation AxisType FloatingAxisType)
|
||||
@@ -127,164 +127,262 @@ public:
|
||||
Graphic(QWidget * parent = 0);
|
||||
virtual ~Graphic();
|
||||
|
||||
typedef QVector<QVector<QPointF> > GraphicsData;
|
||||
enum GraphicAction {gaNone, gaZoomInRect, gaZoomRangeX, gaZoomRangeY, gaMove};
|
||||
enum Button {NoButtons = 0x0,
|
||||
AllButtons = 0xFFFFFFFF,
|
||||
Autofit = 0x01,
|
||||
Grid = 0x02,
|
||||
CursorAxis = 0x04,
|
||||
Fullscreen = 0x20,
|
||||
BorderInputs = 0x40,
|
||||
Legend = 0x80,
|
||||
Configure = 0x100,
|
||||
Save = 0x200,
|
||||
Export = 0x400,
|
||||
Clear = 0x800,
|
||||
Close = 0x1000,
|
||||
Pause = 0x2000,
|
||||
Record = 0x4000,
|
||||
StandartButtons = 0x2BFF
|
||||
};
|
||||
enum Alignment {Left, Right};
|
||||
enum Graduation {Auto, Fixed};
|
||||
enum AxisType {Numeric, DateTime};
|
||||
enum FloatingAxisType {Free, TraceXY, TraceX, TraceY};
|
||||
typedef QVector<QVector<QPointF>> GraphicsData;
|
||||
enum GraphicAction {
|
||||
gaNone,
|
||||
gaZoomInRect,
|
||||
gaZoomRangeX,
|
||||
gaZoomRangeY,
|
||||
gaMove
|
||||
};
|
||||
enum Button {
|
||||
NoButtons = 0x0,
|
||||
AllButtons = 0xFFFFFFFF,
|
||||
Autofit = 0x01,
|
||||
Grid = 0x02,
|
||||
CursorAxis = 0x04,
|
||||
Fullscreen = 0x20,
|
||||
BorderInputs = 0x40,
|
||||
Legend = 0x80,
|
||||
Configure = 0x100,
|
||||
Save = 0x200,
|
||||
Export = 0x400,
|
||||
Clear = 0x800,
|
||||
Close = 0x1000,
|
||||
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)
|
||||
|
||||
QString caption() const;
|
||||
QString labelX() const {return label_x;}
|
||||
QString labelY() const {return label_y;}
|
||||
QString graphicName() const {return graphics[curGraphic].name;}
|
||||
QString graphicName(int index) const {return graphics[index].name;}
|
||||
QColor backgroundColor() const {return back_color;}
|
||||
QColor textColor() const {return text_color;}
|
||||
QColor graphicColor() const {return graphics[curGraphic].pen.color();}
|
||||
QColor graphicColor(int index) const {return graphics[index].pen.color();}
|
||||
QColor gridColor() const {return grid_pen.color();}
|
||||
QColor selectionColor() const {return selpen.color();}
|
||||
Qt::PenStyle graphicStyle() const {return graphics[curGraphic].pen.style();}
|
||||
Qt::PenStyle graphicStyle(int index) const {return graphics[index].pen.style();}
|
||||
Qt::PenStyle gridStyle() const {return grid_pen.style();}
|
||||
Qt::PenStyle selectionStyle() const {return selpen.style();}
|
||||
double graphicLineWidth() const {return graphics[curGraphic].pen.widthF();}
|
||||
double graphicLineWidth(int index) const {return graphics[index].pen.widthF();}
|
||||
double graphicPointWidth() const {return graphics[curGraphic].pointWidth;}
|
||||
double graphicPointWidth(int index) const {return graphics[index].pointWidth;}
|
||||
QColor graphicFillColor() const {return graphics[curGraphic].fill_color;}
|
||||
QColor graphicFillColor(int index) const {return graphics[index].fill_color;}
|
||||
bool graphicVisible() const {return graphics[curGraphic].visible;}
|
||||
bool graphicVisible(int index) const {return graphics[index].visible;}
|
||||
bool graphicLinesEnabled() const {return graphics[curGraphic].lines;}
|
||||
bool graphicLinesEnabled(int index) const {return graphics[index].lines;}
|
||||
bool graphicPointsEnabled() const {return graphics[curGraphic].points;}
|
||||
bool graphicPointsEnabled(int index) const {return graphics[index].points;}
|
||||
bool graphicFillEnabled() const {return graphics[curGraphic].fill;}
|
||||
bool graphicFillEnabled(int index) const {return graphics[index].fill;}
|
||||
QPen graphicPen() const {return graphics[curGraphic].pen;}
|
||||
QPen graphicPen(int index) const {return graphics[index].pen;}
|
||||
QPen gridPen() const {return grid_pen;}
|
||||
QPen selectionPen() const {return selpen;}
|
||||
QBrush selectionBrush() const {return selbrush;}
|
||||
bool navigationEnabled() const {return navigation;}
|
||||
bool openGL() const {return isOGL;}
|
||||
bool antialiasing() const {return aalias;}
|
||||
bool autoUpdate() const {return aupdate;}
|
||||
bool gridEnabled() const {return grid;}
|
||||
QString labelX() const { return label_x; }
|
||||
QString labelY() const { return label_y; }
|
||||
QString graphicName() const { return graphics[curGraphic].name; }
|
||||
QString graphicName(int index) const { return graphics[index].name; }
|
||||
QColor backgroundColor() const { return back_color; }
|
||||
QColor textColor() const { return text_color; }
|
||||
QColor graphicColor() const { return graphics[curGraphic].pen.color(); }
|
||||
QColor graphicColor(int index) const { return graphics[index].pen.color(); }
|
||||
QColor gridColor() const { return grid_pen.color(); }
|
||||
QColor selectionColor() const { return selpen.color(); }
|
||||
Qt::PenStyle graphicStyle() const { return graphics[curGraphic].pen.style(); }
|
||||
Qt::PenStyle graphicStyle(int index) const { return graphics[index].pen.style(); }
|
||||
Qt::PenStyle gridStyle() const { return grid_pen.style(); }
|
||||
Qt::PenStyle selectionStyle() const { return selpen.style(); }
|
||||
double graphicLineWidth() const { return graphics[curGraphic].pen.widthF(); }
|
||||
double graphicLineWidth(int index) const { return graphics[index].pen.widthF(); }
|
||||
double graphicPointWidth() const { return graphics[curGraphic].pointWidth; }
|
||||
double graphicPointWidth(int index) const { return graphics[index].pointWidth; }
|
||||
QColor graphicFillColor() const { return graphics[curGraphic].fill_color; }
|
||||
QColor graphicFillColor(int index) const { return graphics[index].fill_color; }
|
||||
bool graphicVisible() const { return graphics[curGraphic].visible; }
|
||||
bool graphicVisible(int index) const { return graphics[index].visible; }
|
||||
bool graphicLinesEnabled() const { return graphics[curGraphic].lines; }
|
||||
bool graphicLinesEnabled(int index) const { return graphics[index].lines; }
|
||||
bool graphicPointsEnabled() const { return graphics[curGraphic].points; }
|
||||
bool graphicPointsEnabled(int index) const { return graphics[index].points; }
|
||||
bool graphicFillEnabled() const { return graphics[curGraphic].fill; }
|
||||
bool graphicFillEnabled(int index) const { return graphics[index].fill; }
|
||||
QPen graphicPen() const { return graphics[curGraphic].pen; }
|
||||
QPen graphicPen(int index) const { return graphics[index].pen; }
|
||||
QPen gridPen() const { return grid_pen; }
|
||||
QPen selectionPen() const { return selpen; }
|
||||
QBrush selectionBrush() const { return selbrush; }
|
||||
bool navigationEnabled() const { return navigation; }
|
||||
bool openGL() const { return isOGL; }
|
||||
bool antialiasing() const { return aalias; }
|
||||
bool autoUpdate() const { return aupdate; }
|
||||
bool gridEnabled() const { return grid; }
|
||||
bool borderInputsVisible() const;
|
||||
bool statusVisible() const;
|
||||
bool legendVisible() const;
|
||||
bool paused() const {return pause_;}
|
||||
bool onlyExpandY() const {return only_expand_y;}
|
||||
bool onlyExpandX() const {return only_expand_x;}
|
||||
bool gesturesNavigation() const {return gestures;}
|
||||
bool LODOptimization() const {return m_LODOptimization;}
|
||||
bool isAutofitted() const {return isFit;}
|
||||
int currentGraphic() const {return curGraphic;}
|
||||
int currentTraceGraphic() const {return curTrace;}
|
||||
int graphicsCount() const {return graphics.size();}
|
||||
Graphic::Buttons buttons() const {return buttons_;}
|
||||
Graphic::Alignment buttonsPosition() const {return align;}
|
||||
double historySize() const {return history;}
|
||||
double maxVisibleTime() const {return visible_time;}
|
||||
double autoXIncrement() const {return inc_x;}
|
||||
QRectF visualRect() const {return selrect;}
|
||||
QRectF defaultRect() const {return def_rect;}
|
||||
QRectF limit() const {return limit_;}
|
||||
QRect margins() const {return margins_;}
|
||||
int minimumRepaintInterval() const {return min_repaint_int;}
|
||||
double gridNumbersMultiplierX() const {return grid_numbers_x;}
|
||||
double gridNumbersMultiplierY() const {return grid_numbers_y;}
|
||||
Graduation graduationX() const {return grad_x;}
|
||||
Graduation graduationY() const {return grad_y;}
|
||||
double graduationStepX() const {return gridx;}
|
||||
double graduationStepY() const {return gridy;}
|
||||
AxisType axisType() const {return axis_type_x;}
|
||||
FloatingAxisType floatingAxisType() const {return floating_axis_type;}
|
||||
QVector<QPointF> graphicData() const {return graphics[curGraphic].polyline;}
|
||||
QVector<QPointF> graphicData(int index) const {return graphics[index].polyline;}
|
||||
bool paused() const { return pause_; }
|
||||
bool onlyExpandY() const { return only_expand_y; }
|
||||
bool onlyExpandX() const { return only_expand_x; }
|
||||
bool gesturesNavigation() const { return gestures; }
|
||||
bool LODOptimization() const { return m_LODOptimization; }
|
||||
bool isAutofitted() const { return isFit; }
|
||||
int currentGraphic() const { return curGraphic; }
|
||||
int currentTraceGraphic() const { return curTrace; }
|
||||
int graphicsCount() const { return graphics.size(); }
|
||||
Graphic::Buttons buttons() const { return buttons_; }
|
||||
Graphic::Alignment buttonsPosition() const { return align; }
|
||||
double historySize() const { return history; }
|
||||
double maxVisibleTime() const { return visible_time; }
|
||||
double autoXIncrement() const { return inc_x; }
|
||||
QRectF visualRect() const { return selrect; }
|
||||
QRectF defaultRect() const { return def_rect; }
|
||||
QRectF limit() const { return limit_; }
|
||||
QRect margins() const { return margins_; }
|
||||
int minimumRepaintInterval() const { return min_repaint_int; }
|
||||
double gridNumbersMultiplierX() const { return grid_numbers_x; }
|
||||
double gridNumbersMultiplierY() const { return grid_numbers_y; }
|
||||
Graduation graduationX() const { return grad_x; }
|
||||
Graduation graduationY() const { return grad_y; }
|
||||
double graduationStepX() const { return gridx; }
|
||||
double graduationStepY() const { return gridy; }
|
||||
AxisType axisType() const { return axis_type_x; }
|
||||
FloatingAxisType floatingAxisType() const { return floating_axis_type; }
|
||||
QVector<QPointF> graphicData() const { return graphics[curGraphic].polyline; }
|
||||
QVector<QPointF> graphicData(int index) const { return graphics[index].polyline; }
|
||||
GraphicsData graphicsData() const;
|
||||
QByteArray graphicsDataRaw() const;
|
||||
QWidget * viewport() const {return canvas;}
|
||||
QWidget * viewport() const { return canvas; }
|
||||
QByteArray save();
|
||||
void load(QByteArray ba);
|
||||
|
||||
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];}
|
||||
const QVector<GraphicType> & allGraphics() const {return graphics;}
|
||||
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();}
|
||||
GraphicType graphic(int arg) {
|
||||
if (arg < 0 || arg >= graphics.size()) return GraphicType();
|
||||
return graphics[arg];
|
||||
}
|
||||
const QVector<GraphicType> & allGraphics() const { return graphics; }
|
||||
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {
|
||||
graphics = g;
|
||||
if (update) updateLegend();
|
||||
}
|
||||
|
||||
double canvas2realX(double px) const;
|
||||
double canvas2realY(double py) const;
|
||||
double real2canvasX(double px) const;
|
||||
double real2canvasY(double py) const;
|
||||
QPointF canvas2real(QPointF canvas_point) const {return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y()));}
|
||||
QPointF real2canvas(QPointF real_point) const {return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y()));}
|
||||
QPointF canvas2real(QPointF canvas_point) const { return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y())); }
|
||||
QPointF real2canvas(QPointF real_point) const { return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y())); }
|
||||
QPolygonF real2canvas(const QPolygonF & real_polygon) const;
|
||||
QPolygonF canvas2real(const QPolygonF & canvas_polygon) const;
|
||||
double getScaleX() const {return real2canvasX(1.) - real2canvasX(0.);}
|
||||
double getScaleY() const {return real2canvasY(1.) - real2canvasY(0.);}
|
||||
QPointF getScale() const {return QPointF(getScaleX(), getScaleY());}
|
||||
double getScaleX() const { return real2canvasX(1.) - real2canvasX(0.); }
|
||||
double getScaleY() const { return real2canvasY(1.) - real2canvasY(0.); }
|
||||
QPointF getScale() const { return QPointF(getScaleX(), getScaleY()); }
|
||||
|
||||
public slots:
|
||||
void setCaption(const QString & str);
|
||||
void setLabelX(const QString & str) {label_x = str; hasLblX = (str.length() > 0); if (aupdate) update();}
|
||||
void setLabelY(const QString & str) {label_y = str; hasLblY = (str.length() > 0); if (aupdate) update();}
|
||||
void setGraphicName(const QString & str, int index) {graphics[index].name = str; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicName(const QString & str) {graphics[curGraphic].name = str; updateLegend(); if (aupdate) update();}
|
||||
void setBackgroundColor(const QColor & color) {back_color = color; if (aupdate) update(); updateLegend();}
|
||||
void setTextColor(const QColor & color) {text_color = color; if (aupdate) update();}
|
||||
void setGraphicColor(const QColor & color, int index) {graphics[index].pen.setColor(color); updateLegend(); if (aupdate) update();}
|
||||
void setGraphicColor(const QColor & color) {setGraphicColor(color, curGraphic);}
|
||||
void setGridColor(const QColor & color) {grid_pen.setColor(color); if (aupdate) update();}
|
||||
void setSelectionColor(const QColor & color) {selpen.setColor(color);}
|
||||
void setGraphicStyle(const Qt::PenStyle & style, int index) {graphics[index].pen.setStyle(style); updateLegend(); if (aupdate) update();}
|
||||
void setGraphicStyle(const Qt::PenStyle & style) {setGraphicStyle(style, curGraphic);}
|
||||
void setGridStyle(const Qt::PenStyle & style) {grid_pen.setStyle(style); if (aupdate) update();}
|
||||
void setSelectionStyle(const Qt::PenStyle & style) {selpen.setStyle(style);}
|
||||
void setLabelX(const QString & str) {
|
||||
label_x = str;
|
||||
hasLblX = (str.length() > 0);
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setLabelY(const QString & str) {
|
||||
label_y = str;
|
||||
hasLblY = (str.length() > 0);
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicName(const QString & str, int index) {
|
||||
graphics[index].name = str;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicName(const QString & str) {
|
||||
graphics[curGraphic].name = str;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setBackgroundColor(const QColor & color) {
|
||||
back_color = color;
|
||||
if (aupdate) update();
|
||||
updateLegend();
|
||||
}
|
||||
void setTextColor(const QColor & color) {
|
||||
text_color = color;
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicColor(const QColor & color, int index) {
|
||||
graphics[index].pen.setColor(color);
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicColor(const QColor & color) { setGraphicColor(color, curGraphic); }
|
||||
void setGridColor(const QColor & color) {
|
||||
grid_pen.setColor(color);
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setSelectionColor(const QColor & color) { selpen.setColor(color); }
|
||||
void setGraphicStyle(const Qt::PenStyle & style, int index) {
|
||||
graphics[index].pen.setStyle(style);
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicStyle(const Qt::PenStyle & style) { setGraphicStyle(style, curGraphic); }
|
||||
void setGridStyle(const Qt::PenStyle & style) {
|
||||
grid_pen.setStyle(style);
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setSelectionStyle(const Qt::PenStyle & style) { selpen.setStyle(style); }
|
||||
void setGraphicVisible(bool visible, int index);
|
||||
void setGraphicVisible(bool visible) {setGraphicVisible(visible, curGraphic);}
|
||||
void setGraphicLineWidth(double w, int index) {if (qRound(w) == w) graphics[index].pen.setWidth(qRound(w)); else graphics[index].pen.setWidthF(w); updateLegend(); if (aupdate) update();}
|
||||
void setGraphicLineWidth(double w) {setGraphicLineWidth(w, curGraphic);}
|
||||
void setGraphicPointWidth(double w, int index) {graphics[index].pointWidth = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicPointWidth(double w) {setGraphicPointWidth(w, curGraphic);}
|
||||
void setGraphicFillColor(const QColor & w, int index) {graphics[index].fill_color = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicFillColor(const QColor & w) {setGraphicFillColor(w, curGraphic);}
|
||||
void setGraphicLinesEnabled(bool w, int index) {graphics[index].lines = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicLinesEnabled(bool w) {setGraphicLinesEnabled(w, curGraphic);}
|
||||
void setGraphicPointsEnabled(bool w, int index) {graphics[index].points = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicPointsEnabled(bool w) {setGraphicPointsEnabled(w, curGraphic);}
|
||||
void setGraphicFillEnabled(bool w, int index) {graphics[index].fill = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicFillEnabled(bool w) {setGraphicFillEnabled(w, curGraphic);}
|
||||
void setGraphicPen(const QPen & pen, int index) {graphics[index].pen = pen; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicPen(const QPen & pen) {setGraphicPen(pen, curGraphic);}
|
||||
void setGridPen(const QPen & pen) {grid_pen = pen; if (aupdate) update();}
|
||||
void setSelectionPen(const QPen & pen) {selpen = pen;}
|
||||
void setSelectionBrush(const QBrush & brush) {selbrush = brush;}
|
||||
void setNavigationEnabled(bool on) {navigation = on;}
|
||||
void setLODOptimization(bool yes) {m_LODOptimization = yes;}
|
||||
void setGraphicVisible(bool visible) { setGraphicVisible(visible, curGraphic); }
|
||||
void setGraphicLineWidth(double w, int index) {
|
||||
if (qRound(w) == w)
|
||||
graphics[index].pen.setWidth(qRound(w));
|
||||
else
|
||||
graphics[index].pen.setWidthF(w);
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicLineWidth(double w) { setGraphicLineWidth(w, curGraphic); }
|
||||
void setGraphicPointWidth(double w, int index) {
|
||||
graphics[index].pointWidth = w;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicPointWidth(double w) { setGraphicPointWidth(w, curGraphic); }
|
||||
void setGraphicFillColor(const QColor & w, int index) {
|
||||
graphics[index].fill_color = w;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicFillColor(const QColor & w) { setGraphicFillColor(w, curGraphic); }
|
||||
void setGraphicLinesEnabled(bool w, int index) {
|
||||
graphics[index].lines = w;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicLinesEnabled(bool w) { setGraphicLinesEnabled(w, curGraphic); }
|
||||
void setGraphicPointsEnabled(bool w, int index) {
|
||||
graphics[index].points = w;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicPointsEnabled(bool w) { setGraphicPointsEnabled(w, curGraphic); }
|
||||
void setGraphicFillEnabled(bool w, int index) {
|
||||
graphics[index].fill = w;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicFillEnabled(bool w) { setGraphicFillEnabled(w, curGraphic); }
|
||||
void setGraphicPen(const QPen & pen, int index) {
|
||||
graphics[index].pen = pen;
|
||||
updateLegend();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraphicPen(const QPen & pen) { setGraphicPen(pen, curGraphic); }
|
||||
void setGridPen(const QPen & pen) {
|
||||
grid_pen = pen;
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setSelectionPen(const QPen & pen) { selpen = pen; }
|
||||
void setSelectionBrush(const QBrush & brush) { selbrush = brush; }
|
||||
void setNavigationEnabled(bool on) { navigation = on; }
|
||||
void setLODOptimization(bool yes) { m_LODOptimization = yes; }
|
||||
void setOpenGL(bool on);
|
||||
void setAntialiasing(bool enabled);
|
||||
void setAutoUpdate(bool enabled) {aupdate = enabled;}
|
||||
void setAutoUpdate(bool enabled) { aupdate = enabled; }
|
||||
void setGridEnabled(bool enabled);
|
||||
void setBorderInputsVisible(bool visible);
|
||||
void setStatusVisible(bool visible);
|
||||
@@ -294,66 +392,149 @@ public slots:
|
||||
void setButtonsPosition(Graphic::Alignment a);
|
||||
void setHistorySize(double val);
|
||||
void setMaxVisibleTime(double val);
|
||||
void setAutoXIncrement(double val) {inc_x = val;}
|
||||
void setLimit(const QRectF & val) {limit_ = val;}
|
||||
void setMargins(const QRect & val) {margins_ = val; update();}
|
||||
void setMargins(int left_, int right_, int top_, int bottom_) {setMargins(QRect(left_, bottom_, right_, top_));}
|
||||
void setLeftMargin(int value) {margins_.moveLeft(value); setMargins(margins_);}
|
||||
void setRightMargin(int value) {margins_.setWidth(value); setMargins(margins_);}
|
||||
void setTopMargin(int value) {margins_.setHeight(value); setMargins(margins_);}
|
||||
void setBottomMargin(int value) {margins_.moveTop(value); setMargins(margins_);}
|
||||
void setMinimumRepaintInterval(const int & val) {min_repaint_int = val;}
|
||||
void setAutoXIncrement(double val) { inc_x = val; }
|
||||
void setLimit(const QRectF & val) { limit_ = val; }
|
||||
void setMargins(const QRect & val) {
|
||||
margins_ = val;
|
||||
update();
|
||||
}
|
||||
void setMargins(int left_, int right_, int top_, int bottom_) { setMargins(QRect(left_, bottom_, right_, top_)); }
|
||||
void setLeftMargin(int value) {
|
||||
margins_.moveLeft(value);
|
||||
setMargins(margins_);
|
||||
}
|
||||
void setRightMargin(int value) {
|
||||
margins_.setWidth(value);
|
||||
setMargins(margins_);
|
||||
}
|
||||
void setTopMargin(int value) {
|
||||
margins_.setHeight(value);
|
||||
setMargins(margins_);
|
||||
}
|
||||
void setBottomMargin(int value) {
|
||||
margins_.moveTop(value);
|
||||
setMargins(margins_);
|
||||
}
|
||||
void setMinimumRepaintInterval(const int & val) { min_repaint_int = val; }
|
||||
void setOnlyExpandY(bool yes);
|
||||
void setOnlyExpandX(bool yes);
|
||||
void setGesturesNavigation(bool yes);
|
||||
void setGraphicsData(const GraphicsData & gd);
|
||||
void setGraphicsDataRaw(const QByteArray & ba);
|
||||
|
||||
void setGridNumbersMultiplierX(double value) {grid_numbers_x = value; updateGraphics();}
|
||||
void setGridNumbersMultiplierY(double value) {grid_numbers_y = value; updateGraphics();}
|
||||
void setGraduationX(Graduation value) {grad_x = value; if (aupdate) update();;}
|
||||
void setGraduationY(Graduation value) {grad_y = value; if (aupdate) update();;}
|
||||
void setGraduationStepX(double sx) {gridx = sx; if (aupdate) update();}
|
||||
void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();}
|
||||
void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();}
|
||||
void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();}
|
||||
void setFloatingAxisType(FloatingAxisType t) {floating_axis_type = t; setGuidesCursor(); if (aupdate) update();}
|
||||
void setGridNumbersMultiplierX(double value) {
|
||||
grid_numbers_x = value;
|
||||
updateGraphics();
|
||||
}
|
||||
void setGridNumbersMultiplierY(double value) {
|
||||
grid_numbers_y = value;
|
||||
updateGraphics();
|
||||
}
|
||||
void setGraduationX(Graduation value) {
|
||||
grad_x = value;
|
||||
if (aupdate) update();
|
||||
;
|
||||
}
|
||||
void setGraduationY(Graduation value) {
|
||||
grad_y = value;
|
||||
if (aupdate) update();
|
||||
;
|
||||
}
|
||||
void setGraduationStepX(double sx) {
|
||||
gridx = sx;
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraduationStepY(double sy) {
|
||||
gridy = sy;
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setGraduationSteps(double sx, double sy) {
|
||||
gridx = sx;
|
||||
gridy = sy;
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setAxisType(AxisType t) {
|
||||
axis_type_x = t;
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setFloatingAxisType(FloatingAxisType t) {
|
||||
floating_axis_type = t;
|
||||
setGuidesCursor();
|
||||
if (aupdate) update();
|
||||
}
|
||||
void setFloatingAxisEnabled(bool on);
|
||||
|
||||
void addPoint(const QPointF & p, int graphic, bool update_ = true);
|
||||
void addPoint(const QPointF & p, bool update = true) {addPoint(p, curGraphic, update);}
|
||||
void addPoint(double x, double y, int graphic, bool update = true) {addPoint(QPointF(x, y), graphic, update);}
|
||||
void addPoint(double x, double y, bool update = true) {addPoint(QPointF(x, y), update);}
|
||||
void addPoint(double y, int graphic, bool update = true) {if (graphics[graphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), graphic, update); else addPoint(QPointF(graphics[graphic].max_x + inc_x, y), graphic, update);}
|
||||
void addPoint(double y, bool update = true) {if (graphics[curGraphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), update); else addPoint(QPointF(graphics[curGraphic].max_x + inc_x, y), update);}
|
||||
void addPoint(const QPointF & p, bool update = true) { addPoint(p, curGraphic, update); }
|
||||
void addPoint(double x, double y, int graphic, bool update = true) { addPoint(QPointF(x, y), graphic, update); }
|
||||
void addPoint(double x, double y, bool update = true) { addPoint(QPointF(x, y), update); }
|
||||
void addPoint(double y, int graphic, bool update = true) {
|
||||
if (graphics[graphic].polyline.isEmpty())
|
||||
addPoint(QPointF(0.0, y), graphic, update);
|
||||
else
|
||||
addPoint(QPointF(graphics[graphic].max_x + inc_x, y), graphic, update);
|
||||
}
|
||||
void addPoint(double y, bool update = true) {
|
||||
if (graphics[curGraphic].polyline.isEmpty())
|
||||
addPoint(QPointF(0.0, y), update);
|
||||
else
|
||||
addPoint(QPointF(graphics[curGraphic].max_x + inc_x, y), update);
|
||||
}
|
||||
void 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, 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) {setGraphicData(g, curGraphic);}
|
||||
void setGraphicProperties(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true) {setGraphicProperties(curGraphic, name, color, style, width, visible);}
|
||||
void setGraphicProperties(int graphic, const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
|
||||
void addGraphic(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
|
||||
void addGraphic(const GraphicType & gd, bool update = true) {graphics << gd; if (update) updateLegend();}
|
||||
void setGraphicData(const QVector<QPointF> & g) { setGraphicData(g, curGraphic); }
|
||||
void setGraphicProperties(const QString & name,
|
||||
const QColor & color = Qt::darkRed,
|
||||
Qt::PenStyle style = Qt::SolidLine,
|
||||
double width = 0.,
|
||||
bool visible = true) {
|
||||
setGraphicProperties(curGraphic, name, color, style, width, visible);
|
||||
}
|
||||
void setGraphicProperties(int graphic,
|
||||
const QString & name,
|
||||
const QColor & color = Qt::darkRed,
|
||||
Qt::PenStyle style = Qt::SolidLine,
|
||||
double width = 0.,
|
||||
bool visible = true);
|
||||
void addGraphic(const QString & name,
|
||||
const QColor & color = Qt::darkRed,
|
||||
Qt::PenStyle style = Qt::SolidLine,
|
||||
double width = 0.,
|
||||
bool visible = true);
|
||||
void addGraphic(const GraphicType & gd, bool update = true) {
|
||||
graphics << gd;
|
||||
if (update) updateLegend();
|
||||
}
|
||||
void setVisualRect(const QRectF & rect);
|
||||
void setDefaultRect(const QRectF & rect);
|
||||
void autofit() {on_graphic_buttonAutofit_clicked();}
|
||||
void autofit() { on_graphic_buttonAutofit_clicked(); }
|
||||
void saveImage(QString filename);
|
||||
void exportGraphics(QString filename, QChar decimal_point);
|
||||
void clear();
|
||||
void update(bool force);
|
||||
void update() {update(false);}
|
||||
void updateGraphics() {findGraphicsRect(); 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 update() { update(false); }
|
||||
void updateGraphics() {
|
||||
findGraphicsRect();
|
||||
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 removeGraphic(int arg, bool update = true);
|
||||
void setCustomGridMarkFuncs(std::function<QString(double val)> fx, std::function<QString(double val)> fy);
|
||||
|
||||
void zoom(float factor);
|
||||
void zoomIn() {zoom(1. / 1.2);}
|
||||
void zoomOut() {zoom(1.2);}
|
||||
void zoomIn() { zoom(1. / 1.2); }
|
||||
void zoomOut() { zoom(1.2); }
|
||||
void fullscreen();
|
||||
|
||||
|
||||
@@ -365,9 +546,9 @@ protected:
|
||||
};
|
||||
|
||||
void changeEvent(QEvent * e) override;
|
||||
void resizeEvent(QResizeEvent * ) override;
|
||||
void showEvent(QShowEvent * ) override;
|
||||
QSize sizeHint() const override {return QSize(400, 300);}
|
||||
void resizeEvent(QResizeEvent *) override;
|
||||
void showEvent(QShowEvent *) override;
|
||||
QSize sizeHint() const override { return QSize(400, 300); }
|
||||
void timerEvent(QTimerEvent * 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 tick(int index, bool slide = true, bool update = true);
|
||||
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 drawGrid();
|
||||
void drawGuides();
|
||||
@@ -390,7 +575,7 @@ protected:
|
||||
void setCanvasCursor(QCursor cursor);
|
||||
void setGuidesCursor();
|
||||
void swapToBuffer();
|
||||
void swapToNormal() {bufferActive = false;}
|
||||
void swapToNormal() { bufferActive = false; }
|
||||
void setRectToLines();
|
||||
void checkLines();
|
||||
double splitRange(double range, int count = 1);
|
||||
@@ -398,7 +583,7 @@ protected:
|
||||
double roundTo(double value, double round_to);
|
||||
void roundDateTime(QDateTime & dt, int * c);
|
||||
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);
|
||||
QPair<QString, QString> gridMark(double v) const;
|
||||
void fillDateFormats();
|
||||
@@ -438,56 +623,76 @@ protected:
|
||||
double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle;
|
||||
int lastw, lasth, min_repaint_int, thick;
|
||||
int timer_pause, timer_record;
|
||||
bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL, 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;
|
||||
bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL,
|
||||
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;
|
||||
QVector<DateFormats> date_formats;
|
||||
QList<QImage> record_imgs;
|
||||
|
||||
protected slots:
|
||||
void canvasPaintEvent();
|
||||
void canvasMouseMoveEvent(QMouseEvent * );
|
||||
void canvasMousePressEvent(QMouseEvent * );
|
||||
void canvasMouseReleaseEvent(QMouseEvent * );
|
||||
void canvasMouseDoubleClickEvent(QMouseEvent * );
|
||||
void canvasWheelEvent(QWheelEvent * );
|
||||
void canvasLeaveEvent(QEvent * );
|
||||
void canvasKeyPressEvent(QKeyEvent * );
|
||||
void canvasMouseMoveEvent(QMouseEvent *);
|
||||
void canvasMousePressEvent(QMouseEvent *);
|
||||
void canvasMouseReleaseEvent(QMouseEvent *);
|
||||
void canvasMouseDoubleClickEvent(QMouseEvent *);
|
||||
void canvasWheelEvent(QWheelEvent *);
|
||||
void canvasLeaveEvent(QEvent *);
|
||||
void canvasKeyPressEvent(QKeyEvent *);
|
||||
void graphicVisibleChange(bool checked);
|
||||
void graphicAllVisibleChange(bool checked);
|
||||
void lineXMinChanged(double value) {selrect.setLeft(value); checkLines();}
|
||||
void lineXMaxChanged(double value) {selrect.setRight(value); checkLines();}
|
||||
void lineYMinChanged(double value) {selrect.setBottom(value); checkLines();}
|
||||
void lineYMaxChanged(double value) {selrect.setTop(value); checkLines();}
|
||||
void on_graphic_buttonClose_clicked() {emit closeRequest(this);}
|
||||
void on_graphic_buttonClear_clicked() {clear(); emit cleared();}
|
||||
void lineXMinChanged(double value) {
|
||||
selrect.setLeft(value);
|
||||
checkLines();
|
||||
}
|
||||
void lineXMaxChanged(double value) {
|
||||
selrect.setRight(value);
|
||||
checkLines();
|
||||
}
|
||||
void lineYMinChanged(double value) {
|
||||
selrect.setBottom(value);
|
||||
checkLines();
|
||||
}
|
||||
void lineYMaxChanged(double value) {
|
||||
selrect.setTop(value);
|
||||
checkLines();
|
||||
}
|
||||
void on_graphic_buttonClose_clicked() { emit closeRequest(this); }
|
||||
void on_graphic_buttonClear_clicked() {
|
||||
clear();
|
||||
emit cleared();
|
||||
}
|
||||
void on_graphic_buttonAutofit_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_buttonExport_clicked();
|
||||
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_actionExpandX_triggered(bool checked);
|
||||
void on_graphic_actionExpandY_triggered(bool checked);
|
||||
void on_graphic_checkBorderInputs_toggled(bool checked) {setBorderInputsVisible(checked);}
|
||||
void on_graphic_checkLegend_toggled(bool checked) {setLegendVisible(checked);}
|
||||
void on_graphic_checkPause_toggled(bool checked) {setPaused(checked);}
|
||||
void on_graphic_checkBorderInputs_toggled(bool checked) { setBorderInputsVisible(checked); }
|
||||
void on_graphic_checkLegend_toggled(bool checked) { setLegendVisible(checked); }
|
||||
void on_graphic_checkPause_toggled(bool checked) { setPaused(checked); }
|
||||
void actionGuidesTriggered(QAction * a);
|
||||
void enterFullscreen();
|
||||
void leaveFullscreen();
|
||||
void showMenu();
|
||||
|
||||
signals:
|
||||
void beforeGraphicPaintEvent(QPainter * );
|
||||
void graphicPaintEvent(QPainter * );
|
||||
void beforeGraphicPaintEvent(QPainter *);
|
||||
void graphicPaintEvent(QPainter *);
|
||||
void graphicMouseMoveEvent(QPointF point, int buttons);
|
||||
void graphicMousePressEvent(QPointF point, int buttons);
|
||||
void graphicMouseReleaseEvent(QPointF point, int buttons);
|
||||
void graphicWheelEvent(QPointF point, int delta);
|
||||
void graphicTraceEvent(int graphic, QPointF point);
|
||||
void closeRequest(QWidget * );
|
||||
void closeRequest(QWidget *);
|
||||
void cleared();
|
||||
void visualRectChanged();
|
||||
void graphicSettingsChanged();
|
||||
@@ -499,14 +704,20 @@ Q_DECLARE_METATYPE(Graphic::GraphicsData)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Graphic::Buttons)
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const Graphic::Graduation & v) {s << (int)v; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, Graphic::Graduation & v) {s >> *((int*)(&v)); return s;}
|
||||
inline QDataStream & operator<<(QDataStream & s, const Graphic::Graduation & v) {
|
||||
s << (int)v;
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator>>(QDataStream & s, Graphic::Graduation & v) {
|
||||
s >> *((int *)(&v));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ {
|
||||
public:
|
||||
__GraphicRegistrator__() {
|
||||
qRegisterMetaType<QVector<QPointF> >("QVector<QPointF>");
|
||||
qRegisterMetaType<QVector<QPointF>>("QVector<QPointF>");
|
||||
qRegisterMetaType<Graphic::GraphicsData>("Graphic::GraphicsData");
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
qRegisterMetaTypeStreamOperators<Graphic::GraphicsData>("Graphic::GraphicsData");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "graphic_conf.h"
|
||||
|
||||
#include "qad_types.h"
|
||||
#include "ui_graphic_conf.h"
|
||||
|
||||
@@ -7,11 +8,10 @@ GraphicConf::GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent): QD
|
||||
ui = new Ui::GraphicConf();
|
||||
ui->setupUi(this);
|
||||
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);
|
||||
QSize sz(fh * 2.5, fh);
|
||||
styles << tr("NoPen") << tr("Solid") << tr("Dash")
|
||||
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
|
||||
styles << tr("NoPen") << tr("Solid") << tr("Dash") << tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
|
||||
ui->comboStyleGrid->setIconSize(sz);
|
||||
ui->comboStyleGraphic->setIconSize(sz);
|
||||
ui->cbGraphicNames->setIconSize(sz);
|
||||
@@ -72,8 +72,10 @@ void GraphicConf::on_comboStyleGraphic_currentIndexChanged(int index) {
|
||||
|
||||
void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
if (qRound(value) == value) graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value));
|
||||
else graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value);
|
||||
if (qRound(value) == value)
|
||||
graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value));
|
||||
else
|
||||
graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHIC_CONF_H
|
||||
#define GRAPHIC_CONF_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QCheckBox>
|
||||
#include <QPen>
|
||||
#include <QPainter>
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class GraphicConf;
|
||||
class GraphicConf;
|
||||
}
|
||||
|
||||
|
||||
struct QAD_GRAPHIC_EXPORT GraphicType {
|
||||
GraphicType(QString name_ = "y(x)", QColor color = Qt::red, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible_ = true) {
|
||||
GraphicType(QString name_ = "y(x)",
|
||||
QColor color = Qt::red,
|
||||
Qt::PenStyle style = Qt::SolidLine,
|
||||
double width = 0.,
|
||||
bool visible_ = true) {
|
||||
pen.setColor(color);
|
||||
pen.setStyle(style);
|
||||
lines = true;
|
||||
points = false;
|
||||
fill = false;
|
||||
lines = true;
|
||||
points = false;
|
||||
fill = false;
|
||||
fill_color = Qt::yellow;
|
||||
if (qRound(width) == width) pen.setWidth(qRound(width));
|
||||
else pen.setWidthF(width);
|
||||
if (qRound(width) == width)
|
||||
pen.setWidth(qRound(width));
|
||||
else
|
||||
pen.setWidthF(width);
|
||||
pen.setWidth(1);
|
||||
pen.setCosmetic(true);
|
||||
max_x = 0.;
|
||||
name = name_;
|
||||
visible = visible_;
|
||||
max_x = 0.;
|
||||
name = name_;
|
||||
visible = visible_;
|
||||
pointWidth = 2.;
|
||||
pb = new QCheckBox(name);
|
||||
pb = new QCheckBox(name);
|
||||
}
|
||||
//~GraphicType() {delete pb;}
|
||||
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, 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) {
|
||||
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
|
||||
friend class Graphic;
|
||||
|
||||
public:
|
||||
explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "graphic.h"
|
||||
#include "graphicplugin.h"
|
||||
|
||||
#include "graphic.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
@@ -10,8 +12,7 @@ GraphicPlugin::GraphicPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
m_designer = true;
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -26,8 +27,7 @@ bool GraphicPlugin::isInitialized() const {
|
||||
|
||||
QWidget * GraphicPlugin::createWidget(QWidget * parent) {
|
||||
auto ret = new Graphic(parent);
|
||||
if (m_designer)
|
||||
ret->m_fakeGL = true;
|
||||
if (m_designer) ret->m_fakeGL = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ QIcon GraphicPlugin::icon() 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 {
|
||||
return QLatin1String("graphic.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class GraphicPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class GraphicPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized, m_designer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "qad_graphic.h"
|
||||
|
||||
#include "graphicplugin.h"
|
||||
|
||||
QADGraphic::QADGraphic(QObject * parent): QObject(parent)
|
||||
{
|
||||
QADGraphic::QADGraphic(QObject * parent): QObject(parent) {
|
||||
m_widgets.append(new GraphicPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QADGraphic::customWidgets() const {
|
||||
QList<QDesignerCustomWidgetInterface *> QADGraphic::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
#ifndef QAD_GRAPHIC_H
|
||||
#define QAD_GRAPHIC_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
#include <QtDesigner/QtDesigner>
|
||||
|
||||
class QADGraphic: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
class QADGraphic
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetCollectionInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "qad.graphic")
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit QADGraphic(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
QList<QDesignerCustomWidgetInterface *> m_widgets;
|
||||
};
|
||||
|
||||
#endif // QAD_GRAPHIC_H
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef UGLWIDGET_H
|
||||
#define UGLWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDebug>
|
||||
#include <QWidget>
|
||||
#if QT_VERSION >= 0x050400
|
||||
# include <QOpenGLWidget>
|
||||
typedef QOpenGLWidget __GLWidget__;
|
||||
@@ -10,32 +10,37 @@ typedef QOpenGLWidget __GLWidget__;
|
||||
# include <QGLWidget>
|
||||
typedef QGLWidget __GLWidget__;
|
||||
# ifndef GL_MULTISAMPLE
|
||||
# define GL_MULTISAMPLE 0x809D
|
||||
# define GL_MULTISAMPLE 0x809D
|
||||
# endif
|
||||
#endif
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__
|
||||
{
|
||||
class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__ {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
#if QT_VERSION >= 0x050400
|
||||
UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {QSurfaceFormat sf = format(); sf.setSamples(8); setFormat(sf);}
|
||||
UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {
|
||||
QSurfaceFormat sf = format();
|
||||
sf.setSamples(8);
|
||||
setFormat(sf);
|
||||
}
|
||||
#else
|
||||
UGLWidget(QWidget * parent = 0): __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {}
|
||||
UGLWidget(QWidget * parent = 0)
|
||||
: __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {}
|
||||
#endif
|
||||
//UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {}
|
||||
// UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {}
|
||||
|
||||
#if QT_VERSION >= 0x050400
|
||||
QImage grabFrameBuffer() {return grabFramebuffer();}
|
||||
QImage grabFrameBuffer() { return grabFramebuffer(); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#if QT_VERSION >= 0x050400
|
||||
virtual void paintGL() {emit paintSignal();}
|
||||
virtual void paintGL() { emit paintSignal(); }
|
||||
#else
|
||||
virtual void paintEvent(QPaintEvent * ) {emit paintSignal();}
|
||||
virtual void paintEvent(QPaintEvent *) { emit paintSignal(); }
|
||||
#endif
|
||||
virtual void resizeEvent(QResizeEvent * e) {
|
||||
__GLWidget__::resizeEvent(e);
|
||||
@@ -63,7 +68,6 @@ signals:
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void resizeSignal();
|
||||
void paintSignal();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
#ifndef UWIDGET_H
|
||||
#define UWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#include <QEvent>
|
||||
#include "qad_graphic_export.h"
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT UWidget: public QWidget
|
||||
{
|
||||
class QAD_GRAPHIC_EXPORT UWidget: public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UWidget(QWidget * parent = 0): QWidget(parent) {}
|
||||
|
||||
|
||||
private:
|
||||
virtual bool event(QEvent * e) {
|
||||
if (e->type() != QEvent::Paint) return QWidget::event(e);
|
||||
@@ -27,7 +28,7 @@ private:
|
||||
#endif
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
emit paintEvent((QPaintEvent * )e);
|
||||
emit paintEvent((QPaintEvent *)e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,7 +52,6 @@ signals:
|
||||
void showEvent(QShowEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void paintEvent(QPaintEvent * e);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#include "piqt.h"
|
||||
|
||||
#include "qvariantedit.h"
|
||||
#ifdef PIQT_HAS_GEOPOSITION
|
||||
# include <QGeoCoordinate>
|
||||
# include "pigeoposition.h"
|
||||
|
||||
# include <QGeoCoordinate>
|
||||
#endif
|
||||
|
||||
|
||||
const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el) {
|
||||
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.selectValue(el.selectedValue());
|
||||
return ret;
|
||||
@@ -17,7 +19,7 @@ const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el) {
|
||||
|
||||
const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el) {
|
||||
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.selectValue(el.selectedValue());
|
||||
return ret;
|
||||
@@ -54,7 +56,7 @@ const QVariant PI2QVariant(const PIVariant & v) {
|
||||
case PIVariant::pivIODevice: return QVariant::fromValue(PI2QADIODevice(v.toIODevice()));
|
||||
case PIVariant::pivMathVector: return QVariant::fromValue(PI2QMathVector(v.toMathVector()));
|
||||
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();
|
||||
}
|
||||
return QVariant();
|
||||
@@ -168,13 +170,13 @@ const PIVariant Q2PIVariant(const QVariant & v) {
|
||||
case QMetaType::QLine:
|
||||
case QMetaType::QLineF:
|
||||
#endif
|
||||
return PIVariant(Q2PILine(v.toLineF()));
|
||||
return PIVariant(Q2PILine(v.toLineF()));
|
||||
default: break;
|
||||
}
|
||||
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::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::MathVector>()) return PIVariant(Q2PIMathVector(v.value<QAD::MathVector>()));
|
||||
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) {
|
||||
PIVariantTypes::IODevice d;
|
||||
d.set(Q2PIPropertyStorage(v.props));
|
||||
d.prefix = Q2PIString(v.prefix);
|
||||
d.mode = v.mode;
|
||||
d.prefix = Q2PIString(v.prefix);
|
||||
d.mode = v.mode;
|
||||
d.options = v.options;
|
||||
return d;
|
||||
}
|
||||
|
||||
722
libs/piqt/piqt.h
722
libs/piqt/piqt.h
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQT_H
|
||||
#define PIQT_H
|
||||
|
||||
#include <QVector3D>
|
||||
#include <QPolygonF>
|
||||
#include <QDateTime>
|
||||
#include <QColor>
|
||||
#include <QImage>
|
||||
|
||||
#include "pimathmatrix.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "qad_types.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 >= QT_VERSION_CHECK(5, 2, 0)
|
||||
# define PIQT_HAS_GEOPOSITION
|
||||
# define PIQT_HAS_GEOPOSITION
|
||||
# endif
|
||||
#endif
|
||||
#if QT_VERSION_MAJOR == 6
|
||||
# if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
|
||||
# define PIQT_HAS_GEOPOSITION
|
||||
# define PIQT_HAS_GEOPOSITION
|
||||
# endif
|
||||
#endif
|
||||
#ifdef PIQT_HAS_GEOPOSITION
|
||||
@@ -50,114 +50,187 @@ class PIGeoPosition;
|
||||
QAD_PIQT_EXPORT const QVariant PI2QVariant(const PIVariant & 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::fromUtf8(v.dataUTF8());}
|
||||
#if PIP_VERSION >= PIP_MAKE_VERSION(2,38,0)
|
||||
inline const QString PI2QString(const PIConstChars & v) {return QString::fromLatin1(v.data(), v.length());}
|
||||
// inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());}
|
||||
inline const QString PI2QString(const PIString & v) {
|
||||
return QString::fromUtf8(v.dataUTF8());
|
||||
}
|
||||
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 38, 0)
|
||||
inline const QString PI2QString(const PIConstChars & v) {
|
||||
return QString::fromLatin1(v.data(), v.length());
|
||||
}
|
||||
#endif
|
||||
|
||||
//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(v.toLocal8Bit().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 QVector3D PI2QVector3(const PIMathVectorT3d & v) {return QVector3D(v[0], v[1], v[2]);}
|
||||
inline const QPointF PI2QVector2(const PIMathVectorT2d & v) {
|
||||
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 PIMathVectorT3d Q2PIVector3(const QVector3D & v) {return PIMathVectorT3d({double(v.x()), double(v.y()), double(v.z())});}
|
||||
inline const PIMathVectorT2d Q2PIVector2(const QPointF & v) {
|
||||
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 PIPointd Q2PIPoint(const QPointF & v) {return PIPointd(v.x(), v.y());}
|
||||
inline const QPointF PI2QPoint(const PIPointd & v) {
|
||||
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 PIRectd Q2PIRect(const QRectF & v) {return PIRectd(v.left(), v.top(), v.width(), v.height());}
|
||||
inline const QRectF PI2QRect(const PIRectd & v) {
|
||||
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 PILined Q2PILine(const QLineF & v) {return PILined(Q2PIPoint(v.p1()), Q2PIPoint(v.p2()));}
|
||||
inline const QLineF PI2QLine(const PILined & v) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
inline const PIMathVectord Q2PIMathVector(const QAD::MathVector & v) {
|
||||
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;
|
||||
}
|
||||
|
||||
inline const QAD::MathMatrix PI2QMathMatrix(const PIMathMatrixd & v) {
|
||||
PIVector<PIVector<double> > p = v.toVectors();
|
||||
QVector<QVector<double> > q = QVector<QVector<double> >(p.size());
|
||||
PIVector<PIVector<double>> p = v.toVectors();
|
||||
QVector<QVector<double>> q = QVector<QVector<double>>(p.size());
|
||||
for (int i = 0; i < q.size(); ++i) {
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
inline const QDate PI2QDate(const PIDate & v) {return QDate(v.year, v.month, v.day);}
|
||||
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 QDate PI2QDate(const PIDate & v) {
|
||||
return QDate(v.year, v.month, v.day);
|
||||
}
|
||||
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 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 PIDate Q2PIDate(const QDate & v) {
|
||||
return PIDate(v.year(), v.month(), v.day());
|
||||
}
|
||||
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 PIVariantTypes::Color Q2PIColor(const QColor & v) {return PIVariantTypes::Color(v.rgba());}
|
||||
inline const QColor PI2QColor(const PIVariantTypes::Color & v) {
|
||||
return QColor::fromRgba(v.rgba);
|
||||
}
|
||||
inline const PIVariantTypes::Color Q2PIColor(const QColor & v) {
|
||||
return PIVariantTypes::Color(v.rgba());
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
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) {
|
||||
QMap<K, T> ret;
|
||||
auto it = v.makeIterator();
|
||||
while (it.hasNext()) {it.next(); ret[it.key()] = it.value();}
|
||||
return ret;}
|
||||
template <typename K, typename T>
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
ret[it.key()] = it.value();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
template<typename K, typename T>
|
||||
inline PIMap<K, T> Q2PIMap(const QMap<K, T> & v) {
|
||||
PIMap<K, T> ret;
|
||||
ret.reserve((size_t)v.size());
|
||||
QMapIterator<K, T> it(v);
|
||||
while (it.hasNext()) {it.next(); ret[it.key()] = it.value();}
|
||||
return ret;}
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
ret[it.key()] = it.value();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) {
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline PropertyStorage PI2QPropertyStorage(const PIPropertyStorage & props) {
|
||||
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);
|
||||
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::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
|
||||
QAD_PIQT_EXPORT const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v);
|
||||
QAD_PIQT_EXPORT const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v);
|
||||
#endif
|
||||
|
||||
template <typename From>
|
||||
template<typename From>
|
||||
class __PIQtConverter {
|
||||
public:
|
||||
__PIQtConverter(const From & v): val(v) {}
|
||||
template <typename To> operator To() {return To();}
|
||||
template<typename To>
|
||||
operator To() {
|
||||
return To();
|
||||
}
|
||||
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) \
|
||||
template<> template<> inline __PIQtConverter<ft>::operator tt() {return ftc(val);} \
|
||||
template<> template<> inline __PIQtConverter<tt>::operator ft() {return tfc(val);}
|
||||
#define _PIQt_CONVERT(ft, tt, ftc, tfc) \
|
||||
template<> \
|
||||
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)
|
||||
|
||||
_PIQt_CONVERT_S(String)
|
||||
_PIQt_CONVERT_S(ByteArray)
|
||||
_PIQt_CONVERT_S(Time)
|
||||
_PIQt_CONVERT_S(Date)
|
||||
_PIQt_CONVERT_S(DateTime)
|
||||
_PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2)
|
||||
_PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3)
|
||||
|
||||
_PIQt_CONVERT_S(String) _PIQt_CONVERT_S(ByteArray) _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 qtpi __PIQtConvert
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef PIP_BINARY_STREAM
|
||||
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const QString & v) {s << Q2PIString(v); return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, QString & v) {PIString t; s >> t; v = PI2QString(t); return s;}
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const QStringList & v) {s << Q2PIStringList(v); return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, QStringList & v) {PIStringList t; s >> t; v = PI2QStringList(t); 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) {
|
||||
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) {
|
||||
inline PIByteArray &
|
||||
operator<<(PIByteArray & s, const QString & v) {
|
||||
s << Q2PIString(v);
|
||||
return s;
|
||||
}
|
||||
inline PIByteArray & operator>>(PIByteArray & s, QString & v) {
|
||||
PIString t;
|
||||
s >> t;
|
||||
v = PI2QString(t);
|
||||
return s;
|
||||
}
|
||||
inline PIByteArray & operator<<(PIByteArray & s, const QStringList & v) {
|
||||
s << Q2PIStringList(v);
|
||||
return s;
|
||||
}
|
||||
inline PIByteArray & operator>>(PIByteArray & s, QStringList & v) {
|
||||
PIStringList t;
|
||||
s >> t;
|
||||
v = PI2QStringList(t);
|
||||
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 P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, QVector<T> & v) {
|
||||
PIVector<T> t; s >> t;
|
||||
template<typename 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());
|
||||
for (int i = 0; i < t.size_s(); ++i)
|
||||
v[i] = t[i];
|
||||
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;
|
||||
t.reserve(v.size());
|
||||
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;
|
||||
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();
|
||||
PIMap<K, T> t; s >> t;
|
||||
PIMap<K, T> t;
|
||||
s >> t;
|
||||
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;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(QString) {s << Q2PIString(v); return s;}
|
||||
BINARY_STREAM_READ (QString) {PIString t; s >> t; v = PI2QString(t); return s;}
|
||||
BINARY_STREAM_WRITE(QString) {
|
||||
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_READ (QStringList) {PIStringList t; s >> t; v = PI2QStringList(t); return s;}
|
||||
BINARY_STREAM_WRITE(QStringList) {
|
||||
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_READ (QPolygonF) {QVector<QPointF> t; s >> t; v = t; return s;}
|
||||
BINARY_STREAM_WRITE(QPolygonF) {
|
||||
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_READ (QByteArray) {PIByteArray t; s >> t; v = PI2QByteArray(t); return s;}
|
||||
BINARY_STREAM_WRITE(QByteArray) {
|
||||
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_READ (QDate) {PIDate t; s >> t; v = PI2QDate(t); return s;}
|
||||
BINARY_STREAM_WRITE(QDate) {
|
||||
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_READ (QTime) {PITime t; s >> t; v = PI2QTime(t); return s;}
|
||||
BINARY_STREAM_WRITE(QTime) {
|
||||
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_READ (QDateTime) {PIDateTime t; s >> t; v = PI2QDateTime(t); return s;}
|
||||
BINARY_STREAM_WRITE(QDateTime) {
|
||||
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_READ (QVariant) {PIVariant t; s >> t; v = PI2QVariant(t); return s;}
|
||||
BINARY_STREAM_WRITE(QVariant) {
|
||||
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_READ (PropertyStorage) {PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s;}
|
||||
BINARY_STREAM_WRITE(PropertyStorage) {
|
||||
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_READ (QColor) {PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s;}
|
||||
BINARY_STREAM_WRITE(QColor) {
|
||||
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_READ (QAD::Enum) {PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s;}
|
||||
BINARY_STREAM_WRITE(QAD::Enum) {
|
||||
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_READ (QAD::File) {PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s;}
|
||||
BINARY_STREAM_WRITE(QAD::File) {
|
||||
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_READ (QAD::Dir) {PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s;}
|
||||
BINARY_STREAM_WRITE(QAD::Dir) {
|
||||
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_READ (QAD::IODevice) {PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s;}
|
||||
BINARY_STREAM_WRITE(QAD::IODevice) {
|
||||
s << QAD2PIIODevice(v);
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(QAD::IODevice) {
|
||||
PIVariantTypes::IODevice t;
|
||||
s >> t;
|
||||
v = PI2QADIODevice(t);
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(QImage) {
|
||||
QByteArray ba; QBuffer buf(&ba);
|
||||
QByteArray ba;
|
||||
QBuffer buf(&ba);
|
||||
v.save(&buf, "png");
|
||||
s << Q2PIByteArray(ba);
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ (QImage) {
|
||||
PIByteArray pba; s >> pba;
|
||||
BINARY_STREAM_READ(QImage) {
|
||||
PIByteArray pba;
|
||||
s >> pba;
|
||||
QByteArray ba = PI2QByteArray(pba);
|
||||
if (!v.loadFromData(ba, "png"))
|
||||
v = QImage();
|
||||
if (!v.loadFromData(ba, "png")) v = QImage();
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -360,7 +698,8 @@ BINARY_STREAM_READ (QImage) {
|
||||
|
||||
/// 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;
|
||||
QDataStream s(&ret, QIODevice::ReadWrite);
|
||||
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;
|
||||
}
|
||||
|
||||
template <typename T> T qDeserialize(const QByteArray & data, int version = -1) {
|
||||
template<typename T>
|
||||
T qDeserialize(const QByteArray & data, int version = -1) {
|
||||
T ret;
|
||||
if (!data.isEmpty()) {
|
||||
QDataStream s(data);
|
||||
@@ -382,13 +722,15 @@ template <typename T> T qDeserialize(const QByteArray & data, int version = -1)
|
||||
/// PIP with QByteArray
|
||||
|
||||
|
||||
template <typename T> QByteArray piqSerialize(const T & value) {
|
||||
template<typename T>
|
||||
QByteArray piqSerialize(const T & value) {
|
||||
PIByteArray ret;
|
||||
ret << value;
|
||||
return PI2QByteArray(ret);
|
||||
}
|
||||
|
||||
template <typename T> T piqDeserialize(const QByteArray & data) {
|
||||
template<typename T>
|
||||
T piqDeserialize(const QByteArray & data) {
|
||||
T ret;
|
||||
if (!data.isEmpty()) {
|
||||
PIByteArray ba = Q2PIByteArray(data);
|
||||
|
||||
@@ -1,78 +1,89 @@
|
||||
/*
|
||||
PIQt - PIP <-> Qt convertions
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQT_MACROS_H
|
||||
#define PIQT_MACROS_H
|
||||
|
||||
#include <piobject.h>
|
||||
#include <QObject>
|
||||
#include "qad_piqt_export.h"
|
||||
|
||||
|
||||
/// connect PIP event "event" of object "src" directly to Qt slot "slot" of object "tgt"
|
||||
/// e.g. PIQCONNECT(&pip_obj, someEvent, &qt_obj, someSlot)
|
||||
#define PIQCONNECT(src, event, tgt, slot) \
|
||||
PIQt::piqConnect(src, #event, &(src)->__stat_eh_##event##__, tgt, &decltype(PIQt::removePtr(tgt))::slot);
|
||||
|
||||
/// 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!
|
||||
/// e.g. PIQCONNECT_QUEUED(&pip_obj, someEvent, &qt_obj, someSlot)
|
||||
#define PIQCONNECT_QUEUED(src, 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"
|
||||
/// e.g. QPICONNECT(&qt_obj, someSignal, &pip_obj, someHandler)
|
||||
/// Returns QMetaObject::Connection
|
||||
#define QPICONNECT(src, sig, tgt, handler) \
|
||||
PIQt::qpiConnect(src, &decltype(PIQt::removePtr(src))::sig, tgt, &(tgt)->__stat_eh_##handler##__);
|
||||
|
||||
|
||||
namespace PIQt {
|
||||
|
||||
template<typename T> T removePtr(T*) {}
|
||||
template<typename T> QArgument<T> qargument(const T & v) {
|
||||
return QArgument<T>(
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
QMetaType::typeName(qMetaTypeId<T>())
|
||||
#else
|
||||
QMetaType::fromType<T>().name()
|
||||
#endif
|
||||
, 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>
|
||||
void piqConnectQ(PIObject * source, const char * event, void(*func)(void*,ARGS...), QObject * target, const char * slot) {
|
||||
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...);});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // PIQT_MACROS_H
|
||||
/*
|
||||
PIQt - PIP <-> Qt convertions
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQT_MACROS_H
|
||||
#define PIQT_MACROS_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"
|
||||
/// e.g. PIQCONNECT(&pip_obj, someEvent, &qt_obj, someSlot)
|
||||
#define PIQCONNECT(src, event, tgt, slot) \
|
||||
PIQt::piqConnect(src, #event, &(src)->__stat_eh_##event##__, tgt, &decltype(PIQt::removePtr(tgt))::slot);
|
||||
|
||||
/// 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!
|
||||
/// e.g. PIQCONNECT_QUEUED(&pip_obj, someEvent, &qt_obj, someSlot)
|
||||
#define PIQCONNECT_QUEUED(src, 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"
|
||||
/// e.g. QPICONNECT(&qt_obj, someSignal, &pip_obj, someHandler)
|
||||
/// Returns QMetaObject::Connection
|
||||
#define QPICONNECT(src, sig, tgt, handler) \
|
||||
PIQt::qpiConnect(src, &decltype(PIQt::removePtr(src))::sig, tgt, &(tgt)->__stat_eh_##handler##__);
|
||||
|
||||
|
||||
namespace PIQt {
|
||||
|
||||
template<typename T>
|
||||
T removePtr(T *) {}
|
||||
template<typename T>
|
||||
QArgument<T> qargument(const T & v) {
|
||||
return QArgument<T>(
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
QMetaType::typeName(qMetaTypeId<T>())
|
||||
#else
|
||||
QMetaType::fromType<T>().name()
|
||||
#endif
|
||||
,
|
||||
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>
|
||||
void piqConnectQ(PIObject * source, const char * event, void (*func)(void *, ARGS...), QObject * target, const char * slot) {
|
||||
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
|
||||
|
||||
@@ -18,13 +18,19 @@ bool QPIConnection::loadFromCMFile(const QString & file) {
|
||||
|
||||
|
||||
void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) {
|
||||
//piCout << from << PICoutManipulators::Hex << data;
|
||||
QMetaObject::invokeMethod(this, "qDataReceivedEvent", Qt::QueuedConnection,
|
||||
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data)));
|
||||
// piCout << from << PICoutManipulators::Hex << data;
|
||||
QMetaObject::invokeMethod(this,
|
||||
"qDataReceivedEvent",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(QString, PI2QString(from)),
|
||||
Q_ARG(QByteArray, PI2QByteArray(data)));
|
||||
}
|
||||
|
||||
|
||||
void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) {
|
||||
QMetaObject::invokeMethod(this, "qPacketReceivedEvent", Qt::QueuedConnection,
|
||||
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data)));
|
||||
QMetaObject::invokeMethod(this,
|
||||
"qPacketReceivedEvent",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(QString, PI2QString(from)),
|
||||
Q_ARG(QByteArray, PI2QByteArray(data)));
|
||||
}
|
||||
|
||||
@@ -1,56 +1,59 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QPICONNECTION_H
|
||||
#define QPICONNECTION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMetaObject>
|
||||
#include "piconnection.h"
|
||||
#include "qpiconfig.h"
|
||||
#include "piqt.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
|
||||
PIOBJECT_SUBCLASS(QPIConnection, PIConnection);
|
||||
|
||||
public:
|
||||
QPIConnection(const QString & name = QString());
|
||||
|
||||
|
||||
bool loadFromCMFile(const QString & file);
|
||||
|
||||
|
||||
protected:
|
||||
#if PIP_VERSION >= PIP_MAKE_VERSION(2,38,0)
|
||||
void propertyChanged(const char *) override {setObjectName(PI2QString(name()));}
|
||||
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 38, 0)
|
||||
void propertyChanged(const char *) override { setObjectName(PI2QString(name())); }
|
||||
#else
|
||||
void propertyChanged(const PIString &) override {setObjectName(PI2QString(name()));}
|
||||
void propertyChanged(const PIString &) override { setObjectName(PI2QString(name())); }
|
||||
#endif
|
||||
EVENT_HANDLER2(void, piDataRec, const PIString &, from, const PIByteArray &, data);
|
||||
EVENT_HANDLER2(void, piPacketRec, const PIString &, from, const PIByteArray &, data);
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
signals:
|
||||
void qDataReceivedEvent(QString from, QByteArray data);
|
||||
void qPacketReceivedEvent(QString from, QByteArray data);
|
||||
|
||||
};
|
||||
|
||||
#endif // QPICONNECTION_H
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "ui_piqt_connection_edit.h"
|
||||
#include "piqt_connection_edit.h"
|
||||
|
||||
#include "picodeinfo.h"
|
||||
#include "piqt.h"
|
||||
#include "piqt_connection_view.h"
|
||||
#include "piqt_highlighter.h"
|
||||
#include "piqt.h"
|
||||
#include "picodeinfo.h"
|
||||
#include "ui_piqt_connection_edit.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QMessageBox>
|
||||
|
||||
@@ -13,14 +15,15 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
|
||||
ui->setupUi(this);
|
||||
new ConfigHighlighter(ui->codeEdit->document());
|
||||
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()));
|
||||
conn = 0;
|
||||
conn = 0;
|
||||
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
#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));
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
#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));
|
||||
#else
|
||||
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
||||
#endif
|
||||
@@ -28,9 +31,9 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
|
||||
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
|
||||
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) {
|
||||
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) + ")"));
|
||||
#else
|
||||
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");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
#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));
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
#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));
|
||||
#else
|
||||
ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
||||
#endif
|
||||
@@ -61,13 +65,15 @@ ConnectionEdit::~ConnectionEdit() {
|
||||
|
||||
|
||||
void ConnectionEdit::accept() {
|
||||
//bool ok = false;
|
||||
QList<BlockItem * > bl = ui->blockView->allDevices();
|
||||
foreach (BlockItem * i, bl)
|
||||
foreach (BlockItem * j, bl)
|
||||
// bool ok = false;
|
||||
QList<BlockItem *> bl = ui->blockView->allDevices();
|
||||
foreach(BlockItem * i, bl)
|
||||
foreach(BlockItem * j, bl)
|
||||
if (i != j)
|
||||
if (((DeviceItem*)i)->name() == ((DeviceItem*)j)->name()) {
|
||||
QMessageBox::critical(this, windowTitle() + " - " + tr("error") + "!", tr("Equal devices names: \"%1\"!").arg(((DeviceItem*)i)->name()));
|
||||
if (((DeviceItem *)i)->name() == ((DeviceItem *)j)->name()) {
|
||||
QMessageBox::critical(this,
|
||||
windowTitle() + " - " + tr("error") + "!",
|
||||
tr("Equal devices names: \"%1\"!").arg(((DeviceItem *)i)->name()));
|
||||
return;
|
||||
}
|
||||
QDialog::accept();
|
||||
@@ -85,21 +91,19 @@ QByteArray ConnectionEdit::model() const {
|
||||
QDataStream s(&ret, QIODevice::ReadWrite);
|
||||
QString cn = PI2QString(conn ? conn->name() : PIString());
|
||||
s << cn;
|
||||
QList<BlockBusItem*> busl = ui->blockView->buses();
|
||||
QList<BlockBusItem *> busl = ui->blockView->buses();
|
||||
s << busl.size();
|
||||
foreach (BlockBusItem * b, busl)
|
||||
foreach(BlockBusItem * b, busl)
|
||||
s << b->save();
|
||||
QList<BlockItem*> blockl = ui->blockView->blocks();
|
||||
QList<BlockItem *> blockl = ui->blockView->blocks();
|
||||
s << blockl.size();
|
||||
foreach (BlockItem * b, blockl) {
|
||||
foreach(BlockItem * b, blockl) {
|
||||
int type = b->propertyByName("__type").value.toInt();
|
||||
s << type;
|
||||
switch (type) {
|
||||
case __CV_Device:
|
||||
case __CV_Filter:
|
||||
case __CV_Sender:
|
||||
s << b->save();
|
||||
break;
|
||||
case __CV_Sender: s << b->save(); break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -136,7 +140,9 @@ void ConnectionEdit::setModel(const QByteArray & m) {
|
||||
s >> sz;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
BlockBusItem * b = new BlockBusItem();
|
||||
QByteArray ba; s >> ba; b->load(ba);
|
||||
QByteArray ba;
|
||||
s >> ba;
|
||||
b->load(ba);
|
||||
ui->blockView->addItem(b);
|
||||
}
|
||||
s >> sz;
|
||||
@@ -148,26 +154,26 @@ void ConnectionEdit::setModel(const QByteArray & m) {
|
||||
switch (type) {
|
||||
case __CV_Device:
|
||||
b = new DeviceItem();
|
||||
s >> ba; b->load(ba);
|
||||
if (!b->isPropertyExists("bufferSize"))
|
||||
((DeviceItem*)b)->setBufferSize(4096);
|
||||
((DeviceItem*)b)->rename();
|
||||
s >> ba;
|
||||
b->load(ba);
|
||||
if (!b->isPropertyExists("bufferSize")) ((DeviceItem *)b)->setBufferSize(4096);
|
||||
((DeviceItem *)b)->rename();
|
||||
break;
|
||||
case __CV_Filter:
|
||||
b = new FilterItem();
|
||||
s >> ba; b->load(ba);
|
||||
if (!b->isPropertyExists("bufferSize"))
|
||||
((FilterItem*)b)->setBufferSize(65536);
|
||||
((FilterItem*)b)->rename();
|
||||
s >> ba;
|
||||
b->load(ba);
|
||||
if (!b->isPropertyExists("bufferSize")) ((FilterItem *)b)->setBufferSize(65536);
|
||||
((FilterItem *)b)->rename();
|
||||
break;
|
||||
case __CV_Sender:
|
||||
b = new SenderItem();
|
||||
s >> ba; b->load(ba);
|
||||
((SenderItem*)b)->rename();
|
||||
s >> ba;
|
||||
b->load(ba);
|
||||
((SenderItem *)b)->rename();
|
||||
break;
|
||||
}
|
||||
if (b)
|
||||
ui->blockView->addItem(b);
|
||||
if (b) ui->blockView->addItem(b);
|
||||
}
|
||||
ui->blockView->reconnectAll();
|
||||
loading = false;
|
||||
@@ -176,18 +182,18 @@ void ConnectionEdit::setModel(const QByteArray & m) {
|
||||
|
||||
|
||||
void ConnectionEdit::selectionChanged() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
|
||||
ui->buttonRemove->setEnabled(!si.isEmpty());
|
||||
ui->buttonDeviceModify->setEnabled(false);
|
||||
ui->buttonFilterModify->setEnabled(false);
|
||||
ui->buttonSenderModify->setEnabled(false);
|
||||
if (si.size() != 1) return;
|
||||
BlockItem * b = qgraphicsitem_cast<BlockItem*>(si[0]);
|
||||
BlockItem * b = qgraphicsitem_cast<BlockItem *>(si[0]);
|
||||
if (!b) return;
|
||||
int type = b->propertyByName("__type").value.toInt();
|
||||
if (type == __CV_Device) {
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
DeviceItem * di = (DeviceItem*)b;
|
||||
DeviceItem * di = (DeviceItem *)b;
|
||||
ui->buttonDeviceModify->setEnabled(true);
|
||||
for (int i = 0; i < ui->comboMode->count(); ++i)
|
||||
if (ui->comboMode->itemData(i).toInt() == di->mode()) {
|
||||
@@ -202,7 +208,7 @@ void ConnectionEdit::selectionChanged() {
|
||||
}
|
||||
if (type == __CV_Filter) {
|
||||
ui->tabWidget->setCurrentIndex(1);
|
||||
FilterItem * fi = (FilterItem*)b;
|
||||
FilterItem * fi = (FilterItem *)b;
|
||||
ui->buttonFilterModify->setEnabled(true);
|
||||
for (int i = 0; i < ui->comboSplit->count(); ++i)
|
||||
if (ui->comboSplit->itemData(i).toInt() == fi->mode()) {
|
||||
@@ -219,13 +225,12 @@ void ConnectionEdit::selectionChanged() {
|
||||
}
|
||||
if (type == __CV_Sender) {
|
||||
ui->tabWidget->setCurrentIndex(2);
|
||||
SenderItem * si = (SenderItem*)b;
|
||||
SenderItem * si = (SenderItem *)b;
|
||||
ui->buttonSenderModify->setEnabled(true);
|
||||
ui->lineSender->setText(si->name());
|
||||
ui->lineData->setText(si->data());
|
||||
ui->spinFrequency->setValue(si->frequency());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -268,10 +273,9 @@ void ConnectionEdit::applySender(SenderItem * b) {
|
||||
int ConnectionEdit::getOptions() const {
|
||||
int ret(0);
|
||||
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->isChecked())
|
||||
ret |= cb->property("__value").toInt();
|
||||
if (cb->isChecked()) ret |= cb->property("__value").toInt();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -279,27 +283,29 @@ int ConnectionEdit::getOptions() const {
|
||||
|
||||
void ConnectionEdit::setOptions(int o) {
|
||||
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;
|
||||
int cbf = cb->property("__value").toInt();
|
||||
//qDebug() << cbf;
|
||||
// qDebug() << cbf;
|
||||
cb->setChecked((o & cbf) == cbf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::recreateConnection() {
|
||||
//qDebug() << "recreate";
|
||||
// qDebug() << "recreate";
|
||||
if (loading) return;
|
||||
ui->blockView->reconnectAll();
|
||||
if (conn) delete conn;
|
||||
PIString cn = Q2PIString(ui->lineName->text());
|
||||
if (cn.isEmpty()) conn = new PIConnection();
|
||||
else conn = new PIConnection(cn);
|
||||
QList<BlockItem*> devs = ui->blockView->allDevices();
|
||||
foreach (BlockItem * b, devs) {
|
||||
DeviceItem * di = (DeviceItem*)b;
|
||||
//qDebug() << di->path();
|
||||
if (cn.isEmpty())
|
||||
conn = new PIConnection();
|
||||
else
|
||||
conn = new PIConnection(cn);
|
||||
QList<BlockItem *> devs = ui->blockView->allDevices();
|
||||
foreach(BlockItem * b, devs) {
|
||||
DeviceItem * di = (DeviceItem *)b;
|
||||
// qDebug() << di->path();
|
||||
PIIODevice * dev = conn->addDevice(Q2PIString(di->path()), di->mode());
|
||||
if (!dev) continue;
|
||||
dev->setOptions(di->options());
|
||||
@@ -308,35 +314,35 @@ void ConnectionEdit::recreateConnection() {
|
||||
PIDiagnostics * diag = conn->diagnostic(dev);
|
||||
if (diag) diag->setDisconnectTimeout(di->disconnectTimeout());
|
||||
}
|
||||
foreach (BlockItem * b, devs) {
|
||||
DeviceItem * di = (DeviceItem*)b;
|
||||
foreach(BlockItem * b, devs) {
|
||||
DeviceItem * di = (DeviceItem *)b;
|
||||
PIIODevice * dev = conn->deviceByName(Q2PIString(di->name()));
|
||||
if (!dev) continue;
|
||||
BlockItemPin * p = b->pinByText("read");
|
||||
if (!p) continue;
|
||||
QList<BlockBusItem*> buses = p->connectedBuses(), nbuses;
|
||||
QSet<BlockBusItem*> pbuses;
|
||||
QList<BlockBusItem *> buses = p->connectedBuses(), nbuses;
|
||||
QSet<BlockBusItem *> pbuses;
|
||||
while (!buses.isEmpty()) {
|
||||
nbuses.clear();
|
||||
foreach (BlockBusItem * bus, buses) {
|
||||
QList<BlockItem*> cb = bus->connectedBlocks();
|
||||
foreach(BlockBusItem * bus, buses) {
|
||||
QList<BlockItem *> cb = bus->connectedBlocks();
|
||||
if (cb.size() != 2) continue;
|
||||
FilterItem * fi_t(0);
|
||||
BlockItem * bi_f(0);
|
||||
if (cb[0]->pinAtBus(bus)->text() == "in") {
|
||||
fi_t = (FilterItem*)(cb[0]);
|
||||
fi_t = (FilterItem *)(cb[0]);
|
||||
bi_f = (cb[1]);
|
||||
} else if (cb[1]->pinAtBus(bus)->text() == "in") {
|
||||
fi_t = (FilterItem*)(cb[1]);
|
||||
fi_t = (FilterItem *)(cb[1]);
|
||||
bi_f = (cb[0]);
|
||||
}
|
||||
if (!fi_t || !bi_f) continue;
|
||||
PIString name_from;
|
||||
int type = bi_f->propertyByName("__type").value.toInt();
|
||||
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_Device) name_from = Q2PIString(((DeviceItem *)bi_f)->name());
|
||||
if (type == __CV_Filter) name_from = Q2PIString(((FilterItem *)bi_f)->name());
|
||||
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;
|
||||
pe->setHeader(PIByteArray::fromUserInput(Q2PIString(fi_t->header())));
|
||||
pe->setFooter(PIByteArray::fromUserInput(Q2PIString(fi_t->footer())));
|
||||
@@ -345,8 +351,8 @@ void ConnectionEdit::recreateConnection() {
|
||||
pe->setThreadedReadBufferSize(fi_t->bufferSize());
|
||||
PIDiagnostics * diag = conn->diagnostic(pe);
|
||||
if (diag) diag->setDisconnectTimeout(fi_t->disconnectTimeout());
|
||||
QList<BlockBusItem*> nb = fi_t->pinByText("out")->connectedBuses();
|
||||
foreach (BlockBusItem * b_, nb)
|
||||
QList<BlockBusItem *> nb = fi_t->pinByText("out")->connectedBuses();
|
||||
foreach(BlockBusItem * b_, nb)
|
||||
if (!pbuses.contains(b_)) {
|
||||
pbuses << b_;
|
||||
nbuses << b_;
|
||||
@@ -355,34 +361,34 @@ void ConnectionEdit::recreateConnection() {
|
||||
buses = nbuses;
|
||||
}
|
||||
}
|
||||
foreach (BlockItem * b, devs) {
|
||||
foreach(BlockItem * b, devs) {
|
||||
BlockItemPin * p = b->pinByText("write");
|
||||
if (!p) continue;
|
||||
QList<BlockBusItem*> buses = p->connectedBuses();
|
||||
foreach (BlockBusItem * bus, buses) {
|
||||
QList<BlockItem*> cb = bus->connectedBlocks();
|
||||
QList<BlockBusItem *> buses = p->connectedBuses();
|
||||
foreach(BlockBusItem * bus, buses) {
|
||||
QList<BlockItem *> cb = bus->connectedBlocks();
|
||||
if (cb.size() != 2) continue;
|
||||
BlockItem * bi_f(0);
|
||||
DeviceItem * di_t(0);
|
||||
if (cb[0]->pinAtBus(bus)->text() == "write") {
|
||||
di_t = (DeviceItem*)(cb[0]);
|
||||
di_t = (DeviceItem *)(cb[0]);
|
||||
bi_f = (cb[1]);
|
||||
} else if (cb[1]->pinAtBus(bus)->text() == "write") {
|
||||
di_t = (DeviceItem*)(cb[1]);
|
||||
di_t = (DeviceItem *)(cb[1]);
|
||||
bi_f = (cb[0]);
|
||||
}
|
||||
if (!bi_f || !di_t) continue;
|
||||
QString name_from;
|
||||
int type = bi_f->propertyByName("__type").value.toInt();
|
||||
if (type == __CV_Sender) {
|
||||
SenderItem * si = ((SenderItem*)bi_f);
|
||||
SenderItem * si = ((SenderItem *)bi_f);
|
||||
si->name();
|
||||
conn->addSender(Q2PIString(si->name()), Q2PIString(di_t->path()), si->frequency());
|
||||
if (!si->data().isEmpty())
|
||||
conn->setSenderFixedData(Q2PIString(si->name()), PIByteArray::fromUserInput(Q2PIString(si->data())));
|
||||
} else {
|
||||
if (type == __CV_Device) name_from = ((DeviceItem*)bi_f)->name();
|
||||
if (type == __CV_Filter) name_from = ((FilterItem*)bi_f)->name();
|
||||
if (type == __CV_Device) name_from = ((DeviceItem *)bi_f)->name();
|
||||
if (type == __CV_Filter) name_from = ((FilterItem *)bi_f)->name();
|
||||
if (name_from.isEmpty()) continue;
|
||||
conn->addChannel(Q2PIString(name_from), Q2PIString(di_t->name()));
|
||||
}
|
||||
@@ -411,12 +417,11 @@ void ConnectionEdit::on_buttonFilterAdd_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 (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter)
|
||||
return;
|
||||
applyFilter(qgraphicsitem_cast<FilterItem*>(si[0]));
|
||||
if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter) return;
|
||||
applyFilter(qgraphicsitem_cast<FilterItem *>(si[0]));
|
||||
}
|
||||
|
||||
|
||||
@@ -435,12 +440,11 @@ void ConnectionEdit::on_buttonDeviceAdd_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 (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Device)
|
||||
return;
|
||||
applyDevice(qgraphicsitem_cast<DeviceItem*>(si[0]));
|
||||
if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Device) return;
|
||||
applyDevice(qgraphicsitem_cast<DeviceItem *>(si[0]));
|
||||
}
|
||||
|
||||
|
||||
@@ -451,12 +455,11 @@ void ConnectionEdit::on_buttonSenderAdd_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 (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender)
|
||||
return;
|
||||
applySender(qgraphicsitem_cast<SenderItem*>(si[0]));
|
||||
if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender) return;
|
||||
applySender(qgraphicsitem_cast<SenderItem *>(si[0]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_EDIT_H
|
||||
#define CONNECTION_EDIT_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "piconnection.h"
|
||||
#include "qad_piqt_utils_export.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class ConnectionEdit;
|
||||
class ConnectionEdit;
|
||||
}
|
||||
|
||||
class FilterItem;
|
||||
@@ -35,18 +36,19 @@ class SenderItem;
|
||||
|
||||
class QAD_PIQT_UTILS_EXPORT ConnectionEdit: public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConnectionEdit(QWidget * parent = 0);
|
||||
~ConnectionEdit();
|
||||
|
||||
|
||||
QString configuration() const;
|
||||
QByteArray model() const;
|
||||
QString name() const;
|
||||
|
||||
|
||||
void setName(const QString & name);
|
||||
void addDevice(const QString & name, const QString & path);
|
||||
void setModel(const QByteArray & m);
|
||||
|
||||
|
||||
private:
|
||||
void accept();
|
||||
void keyPressEvent(QKeyEvent *) {}
|
||||
@@ -55,14 +57,16 @@ private:
|
||||
void applySender(SenderItem * b);
|
||||
int getOptions() const;
|
||||
void setOptions(int o);
|
||||
|
||||
|
||||
Ui::ConnectionEdit * ui;
|
||||
PIConnection * conn;
|
||||
bool loading;
|
||||
int udevicenum;
|
||||
|
||||
|
||||
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_buttonClear_clicked();
|
||||
void on_buttonFilterAdd_clicked();
|
||||
@@ -73,10 +77,9 @@ private slots:
|
||||
void on_buttonSenderModify_clicked();
|
||||
void on_comboSplit_currentIndexChanged(int index);
|
||||
void selectionChanged();
|
||||
|
||||
|
||||
public slots:
|
||||
void recreateConnection();
|
||||
|
||||
};
|
||||
|
||||
#endif // CONNECTION_EDIT_H
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "piqt_connection_view.h"
|
||||
|
||||
#include "picodeinfo.h"
|
||||
#include "piqt.h"
|
||||
|
||||
#include <alignedtextitem.h>
|
||||
|
||||
|
||||
@@ -11,7 +13,8 @@ DeviceItem::DeviceItem(): BlockItem() {
|
||||
setColor(QColor(192, 192, 255));
|
||||
text_name = 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->setFont(fnt);
|
||||
text_name->setPos(0., -size().height() / 2.);
|
||||
@@ -29,19 +32,29 @@ DeviceItem::DeviceItem(): BlockItem() {
|
||||
|
||||
void DeviceItem::rename() {
|
||||
QString ms;
|
||||
BlockItemPin * pr = pinByText("read"), * pw = pinByText("write");
|
||||
BlockItemPin *pr = pinByText("read"), *pw = pinByText("write");
|
||||
switch (mode()) {
|
||||
case PIIODevice::ReadOnly: ms = "ro"; 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;
|
||||
case PIIODevice::ReadOnly:
|
||||
ms = "ro";
|
||||
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_path->setText(path());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FilterItem::FilterItem(): BlockItem() {
|
||||
addProperty(BlockItem::Property("__type", "", __CV_Filter));
|
||||
addProperty(BlockItem::Property("bufferSize", "", 65536));
|
||||
@@ -50,7 +63,8 @@ FilterItem::FilterItem(): BlockItem() {
|
||||
setColor(QColor(192, 255, 192));
|
||||
text_name = 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->setFont(fnt);
|
||||
text_name->setPos(0., -size().height() / 2.);
|
||||
@@ -71,9 +85,9 @@ void FilterItem::rename() {
|
||||
QString ms;
|
||||
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode", 0);
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & i, ei->members)
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & i, ei->members)
|
||||
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());
|
||||
#else
|
||||
ms = PI2QString(i.name);
|
||||
@@ -82,20 +96,18 @@ void FilterItem::rename() {
|
||||
}
|
||||
}
|
||||
text_mode->setText(ms);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SenderItem::SenderItem(): BlockItem() {
|
||||
addProperty(BlockItem::Property("__type", "", __CV_Sender));
|
||||
setSize(140, 80);
|
||||
setPos(-200, 0);
|
||||
setColor(QColor(255, 192, 192));
|
||||
text_name = new AlignedTextItem();
|
||||
text_name = 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->setFont(fnt);
|
||||
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) {
|
||||
@@ -166,10 +174,9 @@ SenderItem * ConnectionView::addSender(const QString & name) {
|
||||
|
||||
|
||||
DeviceItem * ConnectionView::findDevice(const QString & name) const {
|
||||
QList<BlockItem*> blockl = blocks();
|
||||
foreach (BlockItem * b, blockl)
|
||||
if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device))
|
||||
return (DeviceItem*)b;
|
||||
QList<BlockItem *> blockl = blocks();
|
||||
foreach(BlockItem * b, blockl)
|
||||
if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device)) return (DeviceItem *)b;
|
||||
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;
|
||||
QList<QRectF> collr;
|
||||
foreach (BlockItem * i, coll)
|
||||
foreach(BlockItem * i, coll)
|
||||
collr << i->sceneBoundingRect();
|
||||
while (true) {
|
||||
QRectF br = b->sceneBoundingRect();
|
||||
bool ok = true;
|
||||
bool ok = true;
|
||||
for (int i = 0; i < collr.size(); ++i)
|
||||
if (br.intersects(collr[i])) {
|
||||
ok = false;
|
||||
@@ -199,10 +206,9 @@ void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem * > coll) {
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > ConnectionView::allByType(int type_) const {
|
||||
QList<BlockItem*> blockl = blocks(), ret;
|
||||
foreach (BlockItem * b, blockl)
|
||||
if (b->propertyByName("__type").value.toInt() == type_)
|
||||
ret << b;
|
||||
QList<BlockItem *> ConnectionView::allByType(int type_) const {
|
||||
QList<BlockItem *> blockl = blocks(), ret;
|
||||
foreach(BlockItem * b, blockl)
|
||||
if (b->propertyByName("__type").value.toInt() == type_) ret << b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_VIEW_H
|
||||
@@ -32,102 +32,150 @@ const int __CV_Sender = 3;
|
||||
class QAD_PIQT_UTILS_EXPORT DeviceItem: public BlockItem {
|
||||
public:
|
||||
DeviceItem();
|
||||
|
||||
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
|
||||
void setPath(const QString & p) {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 path() const {return propertyByName("device").value.toString();}
|
||||
PIIODevice::DeviceMode mode() const {return PIIODevice::DeviceMode(propertyByName("mode").value.toInt());}
|
||||
PIIODevice::DeviceOptions options() const {return PIIODevice::DeviceOptions(propertyByName("options").value.toInt());}
|
||||
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();}
|
||||
int bufferSize() const {return propertyByName("bufferSize").value.toInt();}
|
||||
|
||||
|
||||
void setName(const QString & n) {
|
||||
addProperty(BlockItem::Property("name", "", n));
|
||||
rename();
|
||||
}
|
||||
void setPath(const QString & p) {
|
||||
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 path() const { return propertyByName("device").value.toString(); }
|
||||
PIIODevice::DeviceMode mode() const { return PIIODevice::DeviceMode(propertyByName("mode").value.toInt()); }
|
||||
PIIODevice::DeviceOptions options() const { return PIIODevice::DeviceOptions(propertyByName("options").value.toInt()); }
|
||||
double disconnectTimeout() const { return propertyByName("disconnectTimeout").value.toDouble(); }
|
||||
int bufferSize() const { return propertyByName("bufferSize").value.toInt(); }
|
||||
|
||||
void rename();
|
||||
|
||||
|
||||
protected:
|
||||
AlignedTextItem * text_name, * text_path;
|
||||
|
||||
AlignedTextItem *text_name, *text_path;
|
||||
};
|
||||
|
||||
|
||||
class QAD_PIQT_UTILS_EXPORT FilterItem: public BlockItem {
|
||||
public:
|
||||
FilterItem();
|
||||
|
||||
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
|
||||
void setMode(PIPacketExtractor::SplitMode m) {addProperty(BlockItem::Property("mode", "", int(m))); 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();}
|
||||
PIPacketExtractor::SplitMode mode() const {return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt());}
|
||||
QString header() const {return propertyByName("header").value.toString();}
|
||||
QString footer() const {return propertyByName("footer").value.toString();}
|
||||
double timeout() const {return propertyByName("timeout").value.toDouble();}
|
||||
int packetSize() const {return propertyByName("size").value.toInt();}
|
||||
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();}
|
||||
int bufferSize() const {return propertyByName("bufferSize").value.toInt();}
|
||||
void setName(const QString & n) {
|
||||
addProperty(BlockItem::Property("name", "", n));
|
||||
rename();
|
||||
}
|
||||
void setMode(PIPacketExtractor::SplitMode m) {
|
||||
addProperty(BlockItem::Property("mode", "", int(m)));
|
||||
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(); }
|
||||
PIPacketExtractor::SplitMode mode() const { return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt()); }
|
||||
QString header() const { return propertyByName("header").value.toString(); }
|
||||
QString footer() const { return propertyByName("footer").value.toString(); }
|
||||
double timeout() const { return propertyByName("timeout").value.toDouble(); }
|
||||
int packetSize() const { return propertyByName("size").value.toInt(); }
|
||||
double disconnectTimeout() const { return propertyByName("disconnectTimeout").value.toDouble(); }
|
||||
int bufferSize() const { return propertyByName("bufferSize").value.toInt(); }
|
||||
|
||||
void rename();
|
||||
|
||||
|
||||
protected:
|
||||
AlignedTextItem * text_name, * text_mode;
|
||||
|
||||
AlignedTextItem *text_name, *text_mode;
|
||||
};
|
||||
|
||||
|
||||
class QAD_PIQT_UTILS_EXPORT SenderItem: public BlockItem {
|
||||
public:
|
||||
SenderItem();
|
||||
|
||||
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); 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 data() const {return propertyByName("data").value.toString();}
|
||||
double frequency() const {return propertyByName("frequency").value.toDouble();}
|
||||
|
||||
|
||||
void setName(const QString & n) {
|
||||
addProperty(BlockItem::Property("name", "", n));
|
||||
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 data() const { return propertyByName("data").value.toString(); }
|
||||
double frequency() const { return propertyByName("frequency").value.toDouble(); }
|
||||
|
||||
void rename();
|
||||
|
||||
|
||||
protected:
|
||||
AlignedTextItem * text_name, * text_frequency;
|
||||
|
||||
AlignedTextItem *text_name, *text_frequency;
|
||||
};
|
||||
|
||||
|
||||
class QAD_PIQT_UTILS_EXPORT ConnectionView: public BlockView {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConnectionView(QWidget * parent = 0);
|
||||
~ConnectionView();
|
||||
|
||||
|
||||
DeviceItem * addDevice(const QString & name, const QString & path);
|
||||
FilterItem * addFilter(const QString & name);
|
||||
SenderItem * addSender(const QString & name);
|
||||
DeviceItem * findDevice(const QString & name) const;
|
||||
QList<BlockItem * > allDevices() const {return allByType(__CV_Device);}
|
||||
QList<BlockItem * > allFilters() const {return allByType(__CV_Filter);}
|
||||
QList<BlockItem * > allSenders() const {return allByType(__CV_Sender);}
|
||||
|
||||
QList<BlockItem *> allDevices() const { return allByType(__CV_Device); }
|
||||
QList<BlockItem *> allFilters() const { return allByType(__CV_Filter); }
|
||||
QList<BlockItem *> allSenders() const { return allByType(__CV_Sender); }
|
||||
|
||||
private:
|
||||
QSize sizeHint() const {return QSize(800, 600);}
|
||||
QSize sizeHint() const { return QSize(800, 600); }
|
||||
void loadBus(BlockBusItem * bus);
|
||||
void placeBlock(BlockItem * b, QList<BlockItem*> coll);
|
||||
|
||||
QList<BlockItem * > allByType(int type_) const;
|
||||
|
||||
void placeBlock(BlockItem * b, QList<BlockItem *> coll);
|
||||
|
||||
QList<BlockItem *> allByType(int type_) const;
|
||||
|
||||
private slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // CONNECTION_VIEW_H
|
||||
|
||||
@@ -6,30 +6,30 @@ ConfigHighlighter::ConfigHighlighter(QTextDocument * parent): QSyntaxHighlighter
|
||||
|
||||
valueNameFormat.setForeground(QColor(0, 64, 154));
|
||||
rule.pattern = QRegularExpression("[^=]"); //"\\b[A-Za-z0-9_]+(?=\\()");
|
||||
rule.format = valueNameFormat;
|
||||
rule.format = valueNameFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
valueFormat.setForeground(QColor(192, 0, 0));
|
||||
rule.pattern = QRegularExpression("=[^\n]*");
|
||||
rule.format = valueFormat;
|
||||
rule.format = valueFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
equalFormat.setFontWeight(QFont::Bold);
|
||||
equalFormat.setForeground(QColor(96, 126, 0));
|
||||
rule.pattern = QRegularExpression("=");
|
||||
rule.format = equalFormat;
|
||||
rule.format = equalFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
sectionFormat.setFontWeight(QFont::Bold);
|
||||
sectionFormat.setForeground(QColor(0, 32, 64));
|
||||
rule.pattern = QRegularExpression("\\[.*\\]");
|
||||
rule.format = sectionFormat;
|
||||
rule.format = sectionFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
substFormat.setForeground(QColor(192, 0, 192));
|
||||
rule.pattern = QRegularExpression("\\$\\{.*\\}+");
|
||||
//rule.pattern.setMinimal(true);
|
||||
rule.format = substFormat;
|
||||
// rule.pattern.setMinimal(true);
|
||||
rule.format = substFormat;
|
||||
highlightingRules.append(rule);
|
||||
rule.pattern = QRegularExpression("\\$\\{[^\\{]*\\}+");
|
||||
highlightingRules.append(rule);
|
||||
@@ -37,18 +37,18 @@ ConfigHighlighter::ConfigHighlighter(QTextDocument * parent): QSyntaxHighlighter
|
||||
singleLineCommentFormat.setFontItalic(true);
|
||||
singleLineCommentFormat.setForeground(QColor(128, 128, 128));
|
||||
rule.pattern = QRegularExpression("#[^\n]*");
|
||||
rule.format = singleLineCommentFormat;
|
||||
rule.format = singleLineCommentFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
spaceFormat.setForeground(QColor(210, 210, 210));
|
||||
|
||||
//commentStartExpression = QRegExp("/\\*");
|
||||
//commentEndExpression = QRegExp("\\*/");
|
||||
|
||||
// commentStartExpression = QRegExp("/\\*");
|
||||
// commentEndExpression = QRegExp("\\*/");
|
||||
}
|
||||
|
||||
|
||||
void ConfigHighlighter::highlightBlock(const QString & text) {
|
||||
foreach (const HighlightingRule &rule, highlightingRules) {
|
||||
foreach(const HighlightingRule & rule, highlightingRules) {
|
||||
QRegularExpression expression(rule.pattern);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QRegularExpressionMatchIterator i = expression.globalMatch(text);
|
||||
@@ -66,7 +66,7 @@ void ConfigHighlighter::highlightBlock(const QString & text) {
|
||||
#endif
|
||||
}
|
||||
setCurrentBlockState(0);
|
||||
|
||||
|
||||
QRegularExpression expression("[ |\t]");
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QRegularExpressionMatchIterator i = expression.globalMatch(text);
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONF_HIGHLIGHTER_H
|
||||
#define CONF_HIGHLIGHTER_H
|
||||
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextCursor>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextCursor>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
# include <QRegularExpression>
|
||||
#else
|
||||
# include <QRegExp>
|
||||
typedef QRegExp QRegularExpression;
|
||||
typedef QRegExp QRegularExpression;
|
||||
#endif
|
||||
#include "qad_piqt_utils_export.h"
|
||||
|
||||
class QTextDocument;
|
||||
|
||||
class QAD_PIQT_UTILS_EXPORT ConfigHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
class QAD_PIQT_UTILS_EXPORT ConfigHighlighter: public QSyntaxHighlighter {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ConfigHighlighter(QTextDocument *parent = 0);
|
||||
ConfigHighlighter(QTextDocument * parent = 0);
|
||||
|
||||
QTextCursor cursor;
|
||||
|
||||
private:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
void highlightBlock(const QString & text);
|
||||
|
||||
struct QAD_PIQT_UTILS_EXPORT HighlightingRule {
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#include "piqt_iodevice_edit.h"
|
||||
|
||||
#include "piqt_iodevice_edit_dialog.h"
|
||||
#include "qvariantedit_custom.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QToolButton>
|
||||
#include <QBoxLayout>
|
||||
#include <piqt.h>
|
||||
#include <piiodevice.h>
|
||||
#include <piqt.h>
|
||||
|
||||
|
||||
IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) {
|
||||
dlg = new IODeviceEditDialog();
|
||||
dlg = new IODeviceEditDialog();
|
||||
line = new QLineEdit();
|
||||
btn = new QToolButton();
|
||||
btn = new QToolButton();
|
||||
setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
layout()->addWidget(line);
|
||||
@@ -65,11 +67,10 @@ void IODeviceEdit::buttonDlg_clicked() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Factory: public QVariantEditorFactoryBase {
|
||||
public:
|
||||
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) {
|
||||
PIVariantTypes::IODevice sd = Q2PIVariant(v).toIODevice();
|
||||
// piCout << sd;
|
||||
PIIODevice * rd = PIIODevice::createFromVariant(sd);
|
||||
// piCout << sd;
|
||||
PIIODevice * rd = PIIODevice::createFromVariant(sd);
|
||||
if (rd) {
|
||||
PIString ps = rd->constructFullPath();
|
||||
r = PI2QString(ps);
|
||||
r = PI2QString(ps);
|
||||
} else {
|
||||
piCout << "error in " << sd;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQT_IODEVICE_EDIT_H
|
||||
#define PIQT_IODEVICE_EDIT_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qad_types.h"
|
||||
#include "qad_piqt_utils_export.h"
|
||||
#include "qad_types.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLineEdit;
|
||||
class QToolButton;
|
||||
@@ -33,13 +34,14 @@ class QAD_PIQT_UTILS_EXPORT IODeviceEdit: public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
|
||||
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
|
||||
|
||||
public:
|
||||
explicit IODeviceEdit(QWidget * parent = 0);
|
||||
~IODeviceEdit();
|
||||
|
||||
|
||||
QVariant value() const;
|
||||
bool isReadOnly() const;
|
||||
|
||||
|
||||
private:
|
||||
void setDevice(const QAD::IODevice & d);
|
||||
|
||||
@@ -47,7 +49,7 @@ private:
|
||||
QToolButton * btn;
|
||||
IODeviceEditDialog * dlg;
|
||||
QAD::IODevice dev;
|
||||
|
||||
|
||||
public slots:
|
||||
void setValue(const QVariant & v);
|
||||
void setReadOnly(bool yes);
|
||||
@@ -57,7 +59,6 @@ private slots:
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "ui_piqt_iodevice_edit_dialog.h"
|
||||
#include "piqt_iodevice_edit_dialog.h"
|
||||
#include "piqt.h"
|
||||
|
||||
#include "picodeinfo.h"
|
||||
#include "piiodevice.h"
|
||||
#include "piqt.h"
|
||||
#include "ui_piqt_iodevice_edit_dialog.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
|
||||
@@ -11,9 +13,10 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
|
||||
ui->setupUi(this);
|
||||
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
#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));
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
#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));
|
||||
#else
|
||||
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
||||
#endif
|
||||
@@ -21,9 +24,9 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
|
||||
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
|
||||
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
|
||||
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) {
|
||||
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) + ")"));
|
||||
#else
|
||||
cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"));
|
||||
@@ -33,23 +36,21 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
|
||||
}
|
||||
}
|
||||
PIStringList pl = PIIODevice::availablePrefixes();
|
||||
piForeachC (PIString & p, pl) {
|
||||
piForeachC(PIString & p, pl) {
|
||||
ui->comboType->addItem(PI2QString(p));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IODeviceEditDialog::~IODeviceEditDialog() {
|
||||
}
|
||||
IODeviceEditDialog::~IODeviceEditDialog() {}
|
||||
|
||||
|
||||
int IODeviceEditDialog::getOptions() const {
|
||||
int ret = 0;
|
||||
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->isChecked())
|
||||
ret |= cb->property("__value").toInt();
|
||||
if (cb->isChecked()) ret |= cb->property("__value").toInt();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -57,7 +58,7 @@ int IODeviceEditDialog::getOptions() const {
|
||||
|
||||
void IODeviceEditDialog::setOptions(int o) {
|
||||
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;
|
||||
int cbf = cb->property("__value").toInt();
|
||||
cb->setChecked((o & cbf) == cbf);
|
||||
@@ -67,7 +68,7 @@ void IODeviceEditDialog::setOptions(int o) {
|
||||
|
||||
void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) {
|
||||
PIString prefix = Q2PIString(ui->comboType->currentText());
|
||||
auto * d = PIIODevice::createFromFullPath(prefix + "://");
|
||||
auto * d = PIIODevice::createFromFullPath(prefix + "://");
|
||||
if (d) {
|
||||
ps = PI2QPropertyStorage(d->constructVariant().get());
|
||||
ui->widgetProperties->setStorage(&ps);
|
||||
@@ -78,8 +79,7 @@ void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) {
|
||||
|
||||
QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) {
|
||||
setValue(d);
|
||||
if (QDialog::exec() != QDialog::Accepted)
|
||||
return QAD::IODevice();
|
||||
if (QDialog::exec() != QDialog::Accepted) return QAD::IODevice();
|
||||
return value();
|
||||
}
|
||||
|
||||
@@ -87,10 +87,10 @@ QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) {
|
||||
QAD::IODevice IODeviceEditDialog::value() const {
|
||||
QAD::IODevice d;
|
||||
ui->widgetProperties->applyProperties();
|
||||
d.prefix = ui->comboType->currentText();
|
||||
d.mode = ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt();
|
||||
d.prefix = ui->comboType->currentText();
|
||||
d.mode = ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt();
|
||||
d.options = getOptions();
|
||||
d.props = ps;
|
||||
d.props = ps;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +1,42 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQT_IODEVICE_EDIT_DIALOG_H
|
||||
#define PIQT_IODEVICE_EDIT_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "qad_types.h"
|
||||
#include "propertystorage.h"
|
||||
#include "qad_piqt_utils_export.h"
|
||||
#include "qad_types.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class IODeviceEditDialog;
|
||||
class IODeviceEditDialog;
|
||||
}
|
||||
|
||||
class QAD_PIQT_UTILS_EXPORT IODeviceEditDialog: public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit IODeviceEditDialog(QWidget * parent = 0);
|
||||
~IODeviceEditDialog();
|
||||
|
||||
|
||||
QAD::IODevice getIODevice(const QAD::IODevice & d);
|
||||
|
||||
private:
|
||||
@@ -45,10 +47,9 @@ private:
|
||||
|
||||
PropertyStorage ps;
|
||||
Ui::IODeviceEditDialog * ui;
|
||||
|
||||
|
||||
private slots:
|
||||
void on_comboType_currentIndexChanged(int index);
|
||||
|
||||
};
|
||||
|
||||
#endif // PIQT_IODEVICE_EDIT_DIALOG_H
|
||||
|
||||
@@ -104,7 +104,7 @@ void PIValueTreeEdit::build() {
|
||||
widget_array = new QWidget();
|
||||
ui_array->setupUi(widget_array);
|
||||
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->widgetEdit->setVisible(source.attribute(PIValueTree::attributeArrayResize, false).toBool());
|
||||
ui_array->layoutArray->addWidget(grid);
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef pivaluetree_edit_H
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef pivariant_edit_H
|
||||
|
||||
@@ -36,7 +36,7 @@ PIVariantMap PIVariantEditors::Int::defaultAttributes() const {
|
||||
|
||||
void PIVariantEditors::Int::applyAttributes(const PIVariantMap & a) {
|
||||
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->setPrefix(PI2QString(a.value(PIValueTree::attributePrefix, Q2PIString(widget->prefix())).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) {
|
||||
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->setDecimals(a.value(PIValueTree::attributeDecimals, widget->decimals()).toInt());
|
||||
widget->setPrefix(PI2QString(a.value(PIValueTree::attributePrefix, Q2PIString(widget->prefix())).toString()));
|
||||
|
||||
@@ -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
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef pivariant_edit_widgets_H
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -21,20 +21,20 @@
|
||||
|
||||
|
||||
Camera::Camera() {
|
||||
type_ = glCamera;
|
||||
fov_ = 60.;
|
||||
type_ = glCamera;
|
||||
fov_ = 60.;
|
||||
angle_limit_lower_xy = 0.f;
|
||||
angle_limit_upper_xy = 360.f;
|
||||
angles_.setY(270.f);
|
||||
depth_start = 0.1f;
|
||||
depth_end = 1000.f;
|
||||
depth_end = 1000.f;
|
||||
mirror_x = mirror_y = false;
|
||||
}
|
||||
|
||||
|
||||
void Camera::anglesFromPoints() {
|
||||
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_.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) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
if (aspect <= 1.f)
|
||||
glScalef(aspect, aspect, 1.f);
|
||||
if (aspect <= 1.f) glScalef(aspect, aspect, 1.f);
|
||||
QMatrix4x4 pm = glMatrixPerspective(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;
|
||||
// pm.perspective(fov_, aspect, depth_start, depth_end);
|
||||
// qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end);
|
||||
// qDebug() << pm;
|
||||
setGLMatrix(pm);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
pm.setToIdentity();
|
||||
@@ -55,17 +54,17 @@ void Camera::apply(const GLfloat & aspect) {
|
||||
pm.rotate(angles_.y(), 1., 0., 0.);
|
||||
pm.rotate(angles_.x(), 0., 1., 0.);
|
||||
pm.rotate(angles_.z(), 0., 0., 1.);
|
||||
//pm.translate(-aim_);
|
||||
// pm.translate(-aim_);
|
||||
if (parent_) {
|
||||
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.translate(aim_);
|
||||
pm *= pmat.inverted();
|
||||
//qDebug() << pmat;
|
||||
// qDebug() << pmat;
|
||||
}
|
||||
setGLMatrix(pm);
|
||||
//qDebug() << angles_;
|
||||
// qDebug() << angles_;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,65 +76,65 @@ QMatrix4x4 Camera::offsetMatrix() const {
|
||||
|
||||
/*
|
||||
void Camera::localTransform(QMatrix4x4 & m) {
|
||||
return;
|
||||
if (parent_)
|
||||
m *= parent_->worldTransform();
|
||||
QMatrix4x4 ret;
|
||||
//qDebug() << "local camera";
|
||||
ret.translate(0., 0., -distance());
|
||||
ret.rotate(angles_.y(), 1., 0., 0.);
|
||||
ret.rotate(angles_.x(), 0., 1., 0.);
|
||||
ret.rotate(angles_.z(), 0., 0., 1.);
|
||||
//m *= ret.inverted();
|
||||
return;
|
||||
if (parent_)
|
||||
m *= parent_->worldTransform();
|
||||
QMatrix4x4 ret;
|
||||
//qDebug() << "local camera";
|
||||
ret.translate(0., 0., -distance());
|
||||
ret.rotate(angles_.y(), 1., 0., 0.);
|
||||
ret.rotate(angles_.x(), 0., 1., 0.);
|
||||
ret.rotate(angles_.z(), 0., 0., 1.);
|
||||
//m *= ret.inverted();
|
||||
}
|
||||
*/
|
||||
|
||||
void Camera::assign(const Camera & c) {
|
||||
pos_ = c.pos_;
|
||||
aim_ = c.aim_;
|
||||
fov_ = c.fov_;
|
||||
angles_ = c.angles_;
|
||||
pos_ = c.pos_;
|
||||
aim_ = c.aim_;
|
||||
fov_ = c.fov_;
|
||||
angles_ = c.angles_;
|
||||
angle_limit_lower_xy = c.angle_limit_lower_xy;
|
||||
angle_limit_upper_xy = c.angle_limit_upper_xy;
|
||||
mirror_x = c.mirror_x;
|
||||
mirror_y = c.mirror_y;
|
||||
depth_start = c.depth_start;
|
||||
depth_end = c.depth_end;
|
||||
mirror_x = c.mirror_x;
|
||||
mirror_y = c.mirror_y;
|
||||
depth_start = c.depth_start;
|
||||
depth_end = c.depth_end;
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
GLObjectBase * Camera::clone(bool withChildren) {
|
||||
Camera * o = new Camera(*this);
|
||||
//GLObjectBase::clone(withChildren);
|
||||
// GLObjectBase::clone(withChildren);
|
||||
o->is_init = false;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->children_.clear();
|
||||
if (withChildren) {
|
||||
for (int i = 0; i < children_.size(); ++i)
|
||||
o->addChild(children_[i]->clone(withChildren));
|
||||
}
|
||||
o->pos_ = pos_;
|
||||
o->aim_ = aim_;
|
||||
o->fov_ = fov_;
|
||||
o->angles_ = angles_;
|
||||
o->pos_ = pos_;
|
||||
o->aim_ = aim_;
|
||||
o->fov_ = fov_;
|
||||
o->angles_ = angles_;
|
||||
o->angle_limit_lower_xy = angle_limit_lower_xy;
|
||||
o->angle_limit_upper_xy = angle_limit_upper_xy;
|
||||
o->mirror_x = mirror_x;
|
||||
o->mirror_y = mirror_y;
|
||||
o->depth_start = depth_start;
|
||||
o->depth_end = depth_end;
|
||||
o->meta = meta;
|
||||
o->mirror_x = mirror_x;
|
||||
o->mirror_y = mirror_y;
|
||||
o->depth_start = depth_start;
|
||||
o->depth_end = depth_end;
|
||||
o->meta = meta;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
void Camera::panZ(const float & a) {
|
||||
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);
|
||||
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;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -143,11 +142,11 @@ void Camera::panZ(const float & a) {
|
||||
|
||||
void Camera::panXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(angles_.y() + a);
|
||||
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
aim_ = pos_ + dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -155,9 +154,9 @@ void Camera::panXY(const float & a) {
|
||||
|
||||
void Camera::rotateZ(const float & a) {
|
||||
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);
|
||||
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;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -165,11 +164,11 @@ void Camera::rotateZ(const float & a) {
|
||||
|
||||
void Camera::rotateXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(angles_.y() + a);
|
||||
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
aim_ = pos_ + dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -177,9 +176,9 @@ void Camera::rotateXY(const float & a) {
|
||||
|
||||
void Camera::orbitZ(const float & a) {
|
||||
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);
|
||||
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;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -187,11 +186,11 @@ void Camera::orbitZ(const float & a) {
|
||||
|
||||
void Camera::orbitXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(angles_.y() + a);
|
||||
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -199,9 +198,9 @@ void Camera::orbitXY(const float & a) {
|
||||
|
||||
void Camera::setAngleZ(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
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;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -209,21 +208,21 @@ void Camera::setAngleZ(const float & a) {
|
||||
|
||||
void Camera::setAngleXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(a);
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
//pos_ = aim_ - dv;
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
// pos_ = aim_ - dv;
|
||||
aim_ = pos_ + dv * tl;
|
||||
buildTransform();
|
||||
//anglesFromPoints();
|
||||
// anglesFromPoints();
|
||||
}
|
||||
|
||||
|
||||
void Camera::moveForward(const float & x, bool withZ) {
|
||||
QVector3D dv;// = aim_ - pos_;
|
||||
QVector3D dv; // = aim_ - pos_;
|
||||
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));
|
||||
dv.normalize();
|
||||
dv *= x;
|
||||
@@ -234,9 +233,9 @@ void Camera::moveForward(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);
|
||||
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));
|
||||
dv.normalize();
|
||||
dv *= x;
|
||||
@@ -252,7 +251,7 @@ void Camera::moveUp(const float & x, bool onlyZ) {
|
||||
dv = QVector3D(0., 0., x);
|
||||
else {
|
||||
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 *= x;
|
||||
}
|
||||
@@ -265,7 +264,7 @@ void Camera::moveUp(const float & x, bool onlyZ) {
|
||||
void Camera::flyCloser(const float & s) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
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;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -274,7 +273,7 @@ void Camera::flyCloser(const float & s) {
|
||||
void Camera::flyFarer(const float & s) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
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;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -282,9 +281,8 @@ void Camera::flyFarer(const float & s) {
|
||||
|
||||
void Camera::flyToDistance(const float & d) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * d;
|
||||
float tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * d;
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -23,66 +23,101 @@
|
||||
|
||||
class Camera;
|
||||
|
||||
//extern QMatrix4x4 globCameraMatrix;
|
||||
//extern Camera * currentCamera;
|
||||
// extern QMatrix4x4 globCameraMatrix;
|
||||
// extern Camera * currentCamera;
|
||||
|
||||
class Camera: public GLObjectBase
|
||||
{
|
||||
class Camera: public GLObjectBase {
|
||||
friend class QGLView;
|
||||
friend class GLParticlesSystem;
|
||||
friend QDataStream & operator <<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator >>(QDataStream & s, GLObjectBase *& p);
|
||||
friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
|
||||
|
||||
public:
|
||||
Camera();
|
||||
|
||||
void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); 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 setPos(const QVector3D & p) {
|
||||
pos_ = p;
|
||||
anglesFromPoints();
|
||||
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 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 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 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 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 orbitXY(const float & a);
|
||||
void panZ(const float & a);
|
||||
void panXY(const float & a);
|
||||
void setFOV(const float & f) {fov_ = f;}
|
||||
void setAngles(const QVector3D & a) {setRotation(a);}
|
||||
void setFOV(const float & f) { fov_ = f; }
|
||||
void setAngles(const QVector3D & a) { setRotation(a); }
|
||||
void setAngleZ(const float & a);
|
||||
void setAngleXY(const float & a);
|
||||
void setAngleRoll(const float & a) {angles_.setX(a); buildTransform();}
|
||||
void setAngleLowerLimitXY(const float & a) {angle_limit_lower_xy = a; buildTransform();}
|
||||
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 setAngleRoll(const float & a) {
|
||||
angles_.setX(a);
|
||||
buildTransform();
|
||||
}
|
||||
void setAngleLowerLimitXY(const float & a) {
|
||||
angle_limit_lower_xy = a;
|
||||
buildTransform();
|
||||
}
|
||||
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 flyFarer(const float & s);
|
||||
void flyToDistance(const float & d);
|
||||
|
||||
QVector3D aim() const {return aim_;}
|
||||
QVector3D angles() const {return rotation();}
|
||||
QVector3D direction() const {return (aim_ - pos_).normalized();}
|
||||
QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();}
|
||||
float FOV() const {return fov_;}
|
||||
float distance() const {return (pos_ - aim_).length();}
|
||||
float angleZ() const {return angles_.z();}
|
||||
float angleXY() const {return angles_.y();}
|
||||
float angleRoll() const {return angles_.x();}
|
||||
float angleLowerLimitXY() const {return angle_limit_lower_xy;}
|
||||
float angleUpperLimitXY() const {return angle_limit_upper_xy;}
|
||||
float depthStart() const {return depth_start;}
|
||||
float depthEnd() const {return depth_end;}
|
||||
bool isMirrorX() const {return mirror_x;}
|
||||
bool isMirrorY() const {return mirror_y;}
|
||||
QVector3D aim() const { return aim_; }
|
||||
QVector3D angles() const { return rotation(); }
|
||||
QVector3D direction() const { return (aim_ - pos_).normalized(); }
|
||||
QVector3D directionXY() const {
|
||||
QVector3D tv = aim_ - pos_;
|
||||
return QVector3D(tv.x(), tv.y(), 0.).normalized();
|
||||
}
|
||||
float FOV() const { return fov_; }
|
||||
float distance() const { return (pos_ - aim_).length(); }
|
||||
float angleZ() const { return angles_.z(); }
|
||||
float angleXY() const { return angles_.y(); }
|
||||
float angleRoll() const { return angles_.x(); }
|
||||
float angleLowerLimitXY() const { return angle_limit_lower_xy; }
|
||||
float angleUpperLimitXY() const { return angle_limit_upper_xy; }
|
||||
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 apply(const GLfloat & aspect = 1.);
|
||||
void assign(const Camera & c);
|
||||
@@ -100,7 +135,6 @@ private:
|
||||
GLfloat angle_limit_upper_xy;
|
||||
bool mirror_x;
|
||||
bool mirror_y;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLCAMERA_H
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
|
||||
|
||||
GLFramebuffer::GLFramebuffer(int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum target__) {
|
||||
is_depth = withDepth;
|
||||
is_depth = withDepth;
|
||||
color_format = colorFormat_;
|
||||
target_ = target__;
|
||||
target_ = target__;
|
||||
colors.fill(0, colorAttachments_);
|
||||
fbo = drbo = 0;
|
||||
tex_d = 0;
|
||||
wid = hei = 0;
|
||||
tex_d = 0;
|
||||
wid = hei = 0;
|
||||
is_changed = false;
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ void GLFramebuffer::resize(int width, int height, bool force) {
|
||||
|
||||
|
||||
QImage GLFramebuffer::grab() const {
|
||||
//glReadPixels(0, 0, wid, hei, GL_RGBA, );
|
||||
//QImage ret();
|
||||
// glReadPixels(0, 0, wid, hei, GL_RGBA, );
|
||||
// QImage ret();
|
||||
return QImage();
|
||||
}
|
||||
|
||||
@@ -90,17 +90,17 @@ void GLFramebuffer::bind() {
|
||||
if (is_changed) resize(wid, hei);
|
||||
if (fbo == 0) return;
|
||||
initializeOpenGLFunctions();
|
||||
//glFlush();
|
||||
// glFlush();
|
||||
glGetIntegerv(GL_VIEWPORT, prev_view);
|
||||
//glClearError();
|
||||
// glClearError();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
//qDebug() << QString::number(glGetError(), 16);
|
||||
// qDebug() << QString::number(glGetError(), 16);
|
||||
QVector<GLenum> buffers;
|
||||
for (int i = 0; i < colors.size(); ++i)
|
||||
buffers << GL_COLOR_ATTACHMENT0 + i;
|
||||
glDrawBuffers(buffers.size(), buffers.constData());
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
// glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glViewport(0, 0, wid, hei);
|
||||
}
|
||||
|
||||
@@ -108,17 +108,17 @@ void GLFramebuffer::bind() {
|
||||
void GLFramebuffer::release() {
|
||||
is_changed = false;
|
||||
if (fbo == 0) return;
|
||||
//glFlush();
|
||||
// glFlush();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(prev_view[0], prev_view[1], prev_view[2], prev_view[3]);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
glDrawBuffer(e);
|
||||
//glDrawBuffers(1, &e);
|
||||
// glDrawBuffers(1, &e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,48 +19,56 @@
|
||||
#ifndef GLFRAMEBUFFER_H
|
||||
#define GLFRAMEBUFFER_H
|
||||
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#include "gltypes.h"
|
||||
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
class GLFramebuffer : protected QOpenGLExtraFunctions
|
||||
{
|
||||
|
||||
class GLFramebuffer: protected QOpenGLExtraFunctions {
|
||||
public:
|
||||
GLFramebuffer(int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum target = GL_TEXTURE_2D);
|
||||
virtual ~GLFramebuffer();
|
||||
|
||||
GLuint id() const {return fbo;}
|
||||
GLuint colorTexture(int index = 0) const {return colors[index];}
|
||||
GLenum colorFormat() const {return color_format;}
|
||||
GLuint depthTexture() const {return tex_d;}
|
||||
GLenum target() const {return target_;}
|
||||
int width() const {return wid;}
|
||||
int height() const {return hei;}
|
||||
QSize size() const {return QSize(wid, hei);}
|
||||
GLuint id() const { return fbo; }
|
||||
GLuint colorTexture(int index = 0) const { return colors[index]; }
|
||||
GLenum colorFormat() const { return color_format; }
|
||||
GLuint depthTexture() const { return tex_d; }
|
||||
GLenum target() const { return target_; }
|
||||
int width() const { return wid; }
|
||||
int height() const { return hei; }
|
||||
QSize size() const { return QSize(wid, hei); }
|
||||
QImage grab() const;
|
||||
|
||||
void resize(int width, int height, bool force = false);
|
||||
void bind();
|
||||
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 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 bindDepthTexture(int channel);
|
||||
|
||||
private:
|
||||
void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;}
|
||||
void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;}
|
||||
void deleteGLRenderbuffer(GLuint & drbo) {
|
||||
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;
|
||||
QVector<GLuint> colors;
|
||||
GLenum color_format, target_;
|
||||
GLuint fbo, drbo, tex_d;
|
||||
GLint prev_view[4], wid, hei;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLFRAMEBUFFER_H
|
||||
|
||||
@@ -23,24 +23,24 @@ QStringList GLTextureManagerBase::search_pathes(".");
|
||||
|
||||
|
||||
bool GLCubeTexture::create() {
|
||||
//qDebug("create");
|
||||
// qDebug("create");
|
||||
destroy();
|
||||
glGenTextures(1, &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_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_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_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
//glClearError();
|
||||
// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
// glClearError();
|
||||
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_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_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);
|
||||
//qDebug() << glGetError();
|
||||
// qDebug() << glGetError();
|
||||
changed_ = false;
|
||||
return id_ > 0;
|
||||
}
|
||||
@@ -59,28 +59,41 @@ void GLCubeTexture::load() {
|
||||
|
||||
|
||||
void GLCubeTexture::loadFromDirectory(const QString & dir) {
|
||||
QDir d(dir); QFileInfoList sl;
|
||||
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
|
||||
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(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());
|
||||
QDir d(dir);
|
||||
QFileInfoList sl;
|
||||
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
|
||||
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
if (!sl.isEmpty()) loadBack(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) {
|
||||
QDir d(dir); QFileInfoList sl;
|
||||
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
|
||||
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[1] = 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();
|
||||
QDir d(dir);
|
||||
QFileInfoList sl;
|
||||
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
|
||||
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
if (!sl.isEmpty()) pathes[1] = 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) {
|
||||
return ::findFile(path, search_pathes);
|
||||
}
|
||||
@@ -91,16 +104,16 @@ GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, b
|
||||
if (p.isEmpty()) return 0;
|
||||
int tid = textureID(p, bump);
|
||||
if (tid > 0) {
|
||||
//qDebug() << "[TextureManager] Found" << path << "as" << tid;
|
||||
// qDebug() << "[TextureManager] Found" << path << "as" << tid;
|
||||
return tid;
|
||||
}
|
||||
QImage image(p);
|
||||
if (bump) convertToNormal(image);
|
||||
//qDebug() << p << image.width() << image.height() << image.format() << bump;
|
||||
///tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, __GLContext__::MipmapBindOption*/);
|
||||
//GLuint tid = 0;
|
||||
// qDebug() << p << image.width() << image.height() << image.format() << bump;
|
||||
/// tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, __GLContext__::MipmapBindOption*/);
|
||||
// GLuint tid = 0;
|
||||
GLuint _tid = tid;
|
||||
createGLTexture(_tid, image);///currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
createGLTexture(_tid, image); /// currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
tid = _tid;
|
||||
if (tid == 0) {
|
||||
qDebug() << "[TextureManager] Can`t load" << p;
|
||||
@@ -117,12 +130,12 @@ GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool
|
||||
QImage image(im);
|
||||
if (bump) convertToNormal(image);
|
||||
GLuint tid = 0;
|
||||
createGLTexture(tid, im);///currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
createGLTexture(tid, im); /// currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
if (tid == 0) {
|
||||
qDebug() << "[TextureManager] Can`t load image";
|
||||
return tid;
|
||||
}
|
||||
//qDebug() << "[TextureManager] Loaded image as" << tid;
|
||||
// qDebug() << "[TextureManager] Loaded image as" << tid;
|
||||
if (ownership) tex_ids[bump ? 1 : 0].insert(QString(), tid);
|
||||
return tid;
|
||||
}
|
||||
@@ -150,21 +163,24 @@ void GLTextureManagerBase::reloadTexture(GLuint tid, const QImage & im) {
|
||||
|
||||
|
||||
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) {
|
||||
if (im.isNull()) return;
|
||||
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
|
||||
float sum[3] = {0., 0., 0.};
|
||||
llong a = 0;
|
||||
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
|
||||
float sum[3] = {0., 0., 0.};
|
||||
llong a = 0;
|
||||
const uchar * sd = sim.constBits();
|
||||
for (int i = 0; i < sim.height(); i++) {
|
||||
for (int j = 0; j < sim.width(); j++) {
|
||||
sum[2] += 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;
|
||||
sum[2] += 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;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +194,7 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
|
||||
qDebug() << "convert to bump";
|
||||
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
|
||||
int tx, ty, w = sim.width(), h = sim.height();
|
||||
a = 0;
|
||||
a = 0;
|
||||
uchar * dd = dim.bits();
|
||||
for (int i = 0; i < sim.height(); i++) {
|
||||
for (int j = 0; j < sim.width(); j++) {
|
||||
@@ -187,40 +203,42 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
|
||||
ty = i - 1;
|
||||
ty = ty < 0 ? h + ty : ty % h;
|
||||
Vector3d p[3], res;
|
||||
p[0] = colorVector(sim.pixel(j, i));
|
||||
p[1] = colorVector(sim.pixel(j, ty));
|
||||
p[2] = colorVector(sim.pixel(tx, i));
|
||||
p[0] = colorVector(sim.pixel(j, i));
|
||||
p[1] = colorVector(sim.pixel(j, ty));
|
||||
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.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
|
||||
tx = (j + 1) % w;
|
||||
ty = (i + 1) % h;
|
||||
p[1] = colorVector(sim.pixel(j, ty));
|
||||
p[2] = colorVector(sim.pixel(tx, i));
|
||||
tx = (j + 1) % w;
|
||||
ty = (i + 1) % h;
|
||||
p[1] = colorVector(sim.pixel(j, ty));
|
||||
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.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
|
||||
res.z = 1.;
|
||||
dd[a] = res.z * 255; ++a;
|
||||
dd[a] = res.x * 255; ++a;
|
||||
dd[a] = res.y * 255; ++a;
|
||||
dd[a] = 255; ++a;
|
||||
dd[a] = res.z * 255;
|
||||
++a;
|
||||
dd[a] = res.x * 255;
|
||||
++a;
|
||||
dd[a] = res.y * 255;
|
||||
++a;
|
||||
dd[a] = 255;
|
||||
++a;
|
||||
}
|
||||
}
|
||||
im = dim;
|
||||
//im.save("_bump.png");
|
||||
// im.save("_bump.png");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Material::Material(): map_reflection(512) {
|
||||
color_diffuse = color_specular = Qt::white;
|
||||
color_self_illumination = Qt::black;
|
||||
glass = false;
|
||||
transparency = reflectivity = 0.f;
|
||||
color_self_illumination = Qt::black;
|
||||
glass = false;
|
||||
transparency = reflectivity = 0.f;
|
||||
map_specularity.color_amount = 0.5f;
|
||||
map_specular.color_amount = 1.f;
|
||||
iof = 1.f;
|
||||
dispersion = 0.05f;
|
||||
map_specular.color_amount = 1.f;
|
||||
iof = 1.f;
|
||||
dispersion = 0.05f;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,24 +246,24 @@ void Material::apply(QOpenGLShaderProgram * prog) {
|
||||
if (prog) {
|
||||
setUniformMaterial(prog, *this);
|
||||
} 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_emission[4] = {0.f, 0.f, 0.f, 1.0f};
|
||||
mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF();
|
||||
mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF();
|
||||
mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF();
|
||||
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[1] = map_specular.color_amount * color_specular.greenF();
|
||||
mat_specular[2] = map_specular.color_amount * color_specular.blueF();
|
||||
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[2] = map_self_illumination.color_amount * color_self_illumination.blueF();
|
||||
mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF();
|
||||
mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF();
|
||||
mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF();
|
||||
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[1] = map_specular.color_amount * color_specular.greenF();
|
||||
mat_specular[2] = map_specular.color_amount * color_specular.blueF();
|
||||
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[2] = map_self_illumination.color_amount * color_self_illumination.blueF();
|
||||
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
|
||||
//qDebug() << (map_specularity.color_amount)*128.;
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount)*128.f);
|
||||
// qDebug() << (map_specularity.color_amount)*128.;
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount) * 128.f);
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
|
||||
}
|
||||
@@ -253,7 +271,7 @@ void Material::apply(QOpenGLShaderProgram * prog) {
|
||||
|
||||
|
||||
void Material::loadTextures(GLTextureManagerBase * tm) {
|
||||
//qDebug() << "load textures";
|
||||
// qDebug() << "load textures";
|
||||
if (!tm) return;
|
||||
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);
|
||||
@@ -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_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_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();
|
||||
}
|
||||
|
||||
@@ -1,39 +1,55 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLMATERIAL_H
|
||||
#define GLMATERIAL_H
|
||||
|
||||
#include "gltypes.h"
|
||||
#include "chunkstream.h"
|
||||
#include "gltypes.h"
|
||||
|
||||
class GLTexture {
|
||||
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;}
|
||||
bool create() {destroy(); 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_;}
|
||||
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;
|
||||
}
|
||||
bool create() {
|
||||
destroy();
|
||||
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:
|
||||
int wid, hei;
|
||||
GLenum format_, target_;
|
||||
@@ -43,27 +59,95 @@ private:
|
||||
|
||||
class GLCubeTexture {
|
||||
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();
|
||||
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
|
||||
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 destroy() {
|
||||
if (id_ > 0) glDeleteTextures(1, &id_);
|
||||
id_ = 0;
|
||||
}
|
||||
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 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 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 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 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();
|
||||
bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;}
|
||||
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;}
|
||||
bool isEmpty() const {
|
||||
foreach(const QString & i, pathes)
|
||||
if (!i.isEmpty()) return false;
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
|
||||
private:
|
||||
bool changed_;
|
||||
int size;
|
||||
@@ -78,28 +162,33 @@ class GLTextureManagerBase {
|
||||
public:
|
||||
GLTextureManagerBase() {}
|
||||
virtual ~GLTextureManagerBase() {}
|
||||
void addSearchPath(const QString & path) {search_pathes << path;}
|
||||
static QStringList searchPathes() {return search_pathes;}
|
||||
void addSearchPath(const QString & path) { search_pathes << path; }
|
||||
static QStringList searchPathes() { return search_pathes; }
|
||||
QString findFile(const QString & path);
|
||||
GLuint loadTexture(const QString & path, 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 QImage & image);
|
||||
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];}
|
||||
virtual void addTexture(const QString & path) = 0;
|
||||
int textureID(const QString & path, bool bump = false) { return tex_ids[bump ? 1 : 0][path]; }
|
||||
virtual void addTexture(const QString & path) = 0;
|
||||
virtual void addAnimation(const QString & dir, const QString & name) = 0;
|
||||
virtual bool loadTextures() = 0;
|
||||
virtual bool loadTextures() = 0;
|
||||
|
||||
protected:
|
||||
static void convertToNormal(QImage & im);
|
||||
static QStringList search_pathes;
|
||||
QMap<QString, GLuint> tex_ids[2];
|
||||
|
||||
};
|
||||
|
||||
class Map {
|
||||
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;
|
||||
GLuint bitmap_id;
|
||||
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;
|
||||
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);
|
||||
s << cs.data(); return s;
|
||||
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);
|
||||
s << cs.data();
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator >>(QDataStream & s, Map & m) {
|
||||
inline QDataStream & operator>>(QDataStream & s, Map & m) {
|
||||
ChunkStream cs(s);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
@@ -157,14 +252,25 @@ inline QDataStream & operator >>(QDataStream & s, Map & m) {
|
||||
return s;
|
||||
}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const Material & m) {
|
||||
inline QDataStream & operator<<(QDataStream & s, const Material & m) {
|
||||
ChunkStream cs;
|
||||
cs.add(1, m.name).add(2, m.color_diffuse).add(3, m.color_specular).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;
|
||||
cs.add(1, m.name)
|
||||
.add(2, m.color_diffuse)
|
||||
.add(3, m.color_specular)
|
||||
.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;
|
||||
s >> ba;
|
||||
ba = qUncompress(ba);
|
||||
|
||||
@@ -17,34 +17,35 @@
|
||||
*/
|
||||
|
||||
#include "globject.h"
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "qglview.h"
|
||||
|
||||
|
||||
GLObjectBase::GLObjectBase() {
|
||||
type_ = glMesh;
|
||||
type_ = glMesh;
|
||||
render_mode = View;
|
||||
pass_ = Solid;
|
||||
geom_prim = Triangles;
|
||||
scale_ = QVector3D(1., 1., 1.);
|
||||
parent_ = nullptr;
|
||||
pass_ = Solid;
|
||||
geom_prim = Triangles;
|
||||
scale_ = QVector3D(1., 1., 1.);
|
||||
parent_ = nullptr;
|
||||
is_root = is_init = is_tex_loaded = selected_ = false;
|
||||
visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true;
|
||||
line_width = -1.;
|
||||
blend_src = GL_SRC_ALPHA;
|
||||
blend_dest = GL_ONE_MINUS_SRC_ALPHA;
|
||||
type_ = glMesh;
|
||||
raw_matrix = false;
|
||||
line_width = -1.;
|
||||
blend_src = GL_SRC_ALPHA;
|
||||
blend_dest = GL_ONE_MINUS_SRC_ALPHA;
|
||||
type_ = glMesh;
|
||||
raw_matrix = false;
|
||||
mat_.setToIdentity();
|
||||
view_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
GLObjectBase::~GLObjectBase() {
|
||||
//qDebug() << "del" << name() << view_;
|
||||
// qDebug() << "del" << name() << view_;
|
||||
if (parent_) parent_->children_.removeAll(this);
|
||||
if (view_) ((QGLView*)view_)->objectDeleted(this);
|
||||
foreach (GLObjectBase * c, children_) {
|
||||
if (view_) ((QGLView *)view_)->objectDeleted(this);
|
||||
foreach(GLObjectBase * c, children_) {
|
||||
c->parent_ = nullptr;
|
||||
delete c;
|
||||
}
|
||||
@@ -52,37 +53,37 @@ GLObjectBase::~GLObjectBase() {
|
||||
|
||||
|
||||
GLObjectBase * GLObjectBase::clone(bool withChildren) {
|
||||
GLObjectBase * o = new GLObjectBase();
|
||||
o->pass_ = pass_;
|
||||
o->is_init = false;
|
||||
o->accept_light = accept_light;
|
||||
o->accept_fog = accept_fog;
|
||||
o->visible_ = visible_;
|
||||
o->type_ = type_;
|
||||
o->raw_matrix = raw_matrix;
|
||||
o->mat_ = mat_;
|
||||
o->pos_ = pos_;
|
||||
o->angles_ = angles_;
|
||||
o->scale_ = scale_;
|
||||
o->itransform_ = itransform_;
|
||||
o->bound = bound;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->blend_src = blend_src;
|
||||
o->blend_dest = blend_dest;
|
||||
o->material_ = material_;
|
||||
o->pos_h = pos_h;
|
||||
o->points = points;
|
||||
o->puvws = puvws;
|
||||
o->faces = faces;
|
||||
o->uvws = uvws;
|
||||
o->norms = norms;
|
||||
o->normals = normals;
|
||||
o->vbo.vertices_ = vbo.vertices_;
|
||||
o->vbo.normals_ = vbo.normals_;
|
||||
GLObjectBase * o = new GLObjectBase();
|
||||
o->pass_ = pass_;
|
||||
o->is_init = false;
|
||||
o->accept_light = accept_light;
|
||||
o->accept_fog = accept_fog;
|
||||
o->visible_ = visible_;
|
||||
o->type_ = type_;
|
||||
o->raw_matrix = raw_matrix;
|
||||
o->mat_ = mat_;
|
||||
o->pos_ = pos_;
|
||||
o->angles_ = angles_;
|
||||
o->scale_ = scale_;
|
||||
o->itransform_ = itransform_;
|
||||
o->bound = bound;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->blend_src = blend_src;
|
||||
o->blend_dest = blend_dest;
|
||||
o->material_ = material_;
|
||||
o->pos_h = pos_h;
|
||||
o->points = points;
|
||||
o->puvws = puvws;
|
||||
o->faces = faces;
|
||||
o->uvws = uvws;
|
||||
o->norms = norms;
|
||||
o->normals = normals;
|
||||
o->vbo.vertices_ = vbo.vertices_;
|
||||
o->vbo.normals_ = vbo.normals_;
|
||||
o->vbo.texcoords_ = vbo.texcoords_;
|
||||
o->vbo.colors_ = vbo.colors_;
|
||||
o->meta = meta;
|
||||
o->view_ = nullptr;
|
||||
o->vbo.colors_ = vbo.colors_;
|
||||
o->meta = meta;
|
||||
o->view_ = nullptr;
|
||||
o->children_.clear();
|
||||
if (withChildren) {
|
||||
for (int i = 0; i < children_.size(); ++i)
|
||||
@@ -96,8 +97,8 @@ void GLObjectBase::init() {
|
||||
calculateBoundingBox();
|
||||
vbo.init();
|
||||
vbo.rebuffer();
|
||||
//material_.reflection.create();
|
||||
//qDebug() << "init" << vbo.buffer_;
|
||||
// material_.reflection.create();
|
||||
// qDebug() << "init" << vbo.buffer_;
|
||||
is_init = true;
|
||||
}
|
||||
|
||||
@@ -105,42 +106,41 @@ void GLObjectBase::init() {
|
||||
void GLObjectBase::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
vbo.draw(geom_prim, prog, simplest);
|
||||
/*if (!d_vertices.isEmpty()) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData());
|
||||
//glColorPointer(4, GL_FLOAT, 0, d_colors.constData());
|
||||
glNormalPointer(GL_FLOAT, 0, d_normals.constData());
|
||||
glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/
|
||||
/*if (pass_ == Reflection) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
}*/
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData());
|
||||
//glColorPointer(4, GL_FLOAT, 0, d_colors.constData());
|
||||
glNormalPointer(GL_FLOAT, 0, d_normals.constData());
|
||||
glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/
|
||||
/*if (pass_ == Reflection) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
}*/
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::setView(QGLView * v) {
|
||||
view_ = v;
|
||||
foreach (GLObjectBase * c, children_)
|
||||
foreach(GLObjectBase * c, children_)
|
||||
c->setView(v);
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::addChild(GLObjectBase * o) {
|
||||
if (o == this) return;
|
||||
if (o->parent_)
|
||||
o->parent_->children_.removeAll(o);
|
||||
if (o->parent_) o->parent_->children_.removeAll(o);
|
||||
children_ << o;
|
||||
o->parent_ = this;
|
||||
o->setView((QGLView*)view_);
|
||||
o->setView((QGLView *)view_);
|
||||
o->buildTransform();
|
||||
if (view_) {
|
||||
view_->collectLights();
|
||||
QList<GLObjectBase*> cl = o->children(true);
|
||||
QList<GLObjectBase *> cl = o->children(true);
|
||||
cl << o;
|
||||
foreach (GLObjectBase * i, cl) {
|
||||
emit ((QGLView*)view_)->objectAdded(i);
|
||||
foreach(GLObjectBase * i, cl) {
|
||||
emit((QGLView *)view_)->objectAdded(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,8 +164,8 @@ void GLObjectBase::removeChild(int index) {
|
||||
|
||||
|
||||
void GLObjectBase::clearChildren(bool deleteAll) {
|
||||
foreach (GLObjectBase * i, children_) {
|
||||
i->view_ = nullptr;
|
||||
foreach(GLObjectBase * i, children_) {
|
||||
i->view_ = nullptr;
|
||||
i->parent_ = nullptr;
|
||||
i->clearChildren(deleteAll);
|
||||
if (deleteAll) {
|
||||
@@ -186,7 +186,7 @@ GLObjectBase * GLObjectBase::child(int index) {
|
||||
|
||||
|
||||
GLObjectBase * GLObjectBase::child(const QString & name) {
|
||||
foreach (GLObjectBase * i, children_)
|
||||
foreach(GLObjectBase * i, children_)
|
||||
if (i->name_ == name) return i;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -199,15 +199,15 @@ const GLObjectBase * GLObjectBase::child(int index) const {
|
||||
|
||||
|
||||
const GLObjectBase * GLObjectBase::child(const QString & name) const {
|
||||
foreach (GLObjectBase * i, children_)
|
||||
foreach(GLObjectBase * i, children_)
|
||||
if (i->name_ == name) return i;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
QList<GLObjectBase * > GLObjectBase::children(bool all_) {
|
||||
QList<GLObjectBase *> GLObjectBase::children(bool all_) {
|
||||
if (!all_) return children_;
|
||||
QList<GLObjectBase * > cl;
|
||||
QList<GLObjectBase *> cl;
|
||||
addChildren(cl, this);
|
||||
return cl;
|
||||
}
|
||||
@@ -230,8 +230,10 @@ void GLObjectBase::rotateY(GLfloat a) {
|
||||
void GLObjectBase::rotateZ(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
angles_.setZ(angles_.z() + a);
|
||||
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
|
||||
while (angles_.z() < -360.f)
|
||||
angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f)
|
||||
angles_.setZ(angles_.z() - 360.f);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
@@ -253,28 +255,30 @@ void GLObjectBase::setRotationY(GLfloat a) {
|
||||
void GLObjectBase::setRotationZ(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
angles_.setZ(a);
|
||||
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
|
||||
while (angles_.z() < -360.f)
|
||||
angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f)
|
||||
angles_.setZ(angles_.z() - 360.f);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::setRotation(const QVector3D & a) {
|
||||
raw_matrix = false;
|
||||
angles_= a;
|
||||
angles_ = a;
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::resetRotation() {
|
||||
raw_matrix = false;
|
||||
angles_ = QVector3D(0., 0., 0.);
|
||||
angles_ = QVector3D(0., 0., 0.);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * where) {
|
||||
foreach (GLObjectBase * i, where->children_) {
|
||||
void GLObjectBase::addChildren(QList<GLObjectBase *> & list, GLObjectBase * where) {
|
||||
foreach(GLObjectBase * i, where->children_) {
|
||||
list << i;
|
||||
addChildren(list, i);
|
||||
}
|
||||
@@ -284,21 +288,22 @@ void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * whe
|
||||
void GLObjectBase::loadTextures(bool with_children) {
|
||||
material_.loadTextures(view_->textureManager());
|
||||
if (with_children)
|
||||
foreach (GLObjectBase * i, children_) i->loadTextures();
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->loadTextures();
|
||||
is_tex_loaded = true;
|
||||
checkPass();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::calculateBoundingBox() {
|
||||
bound = vbo.boundingBox();
|
||||
bound = vbo.boundingBox();
|
||||
QVector<QVector3D> c = bound.corners(), tc;
|
||||
//QMatrix4x4 mat = itransform_.inverted();
|
||||
//qDebug() << itransform_ << mat_ << mat;
|
||||
foreach (QVector3D p, c)
|
||||
// QMatrix4x4 mat = itransform_.inverted();
|
||||
// qDebug() << itransform_ << mat_ << mat;
|
||||
foreach(QVector3D p, c)
|
||||
tc << (itransform_ * QVector4D(p, 1)).toVector3D();
|
||||
bound = Box3D(tc);
|
||||
foreach (GLObjectBase * i, children_) {
|
||||
foreach(GLObjectBase * i, children_) {
|
||||
i->calculateBoundingBox();
|
||||
bound |= i->boundingBox();
|
||||
}
|
||||
@@ -328,25 +333,25 @@ void GLObjectBase::removeProperty(const QString & pn) {
|
||||
|
||||
void GLObjectBase::setTransform(const QMatrix4x4 & t) {
|
||||
raw_matrix = true;
|
||||
mat_ = t;
|
||||
pos_ = mat_.column(3).toVector3D();
|
||||
mat_ = t;
|
||||
pos_ = mat_.column(3).toVector3D();
|
||||
mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::select() {
|
||||
//qDebug() << "select" << name() << view_;
|
||||
// qDebug() << "select" << name() << view_;
|
||||
selected_ = true;
|
||||
if (view_)
|
||||
((QGLView*)view_)->selectObject(this);
|
||||
if (view_) ((QGLView *)view_)->selectObject(this);
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::setMaterial(const Material & m, bool with_children) {
|
||||
material_ = m;
|
||||
if (with_children)
|
||||
foreach (GLObjectBase * i, children_) i->setMaterial(m, true);
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->setMaterial(m, true);
|
||||
checkPass();
|
||||
is_tex_loaded = false;
|
||||
}
|
||||
@@ -355,16 +360,15 @@ void GLObjectBase::setMaterial(const Material & m, bool with_children) {
|
||||
void GLObjectBase::buildTransform() {
|
||||
itransform_.setToIdentity();
|
||||
GLObjectBase * p = parent_;
|
||||
if (p)
|
||||
itransform_ = p->itransform_;
|
||||
if (p) itransform_ = p->itransform_;
|
||||
if (raw_matrix) {
|
||||
itransform_.translate(pos_);
|
||||
itransform_ *= mat_;
|
||||
//qDebug() << "raw_matrix" << itransform_;
|
||||
// qDebug() << "raw_matrix" << itransform_;
|
||||
} else
|
||||
localTransform(itransform_);
|
||||
//qDebug() << name_ << itransform_;
|
||||
foreach (GLObjectBase * i, children_)
|
||||
// qDebug() << name_ << itransform_;
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->buildTransform();
|
||||
}
|
||||
|
||||
@@ -372,7 +376,8 @@ void GLObjectBase::buildTransform() {
|
||||
void GLObjectBase::initInternal() {
|
||||
init();
|
||||
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() {
|
||||
if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f) pass_ = Transparent;
|
||||
else pass_ = Solid;
|
||||
if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f)
|
||||
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;
|
||||
//glPushMatrix();
|
||||
///qglMultMatrix TODO
|
||||
// glPushMatrix();
|
||||
/// qglMultMatrix TODO
|
||||
material_.apply(nullptr);
|
||||
if (id != nullptr) {
|
||||
++(*id);
|
||||
ids->insert(*id, this);
|
||||
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
|
||||
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
|
||||
// glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
|
||||
// qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
|
||||
}
|
||||
draw(nullptr);
|
||||
foreach (GLObjectBase * i, children_)
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->render(id, ids, sh_id_loc);
|
||||
//glPopMatrix();
|
||||
// glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) {
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
intensity = 1.;
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
intensity = 1.;
|
||||
angle_start = angle_end = 180.;
|
||||
decay_linear = decay_quadratic = decay_start = 0.;
|
||||
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) {
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
pos_ = p;
|
||||
intensity = i;
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
pos_ = p;
|
||||
intensity = i;
|
||||
/*color_ = c;*/
|
||||
angle_start = angle_end = 180.;
|
||||
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) {
|
||||
Light * o = new Light(*this);
|
||||
//GLObjectBase::clone(withChildren);
|
||||
Light * o = new Light(*this);
|
||||
// GLObjectBase::clone(withChildren);
|
||||
o->is_init = false;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->children_.clear();
|
||||
if (withChildren) {
|
||||
for (int i = 0; i < children_.size(); ++i)
|
||||
o->addChild(children_[i]->clone(withChildren));
|
||||
}
|
||||
o->light_type = light_type;
|
||||
o->direction = direction;
|
||||
o->angle_start = angle_start;
|
||||
o->angle_end = angle_end;
|
||||
o->intensity = intensity;
|
||||
o->decay_const = decay_const;
|
||||
o->decay_linear = decay_linear;
|
||||
o->light_type = light_type;
|
||||
o->direction = direction;
|
||||
o->angle_start = angle_start;
|
||||
o->angle_end = angle_end;
|
||||
o->intensity = intensity;
|
||||
o->decay_const = decay_const;
|
||||
o->decay_linear = decay_linear;
|
||||
o->decay_quadratic = decay_quadratic;
|
||||
o->meta = meta;
|
||||
o->meta = meta;
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -486,8 +491,7 @@ void Light::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
if (light_type != Omni) {
|
||||
glBegin(GL_LINES);
|
||||
QVector4D dir = QVector4D(direction);
|
||||
if (raw_matrix)
|
||||
dir = transform().inverted() * dir;
|
||||
if (raw_matrix) dir = transform().inverted() * dir;
|
||||
glVertex3f(0., 0., 0.);
|
||||
glVertex3f(dir.x() * s, dir.y() * s, dir.z() * s);
|
||||
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;
|
||||
//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.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(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);
|
||||
//qDebug() << "place self done";
|
||||
<< 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(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);
|
||||
// qDebug() << "place self done";
|
||||
if (p->type_ == GLObjectBase::glLight) {
|
||||
//qDebug() << "place light ...";
|
||||
const Light * l = (const Light*)p;
|
||||
// qDebug() << "place light ...";
|
||||
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.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(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));
|
||||
}
|
||||
if (p->type_ == GLObjectBase::glCamera) {
|
||||
//qDebug() << "place camera ...";
|
||||
const Camera * c = (const Camera*)p;
|
||||
// qDebug() << "place camera ...";
|
||||
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.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy)
|
||||
<< cs.chunk(206, c->mirror_x) << cs.chunk(207, c->mirror_y);
|
||||
<< cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy) << cs.chunk(206, c->mirror_x)
|
||||
<< 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();
|
||||
foreach (const GLObjectBase * c, p->children_)
|
||||
foreach(const GLObjectBase * c, p->children_)
|
||||
s << c;
|
||||
return s;
|
||||
}
|
||||
QDataStream & operator >>(QDataStream & s, GLObjectBase *& p) {
|
||||
QDataStream & operator>>(QDataStream & s, GLObjectBase *& p) {
|
||||
ChunkStream cs(s);
|
||||
p = nullptr;
|
||||
int ccnt = 0;
|
||||
Light * l = nullptr;
|
||||
p = nullptr;
|
||||
int ccnt = 0;
|
||||
Light * l = nullptr;
|
||||
Camera * c = nullptr;
|
||||
QVector3D cam_angles;
|
||||
//qDebug() << "read obj ...";
|
||||
// qDebug() << "read obj ...";
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1:
|
||||
{
|
||||
case 1: {
|
||||
GLObjectBase::Type type = (GLObjectBase::Type)cs.getData<int>();
|
||||
switch (type) {
|
||||
case GLObjectBase::glMesh: p = new GLObjectBase(); break;
|
||||
case GLObjectBase::glLight: p = new Light(); l = (Light*)p; break;
|
||||
case GLObjectBase::glCamera: p = new Camera(); c = (Camera*)p; break;
|
||||
default : break;
|
||||
case GLObjectBase::glLight:
|
||||
p = new Light();
|
||||
l = (Light *)p;
|
||||
break;
|
||||
case GLObjectBase::glCamera:
|
||||
p = new Camera();
|
||||
c = (Camera *)p;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
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;
|
||||
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:
|
||||
if (p) p->angles_ = cs.getData<QVector3D>();
|
||||
if (c) {
|
||||
c->setAngles(cs.getData<QVector3D>());
|
||||
cam_angles = c->angles();
|
||||
}
|
||||
break;
|
||||
case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break;
|
||||
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break;
|
||||
case 15: if (p) p->vbo = cs.getData<GLVBO>(); break;
|
||||
case 16: if (p) ccnt = cs.getData<int>(); break;
|
||||
case 17: if (p) p->name_ = cs.getData<QString>(); break;
|
||||
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break;
|
||||
case 100: if (l) l->direction = cs.getData<QVector3D>(); break;
|
||||
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); 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;
|
||||
break;
|
||||
case 13:
|
||||
if (p) p->scale_ = cs.getData<QVector3D>();
|
||||
break;
|
||||
case 14:
|
||||
if (p) p->mat_ = cs.getData<QMatrix4x4>();
|
||||
break;
|
||||
case 15:
|
||||
if (p) p->vbo = cs.getData<GLVBO>();
|
||||
break;
|
||||
case 16:
|
||||
if (p) ccnt = cs.getData<int>();
|
||||
break;
|
||||
case 17:
|
||||
if (p) p->name_ = cs.getData<QString>();
|
||||
break;
|
||||
case 18:
|
||||
if (p) p->meta = cs.getData<QVariantMap>();
|
||||
break;
|
||||
case 100:
|
||||
if (l) l->direction = cs.getData<QVector3D>();
|
||||
break;
|
||||
case 101:
|
||||
if (l) l->angle_start = cs.getData<GLfloat>();
|
||||
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);
|
||||
//qDebug() << p->name() << ccnt;
|
||||
// qDebug() << p->name() << ccnt;
|
||||
for (int i = 0; i < ccnt; ++i) {
|
||||
GLObjectBase * c = nullptr;
|
||||
s >> c;
|
||||
|
||||
@@ -19,101 +19,158 @@
|
||||
#ifndef GLOBJECT_H
|
||||
#define GLOBJECT_H
|
||||
|
||||
#include "glvbo.h"
|
||||
#include "glframebuffer.h"
|
||||
#include "glmaterial.h"
|
||||
#include "glvbo.h"
|
||||
|
||||
class Camera;
|
||||
class QGLView;
|
||||
|
||||
class GLObjectBase
|
||||
{
|
||||
class GLObjectBase {
|
||||
friend class QGLView;
|
||||
friend class GLRendererBase;
|
||||
friend QDataStream & operator <<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator >>(QDataStream & s, GLObjectBase *& p);
|
||||
friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
|
||||
friend GLObjectBase * loadFromQGLFile(const QString & filepath);
|
||||
|
||||
public:
|
||||
enum Type {glMesh, glLight, 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};
|
||||
enum Type {
|
||||
glMesh,
|
||||
glLight,
|
||||
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();
|
||||
virtual ~GLObjectBase();
|
||||
|
||||
virtual GLObjectBase * clone(bool withChildren = true);
|
||||
|
||||
QString name() const {return name_;}
|
||||
void setName(const QString & name) {name_ = name;}
|
||||
//virtual GLuint hList() {return list;}
|
||||
QString name() const { return name_; }
|
||||
void setName(const QString & name) { name_ = name; }
|
||||
// virtual GLuint hList() {return list;}
|
||||
virtual void init();
|
||||
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
virtual void update() {}
|
||||
bool isInit() const {return is_init;}
|
||||
bool isTexturesLoaded() const {return is_tex_loaded;}
|
||||
Type type() const {return type_;}
|
||||
bool isInit() const { return is_init; }
|
||||
bool isTexturesLoaded() const { return is_tex_loaded; }
|
||||
Type type() const { return type_; }
|
||||
|
||||
RenderMode renderMode() const {return render_mode;}
|
||||
void setRenderMode(RenderMode mode) {render_mode = mode;}
|
||||
RenderMode renderMode() const { return render_mode; }
|
||||
void setRenderMode(RenderMode mode) { render_mode = mode; }
|
||||
|
||||
float lineWidth() const {return line_width;}
|
||||
void setLineWidth(const float & width) {line_width = width;}
|
||||
float lineWidth() const { return line_width; }
|
||||
void setLineWidth(const float & width) { line_width = width; }
|
||||
|
||||
GLObjectBase * parent() {return parent_;}
|
||||
void setParent(GLObjectBase * o) {parent_ = o;}
|
||||
bool hasParent() const {return parent_ != nullptr;}
|
||||
bool hasChildren() const {return children_.size() != 0;}
|
||||
GLObjectBase * parent() { return parent_; }
|
||||
void setParent(GLObjectBase * o) { parent_ = o; }
|
||||
bool hasParent() const { return parent_ != nullptr; }
|
||||
bool hasChildren() const { return children_.size() != 0; }
|
||||
void setView(QGLView * v);
|
||||
|
||||
void addChild(GLObjectBase * o);
|
||||
void removeChild(GLObjectBase * o);
|
||||
void removeChild(int index);
|
||||
void clearChildren(bool deleteAll = false);
|
||||
int childCount() const {return children_.size();}
|
||||
int childCount() const { return children_.size(); }
|
||||
GLObjectBase * child(int index);
|
||||
GLObjectBase * child(const QString & name);
|
||||
const GLObjectBase * child(int index) 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 isHidden() const {return !visible_;}
|
||||
void setVisible(bool v) {visible_ = v;}
|
||||
void setHidden(bool v) {visible_ = !v;}
|
||||
void show() {visible_ = true;}
|
||||
void hide() {visible_ = false;}
|
||||
bool isVisible() const { return visible_; }
|
||||
bool isHidden() const { return !visible_; }
|
||||
void setVisible(bool v) { visible_ = v; }
|
||||
void setHidden(bool v) { visible_ = !v; }
|
||||
void show() { visible_ = true; }
|
||||
void hide() { visible_ = false; }
|
||||
|
||||
bool isReceiveShadows() const {return rec_shadow;}
|
||||
bool isCastShadows() const {return cast_shadow;}
|
||||
void setReceiveShadows(bool on) {rec_shadow = on;}
|
||||
void setCastShadows(bool on) {cast_shadow = on;}
|
||||
bool isReceiveShadows() const { return rec_shadow; }
|
||||
bool isCastShadows() const { return cast_shadow; }
|
||||
void setReceiveShadows(bool on) { rec_shadow = on; }
|
||||
void setCastShadows(bool on) { cast_shadow = on; }
|
||||
|
||||
void move(const QVector3D & dv) {pos_ += dv; buildTransform();}
|
||||
void moveTo(const QVector3D & dv) {pos_ = dv; buildTransform();}
|
||||
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); 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();}
|
||||
void move(const QVector3D & dv) {
|
||||
pos_ += dv;
|
||||
buildTransform();
|
||||
}
|
||||
void moveTo(const QVector3D & dv) {
|
||||
pos_ = dv;
|
||||
buildTransform();
|
||||
}
|
||||
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
|
||||
move(QVector3D(dx, dy, dz));
|
||||
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_;}
|
||||
float posX() const {return pos_.x();}
|
||||
float posY() const {return pos_.y();}
|
||||
float posZ() const {return pos_.z();}
|
||||
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();}
|
||||
QMatrix4x4 worldTransform() const {return itransform_;}
|
||||
QVector3D pos() const { return pos_; }
|
||||
float posX() const { return pos_.x(); }
|
||||
float posY() const { return pos_.y(); }
|
||||
float posZ() const { return pos_.z(); }
|
||||
QVector3D worldPos() const { return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D(); }
|
||||
QMatrix4x4 worldTransform() const { return itransform_; }
|
||||
|
||||
QVector3D rotation() const {return angles_;}
|
||||
float rotationX() const {return angles_.x();}
|
||||
float rotationY() const {return angles_.y();}
|
||||
float rotationZ() const {return angles_.z();}
|
||||
QVector3D rotation() const { return angles_; }
|
||||
float rotationX() const { return angles_.x(); }
|
||||
float rotationY() const { return angles_.y(); }
|
||||
float rotationZ() const { return angles_.z(); }
|
||||
void rotateX(GLfloat a);
|
||||
void rotateY(GLfloat a);
|
||||
void rotateZ(GLfloat a);
|
||||
@@ -123,58 +180,113 @@ public:
|
||||
void setRotation(const QVector3D & a);
|
||||
void resetRotation();
|
||||
|
||||
QVector3D scale() {return scale_;}
|
||||
float scaleX() {return scale_.x();}
|
||||
float scaleY() {return scale_.y();}
|
||||
float scaleZ() {return scale_.z();}
|
||||
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();}
|
||||
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();}
|
||||
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; 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_;}
|
||||
QVector3D scale() { return scale_; }
|
||||
float scaleX() { return scale_.x(); }
|
||||
float scaleY() { return scale_.y(); }
|
||||
float scaleZ() { return scale_.z(); }
|
||||
void scale(const QVector3D & sv) {
|
||||
raw_matrix = false;
|
||||
scale_ *= sv;
|
||||
buildTransform();
|
||||
}
|
||||
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {
|
||||
raw_matrix = false;
|
||||
scale(QVector3D(sx, sy, sz));
|
||||
buildTransform();
|
||||
}
|
||||
void scale(GLfloat sx, GLfloat sy) {
|
||||
raw_matrix = false;
|
||||
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_; }
|
||||
void setTransform(const QMatrix4x4 & t);
|
||||
bool isRawMatrix() {return raw_matrix;}
|
||||
bool isRawMatrix() { return raw_matrix; }
|
||||
|
||||
bool isAcceptLight() const {return accept_light;}
|
||||
void setAcceptLight(bool yes) {accept_light = yes;}
|
||||
bool isAcceptLight() const { return accept_light; }
|
||||
void setAcceptLight(bool yes) { accept_light = yes; }
|
||||
|
||||
bool isAcceptFog() const {return accept_fog;}
|
||||
void setAcceptFog(bool yes) {accept_fog = yes;}
|
||||
bool isAcceptFog() const { return accept_fog; }
|
||||
void setAcceptFog(bool yes) { accept_fog = yes; }
|
||||
|
||||
bool isSelected() const {return selected_;}
|
||||
void setSelected(bool yes) {selected_ = yes;}
|
||||
bool isSelected() const { return selected_; }
|
||||
void setSelected(bool yes) { selected_ = yes; }
|
||||
void select();
|
||||
void deselect() {selected_ = false;}
|
||||
void deselect() { selected_ = false; }
|
||||
|
||||
bool isSelectable() const {return select_;}
|
||||
void setSelectable(bool yes) {select_ = yes;}
|
||||
bool isSelectable() const { return select_; }
|
||||
void setSelectable(bool yes) { select_ = yes; }
|
||||
/*
|
||||
bool isWriteDepth() const {return write_depth_;}
|
||||
void setWriteDepth(bool yes) {write_depth_ = yes;}*/
|
||||
|
||||
QColor color() const {return material_.color_diffuse;}
|
||||
void setColor(const QColor & c) {material_.color_diffuse = c; checkPass();}
|
||||
QColor color() const { return material_.color_diffuse; }
|
||||
void setColor(const QColor & c) {
|
||||
material_.color_diffuse = c;
|
||||
checkPass();
|
||||
}
|
||||
|
||||
GLenum srcAlpha() const {return blend_src;}
|
||||
GLenum destAlpha() const {return blend_dest;}
|
||||
void setSrcAlpha(GLenum mode) {blend_src = mode;}
|
||||
void setDestAlpha(GLenum mode) {blend_dest = mode;}
|
||||
GLenum srcAlpha() const { return blend_src; }
|
||||
GLenum destAlpha() const { return blend_dest; }
|
||||
void setSrcAlpha(GLenum mode) { blend_src = mode; }
|
||||
void setDestAlpha(GLenum mode) { blend_dest = mode; }
|
||||
|
||||
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;}
|
||||
GLVBO & VBO() {return vbo;}
|
||||
const Box3D & boundingBox(bool withChildren = true) const { return bound; }
|
||||
GLVBO & VBO() { return vbo; }
|
||||
|
||||
void calculateBoundingBox();
|
||||
|
||||
@@ -188,21 +300,22 @@ public:
|
||||
QVector<Vector3i> faces, uvws, norms;
|
||||
QVector<Vector3d> normals;
|
||||
|
||||
//QVector<GLfloat> d_vertices, d_normals, d_uvs;
|
||||
// QVector<GLfloat> d_vertices, d_normals, d_uvs;
|
||||
|
||||
protected:
|
||||
void addChildren(QList<GLObjectBase * > & list, GLObjectBase * where);
|
||||
void addChildren(QList<GLObjectBase *> & list, GLObjectBase * where);
|
||||
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 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();
|
||||
virtual void localTransform(QMatrix4x4 & m);
|
||||
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
|
||||
|
||||
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;
|
||||
float line_width;
|
||||
Type type_;
|
||||
@@ -211,31 +324,40 @@ protected:
|
||||
Material material_;
|
||||
Box3D bound;
|
||||
QVector3D pos_, angles_, scale_;
|
||||
QList<GLObjectBase * > children_;
|
||||
QList<GLObjectBase *> children_;
|
||||
QList<GLuint> textures;
|
||||
QMatrix4x4 itransform_, mat_;
|
||||
//QColor color_;
|
||||
// QColor color_;
|
||||
QString name_;
|
||||
GLenum blend_src, blend_dest;
|
||||
GLObjectBase * parent_;
|
||||
QGLViewBase * view_;
|
||||
GLVBO vbo;
|
||||
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 {
|
||||
friend class QGLView;
|
||||
friend class GLRendererBase;
|
||||
|
||||
public:
|
||||
enum Type {Omni, Directional, Cone};
|
||||
enum Type {
|
||||
Omni,
|
||||
Directional,
|
||||
Cone
|
||||
};
|
||||
|
||||
Light();
|
||||
Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.);
|
||||
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);
|
||||
|
||||
QVector3D direction, dir0, dir1;
|
||||
@@ -252,17 +374,20 @@ public:
|
||||
QMatrix4x4 shadow_matrix;
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T globject_cast(GLObjectBase * object) {return reinterpret_cast<T>(object);}
|
||||
template<class T>
|
||||
inline T globject_cast(GLObjectBase * object) {
|
||||
return reinterpret_cast<T>(object);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T globject_cast(const GLObjectBase * object) {return reinterpret_cast<T>(object);}
|
||||
template<class T>
|
||||
inline T globject_cast(const GLObjectBase * object) {
|
||||
return reinterpret_cast<T>(object);
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const GLObjectBase * p);
|
||||
QDataStream & operator >>(QDataStream & s, GLObjectBase *& p);
|
||||
QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
|
||||
QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
|
||||
|
||||
#endif // GLOBJECT_H
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
*/
|
||||
|
||||
#include "globject_editor.h"
|
||||
#include "ui_globject_editor.h"
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "ui_globject_editor.h"
|
||||
|
||||
|
||||
GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
|
||||
@@ -37,11 +38,8 @@ GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
|
||||
void GLObjectEditor::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: ui->retranslateUi(this); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +74,8 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
|
||||
ui->groupLight->setEnabled(object->type() == GLObjectBase::glLight);
|
||||
ui->groupLight->setVisible(object->type() == GLObjectBase::glLight);
|
||||
if (object->type() == GLObjectBase::glLight) {
|
||||
Light * l = globject_cast<Light * >(object);
|
||||
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
Light * l = globject_cast<Light *>(object);
|
||||
// bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
ui->buttonLightColor->setColor(l->color());
|
||||
ui->comboLightType->setCurrentIndex(l->light_type);
|
||||
ui->spinLightIntensity->setValue(l->intensity);
|
||||
@@ -93,7 +91,7 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
|
||||
ui->groupCamera->setEnabled(object->type() == GLObjectBase::glCamera);
|
||||
ui->groupCamera->setVisible(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->checkCameraMirrorY->setChecked(c->isMirrorY());
|
||||
ui->spinCameraFOV->setValue(c->FOV());
|
||||
@@ -125,20 +123,21 @@ void GLObjectEditor::objectChanged() {
|
||||
object->setReceiveShadows(ui->checkReceiveShadows->isChecked());
|
||||
object->setRenderMode((GLObjectBase::RenderMode)rmodes[ui->comboRenderMode->currentIndex()]);
|
||||
if (object->type() == GLObjectBase::glLight) {
|
||||
Light * l = globject_cast<Light * >(object);
|
||||
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
Light * l = globject_cast<Light *>(object);
|
||||
// bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
l->setColor(ui->buttonLightColor->color());
|
||||
l->light_type = (Light::Type)ui->comboLightType->currentIndex();
|
||||
l->intensity = ui->spinLightIntensity->value();
|
||||
l->decay_const = ui->spinLightDecayConst->value();
|
||||
l->decay_linear = ui->spinLightDecayLinear->value();
|
||||
l->light_type = (Light::Type)ui->comboLightType->currentIndex();
|
||||
l->intensity = ui->spinLightIntensity->value();
|
||||
l->decay_const = ui->spinLightDecayConst->value();
|
||||
l->decay_linear = ui->spinLightDecayLinear->value();
|
||||
l->decay_quadratic = ui->spinLightDecayQuadratic->value();
|
||||
l->angle_start = ui->spinLightAngleStart->value();
|
||||
l->angle_end = ui->spinLightAngleEnd->value();
|
||||
l->direction = QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
|
||||
l->angle_start = ui->spinLightAngleStart->value();
|
||||
l->angle_end = ui->spinLightAngleEnd->value();
|
||||
l->direction =
|
||||
QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
|
||||
}
|
||||
if (object->type() == GLObjectBase::glCamera) {
|
||||
Camera * c = globject_cast<Camera * >(object);
|
||||
Camera * c = globject_cast<Camera *>(object);
|
||||
c->setMirrorX(ui->checkCameraMirrorX->isChecked());
|
||||
c->setMirrorY(ui->checkCameraMirrorY->isChecked());
|
||||
c->setFOV(ui->spinCameraFOV->value());
|
||||
@@ -150,14 +149,12 @@ void GLObjectEditor::objectChanged() {
|
||||
|
||||
|
||||
void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
|
||||
if (ui->spinLightAngleEnd->value() < v)
|
||||
ui->spinLightAngleEnd->setValue(v);
|
||||
if (ui->spinLightAngleEnd->value() < v) ui->spinLightAngleEnd->setValue(v);
|
||||
}
|
||||
|
||||
|
||||
void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
|
||||
if (ui->spinLightAngleStart->value() > v)
|
||||
ui->spinLightAngleStart->setValue(v);
|
||||
if (ui->spinLightAngleStart->value() > v) ui->spinLightAngleStart->setValue(v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
#include "globject.h"
|
||||
|
||||
namespace Ui {
|
||||
class GLObjectEditor;
|
||||
class GLObjectEditor;
|
||||
};
|
||||
|
||||
class GLObjectEditor: public QWidget
|
||||
{
|
||||
class GLObjectEditor: public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GLObjectEditor(QWidget * parent = 0);
|
||||
|
||||
void setObject(GLObjectBase * o);
|
||||
GLObjectBase * getObject() {return object;}
|
||||
GLObjectBase * getObject() { return object; }
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent * e);
|
||||
@@ -50,7 +50,6 @@ private slots:
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
};
|
||||
|
||||
#endif // GLOBJECT_EDITOR_H
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
|
||||
|
||||
GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() {
|
||||
pass_ = GLObjectBase::Transparent;
|
||||
freq = 40.f;
|
||||
birthRate_ = 10.f;
|
||||
lifeDuration_ = 2.f;
|
||||
fade_time = 0.5f;
|
||||
size_ = 1.f;
|
||||
pass_ = GLObjectBase::Transparent;
|
||||
freq = 40.f;
|
||||
birthRate_ = 10.f;
|
||||
lifeDuration_ = 2.f;
|
||||
fade_time = 0.5f;
|
||||
size_ = 1.f;
|
||||
additionalSpeed = 0.f;
|
||||
initialSpeed_ = 1.f;
|
||||
need_birth = -1.f;
|
||||
initialSpeed_ = 1.f;
|
||||
need_birth = -1.f;
|
||||
tex_rect.setRect(0., 0., 1., 1.);
|
||||
tex_scale = QSizeF();
|
||||
tex_scale = QSizeF();
|
||||
emitterPosition_ = pos;
|
||||
emitterDirection_.setZ(1.);
|
||||
speedDirection_.setZ(1.);
|
||||
@@ -38,64 +38,65 @@ GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() {
|
||||
lifeDurationJitter_ = speedJitter_ = speedDirectionJitter_ = sizeJitter_ = angleJitter_ = 0.f;
|
||||
active_ = birthEnabled_ = true;
|
||||
is_diffuse_anim = add_vert_face = false;
|
||||
emitterType_ = Cone;
|
||||
tick_life = 1.f / freq;
|
||||
tick_birth = birthRate_ / freq;
|
||||
emitterType_ = Cone;
|
||||
tick_life = 1.f / freq;
|
||||
tick_birth = birthRate_ / freq;
|
||||
}
|
||||
|
||||
|
||||
void GLParticlesSystem::update() {
|
||||
//qDebug() << "update" << need_birth << tick_birth;
|
||||
// qDebug() << "update" << need_birth << tick_birth;
|
||||
if (!active_) return;
|
||||
//QMutexLocker locker(&mutex);
|
||||
// QMutexLocker locker(&mutex);
|
||||
Particle cp(lifeDuration_);
|
||||
if (birthEnabled_) need_birth += tick_birth;
|
||||
qDebug() << "update" << particles.size();
|
||||
if (need_birth >= 1.f) {
|
||||
cp.pos = emitterPosition_;
|
||||
//qDebug() << "speed" << cp.speed;
|
||||
cp.pos = emitterPosition_;
|
||||
// qDebug() << "speed" << cp.speed;
|
||||
cp.speedDecay = 1.f + speedDecay_;
|
||||
for (int i = 0; i < floor(need_birth); ++i) {
|
||||
cp.lifeDuration = lifeDuration_ + urand(lifeDurationJitter_);
|
||||
switch (emitterType_) {
|
||||
case Omni:
|
||||
cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_));
|
||||
break;
|
||||
case Cone: case Box:
|
||||
case Omni: cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_)); break;
|
||||
case Cone:
|
||||
case Box:
|
||||
cp.speed = emitterDirection_ * initialSpeed_ * (1.f + urand(speedJitter_));
|
||||
cp.speed += orthToVector(cp.speed, speedDirectionJitter_);
|
||||
break;
|
||||
}
|
||||
if (emitterType_ == Box)
|
||||
cp.pos = emitterRect_.randomPoint();
|
||||
//qDebug() << "before" << cp.speed.length();
|
||||
if (emitterType_ == Box) cp.pos = emitterRect_.randomPoint();
|
||||
// qDebug() << "before" << cp.speed.length();
|
||||
lengthenVector(cp.speed, additionalSpeed);
|
||||
//qDebug() << "after" << cp.speed.length();
|
||||
cp.size = size_ + urand(sizeJitter_);
|
||||
cp.angle = initialAngle_ + urand(angleJitter_);
|
||||
// qDebug() << "after" << cp.speed.length();
|
||||
cp.size = size_ + urand(sizeJitter_);
|
||||
cp.angle = initialAngle_ + urand(angleJitter_);
|
||||
cp.enlargeSpeed = (enlargeSpeed_ + urand(enlargeSpeedJitter_)) * tick_life;
|
||||
/*if (is_diffuse_anim) {
|
||||
if (material_.diffuse.animation_frame_rate < 0 && animation->bitmaps.size() > 0)
|
||||
cp.animationFrameRate = animation->bitmaps.size() / cp.lifeDuration;
|
||||
else
|
||||
cp.animationFrameRate = material_.diffuse.animation_frame_rate;
|
||||
if (material_.diffuse.animation_frame_rate < 0 && animation->bitmaps.size() > 0)
|
||||
cp.animationFrameRate = animation->bitmaps.size() / cp.lifeDuration;
|
||||
else
|
||||
cp.animationFrameRate = material_.diffuse.animation_frame_rate;
|
||||
}*/
|
||||
if (tex_scale.isEmpty()) cp.tex_rect.setSize(tex_rect.size());
|
||||
else 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;
|
||||
if (tex_scale.isEmpty())
|
||||
cp.tex_rect.setSize(tex_rect.size());
|
||||
else
|
||||
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);
|
||||
}
|
||||
need_birth -= floor(need_birth);
|
||||
}
|
||||
for (int i = 0; i < particles.size(); ++i) {
|
||||
Particle & c(particles[i]);
|
||||
foreach (const QVector3D & f, forces)
|
||||
foreach(const QVector3D & f, forces)
|
||||
c.speed += f;
|
||||
c.lifeCurrent += tick_life;
|
||||
//qDebug() << "life" << c.lifeCurrent << c.lifeDuration;
|
||||
// qDebug() << "life" << c.lifeCurrent << c.lifeDuration;
|
||||
if (c.lifeCurrent > c.lifeDuration) {
|
||||
//qDebug() << "remove" << i;
|
||||
// qDebug() << "remove" << i;
|
||||
particles.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
@@ -103,7 +104,7 @@ void GLParticlesSystem::update() {
|
||||
c.pos += c.speed * tick_life;
|
||||
c.speed /= c.speedDecay;
|
||||
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;
|
||||
Camera * camera(view_->camera());
|
||||
QVector3D apos = camera->pos(), dir = camera->direction();
|
||||
//qDebug() << dir;
|
||||
//qDebug() << camera.angles();
|
||||
//qDebug() << camera.angle_xy;
|
||||
// qDebug() << dir;
|
||||
// qDebug() << camera.angles();
|
||||
// qDebug() << camera.angle_xy;
|
||||
GLfloat cxyc, czs, czc;
|
||||
GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(),
|
||||
tr_g = material_.color_diffuse.greenF(),
|
||||
GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(), tr_g = material_.color_diffuse.greenF(),
|
||||
tr_b = material_.color_diffuse.blueF(),
|
||||
tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency);
|
||||
//cxys = sin(camera.angle_xy * deg2rad);
|
||||
cxyc = cosf(camera->angles_.y() * deg2rad);
|
||||
czs = sinf(camera->angles_.z() * deg2rad);
|
||||
czc = cosf(camera->angles_.z() * deg2rad);
|
||||
// cxys = sin(camera.angle_xy * deg2rad);
|
||||
cxyc = cosf(camera->angles_.y() * deg2rad);
|
||||
czs = sinf(camera->angles_.z() * deg2rad);
|
||||
czc = cosf(camera->angles_.z() * deg2rad);
|
||||
|
||||
dx = -czc;
|
||||
dy = czs;
|
||||
dx = -czc;
|
||||
dy = czs;
|
||||
vertices.clear();
|
||||
texcoords.clear();
|
||||
colors.clear();
|
||||
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));
|
||||
std::sort(particles.begin(), particles.end());
|
||||
glBegin(GL_POINTS);
|
||||
foreach (const Particle & i, particles) {
|
||||
//glVertex3f(i.pos.x(), i.pos.y(), i.pos.z());
|
||||
foreach(const Particle & i, particles) {
|
||||
// glVertex3f(i.pos.x(), i.pos.y(), i.pos.z());
|
||||
a = (i.lifeDuration - i.lifeCurrent) / fade_time;
|
||||
if (a > 1.f) a = 1.f;
|
||||
a *= tr_a;
|
||||
@@ -182,12 +182,12 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
|
||||
}
|
||||
}
|
||||
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_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
//glNormal3f(vn.x(), vn.y(), vn.z());
|
||||
// glNormal3f(vn.x(), vn.y(), vn.z());
|
||||
glNormal3f(0., 0., 1.);
|
||||
glDepthMask(false);
|
||||
glEnable(GL_COLOR_ARRAY);
|
||||
@@ -195,21 +195,20 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, texcoords.constData());
|
||||
glColorPointer(4, GL_FLOAT, 0, colors.constData());
|
||||
//glEnable(GL_ALPHA_TEST);
|
||||
//glAlphaFunc();
|
||||
// glEnable(GL_ALPHA_TEST);
|
||||
// glAlphaFunc();
|
||||
glDrawArrays(GL_QUADS, 0, vertices.size() / 3);
|
||||
glDepthMask(true);
|
||||
//glDisable(GL_ALPHA_TEST);
|
||||
//if (!cae) glDisable(GL_COLOR_ARRAY);
|
||||
//if (nae) glEnable(GL_NORMAL_ARRAY);
|
||||
// glDisable(GL_ALPHA_TEST);
|
||||
// if (!cae) glDisable(GL_COLOR_ARRAY);
|
||||
// if (nae) glEnable(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLParticlesSystem::Particle::Particle(float life_dur) {
|
||||
size = 1.;
|
||||
size = 1.;
|
||||
angle = lifeCurrent = 0.;
|
||||
speedDecay = 0.;
|
||||
lifeDuration = life_dur;
|
||||
tex_rect = QRectF(0, 0, 1, 1);
|
||||
speedDecay = 0.;
|
||||
lifeDuration = life_dur;
|
||||
tex_rect = QRectF(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
@@ -19,13 +19,16 @@
|
||||
#ifndef GLPARTICLES_SYSTEM_H
|
||||
#define GLPARTICLES_SYSTEM_H
|
||||
|
||||
#include <QMutex>
|
||||
#include "gltexture_manager.h"
|
||||
#include "globject.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_PROPERTY(float birthRate READ birthRate WRITE setBirthRate)
|
||||
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 birthEnabled READ isBirthEnabled WRITE setBirthEnabled)
|
||||
Q_PROPERTY(float fadeTime READ fadeTime WRITE setFadeTime)
|
||||
|
||||
public:
|
||||
GLParticlesSystem(const QVector3D & pos = QVector3D());
|
||||
~GLParticlesSystem() {;}
|
||||
~GLParticlesSystem() { ; }
|
||||
|
||||
enum Type {Cone, Omni, Box};
|
||||
enum Type {
|
||||
Cone,
|
||||
Omni,
|
||||
Box
|
||||
};
|
||||
|
||||
struct Particle {
|
||||
Particle(float life_dur = 40.);
|
||||
@@ -71,62 +79,65 @@ public:
|
||||
void update();
|
||||
void draw(QOpenGLShaderProgram * prog, bool);
|
||||
|
||||
float birthRate() const {return birthRate_;}
|
||||
float lifeDuration() const {return lifeDuration_;}
|
||||
float size() const {return size_;}
|
||||
float enlargeSpeed() const {return enlargeSpeed_;}
|
||||
float initialAngle() const {return initialAngle_;}
|
||||
float initialSpeed() const {return initialSpeed_;}
|
||||
float speedDecay() const {return speedDecay_;}
|
||||
float baseAngle() const {return baseAngle_;}
|
||||
QVector3D speedDirection() const {return speedDirection_;}
|
||||
QVector3D emitterPosition() const {return emitterPosition_;}
|
||||
QVector3D emitterDirection() const {return emitterDirection_;}
|
||||
Box3D emitterRect() const {return emitterRect_;}
|
||||
float lifeDurationJitter() const {return lifeDurationJitter_;}
|
||||
float speedJitter() const {return speedJitter_;}
|
||||
float speedDirectionJitter() const {return speedDirectionJitter_;}
|
||||
float sizeJitter() const {return sizeJitter_;}
|
||||
float enlargeSpeedJitter() const {return enlargeSpeedJitter_;}
|
||||
float angleJitter() const {return angleJitter_;}
|
||||
bool isActive() const {return active_;}
|
||||
bool isBirthEnabled() const {return birthEnabled_;}
|
||||
GLParticlesSystem::Type emitterType() const {return emitterType_;}
|
||||
float fadeTime() const {return fade_time;}
|
||||
bool isAddVerticalFaceEnabled() const {return add_vert_face;}
|
||||
float birthRate() const { return birthRate_; }
|
||||
float lifeDuration() const { return lifeDuration_; }
|
||||
float size() const { return size_; }
|
||||
float enlargeSpeed() const { return enlargeSpeed_; }
|
||||
float initialAngle() const { return initialAngle_; }
|
||||
float initialSpeed() const { return initialSpeed_; }
|
||||
float speedDecay() const { return speedDecay_; }
|
||||
float baseAngle() const { return baseAngle_; }
|
||||
QVector3D speedDirection() const { return speedDirection_; }
|
||||
QVector3D emitterPosition() const { return emitterPosition_; }
|
||||
QVector3D emitterDirection() const { return emitterDirection_; }
|
||||
Box3D emitterRect() const { return emitterRect_; }
|
||||
float lifeDurationJitter() const { return lifeDurationJitter_; }
|
||||
float speedJitter() const { return speedJitter_; }
|
||||
float speedDirectionJitter() const { return speedDirectionJitter_; }
|
||||
float sizeJitter() const { return sizeJitter_; }
|
||||
float enlargeSpeedJitter() const { return enlargeSpeedJitter_; }
|
||||
float angleJitter() const { return angleJitter_; }
|
||||
bool isActive() const { return active_; }
|
||||
bool isBirthEnabled() const { return birthEnabled_; }
|
||||
GLParticlesSystem::Type emitterType() const { return emitterType_; }
|
||||
float fadeTime() const { return fade_time; }
|
||||
bool isAddVerticalFaceEnabled() const { return add_vert_face; }
|
||||
|
||||
void setBirthRate(const float & arg) {birthRate_ = arg; tick_birth = birthRate_ / freq;}
|
||||
void setLifeDuration(const float & arg) {lifeDuration_ = arg;}
|
||||
void setSize(const float & arg) {size_ = arg;}
|
||||
void setEnlargeSpeed(const float & arg) {enlargeSpeed_ = arg;}
|
||||
void setInitialAngle(const float & arg) {initialAngle_ = arg;}
|
||||
void setInitialSpeed(const float & arg) {initialSpeed_ = arg;}
|
||||
void setBaseAngle(const float & arg) {baseAngle_ = arg;}
|
||||
void setSpeedDecay(const float & arg) {speedDecay_ = arg;}
|
||||
void setSpeedDirection(const QVector3D & arg) {speedDirection_ = arg;}
|
||||
void setEmitterPosition(const QVector3D & arg) {emitterPosition_ = arg;}
|
||||
void setEmitterDirection(const QVector3D & arg) {emitterDirection_ = arg.normalized();}
|
||||
void setEmitterRect(const Box3D & arg) {emitterRect_ = arg;}
|
||||
void setLifeDurationJitter(const float & arg) {lifeDurationJitter_ = arg;}
|
||||
void setSpeedJitter(const float & arg) {speedJitter_ = arg;}
|
||||
void setSpeedDirectionJitter(const float & arg) {speedDirectionJitter_ = arg;}
|
||||
void setSizeJitter(const float & arg) {sizeJitter_ = arg;}
|
||||
void setEnlargeSpeedJitter(const float & arg) {enlargeSpeedJitter_ = arg;}
|
||||
void setActive(const bool & arg) {active_ = arg;}
|
||||
void setAngleJitter(const float & arg) {angleJitter_ = arg;}
|
||||
void setBirthEnabled(const bool & arg) {birthEnabled_ = arg;}
|
||||
void setEmitterType(const GLParticlesSystem::Type & arg) {emitterType_ = arg;}
|
||||
void setFadeTime(const float & arg) {fade_time = 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 setBirthRate(const float & arg) {
|
||||
birthRate_ = arg;
|
||||
tick_birth = birthRate_ / freq;
|
||||
}
|
||||
void setLifeDuration(const float & arg) { lifeDuration_ = arg; }
|
||||
void setSize(const float & arg) { size_ = arg; }
|
||||
void setEnlargeSpeed(const float & arg) { enlargeSpeed_ = arg; }
|
||||
void setInitialAngle(const float & arg) { initialAngle_ = arg; }
|
||||
void setInitialSpeed(const float & arg) { initialSpeed_ = arg; }
|
||||
void setBaseAngle(const float & arg) { baseAngle_ = arg; }
|
||||
void setSpeedDecay(const float & arg) { speedDecay_ = arg; }
|
||||
void setSpeedDirection(const QVector3D & arg) { speedDirection_ = arg; }
|
||||
void setEmitterPosition(const QVector3D & arg) { emitterPosition_ = arg; }
|
||||
void setEmitterDirection(const QVector3D & arg) { emitterDirection_ = arg.normalized(); }
|
||||
void setEmitterRect(const Box3D & arg) { emitterRect_ = arg; }
|
||||
void setLifeDurationJitter(const float & arg) { lifeDurationJitter_ = arg; }
|
||||
void setSpeedJitter(const float & arg) { speedJitter_ = arg; }
|
||||
void setSpeedDirectionJitter(const float & arg) { speedDirectionJitter_ = arg; }
|
||||
void setSizeJitter(const float & arg) { sizeJitter_ = arg; }
|
||||
void setEnlargeSpeedJitter(const float & arg) { enlargeSpeedJitter_ = arg; }
|
||||
void setActive(const bool & arg) { active_ = arg; }
|
||||
void setAngleJitter(const float & arg) { angleJitter_ = arg; }
|
||||
void setBirthEnabled(const bool & arg) { birthEnabled_ = arg; }
|
||||
void setEmitterType(const GLParticlesSystem::Type & arg) { emitterType_ = arg; }
|
||||
void setFadeTime(const float & arg) { fade_time = 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 birthParticles(int count) {need_birth += count;}
|
||||
void addForce(const QVector3D & f) { forces << f; }
|
||||
void birthParticles(int count) { need_birth += count; }
|
||||
|
||||
float frequency() const {return freq;}
|
||||
void setFrequency(const float & f) {freq = f;}
|
||||
float frequency() const { return freq; }
|
||||
void setFrequency(const float & f) { freq = f; }
|
||||
|
||||
float additionalSpeed;
|
||||
|
||||
@@ -145,9 +156,10 @@ private:
|
||||
float lifeDurationJitter_, speedJitter_, speedDirectionJitter_, sizeJitter_, angleJitter_, initialAngle_;
|
||||
float enlargeSpeed_, enlargeSpeedJitter_, baseAngle_;
|
||||
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
|
||||
|
||||
@@ -28,7 +28,6 @@ void GLPrimitivePoint::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());
|
||||
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() {
|
||||
geom_prim = Quads;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
moveTo(pos);
|
||||
//init();
|
||||
// init();
|
||||
}
|
||||
|
||||
|
||||
void GLPrimitiveCube::init() {
|
||||
float hw = w / 2.f, hl = l / 2.f, hh = h / 2.f;
|
||||
//list = glGenLists(1);
|
||||
//glNewList(list, GL_COMPILE);
|
||||
//glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(), material_.color_diffuse.alphaF());
|
||||
// list = glGenLists(1);
|
||||
// glNewList(list, GL_COMPILE);
|
||||
// glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(),
|
||||
// material_.color_diffuse.alphaF());
|
||||
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_normals.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) {
|
||||
geom_prim = GLObjectBase::Triangles;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
swl = seg_wl;
|
||||
sh = seg_h;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
swl = seg_wl;
|
||||
sh = seg_h;
|
||||
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();
|
||||
return;
|
||||
QVector3D s(w, l, h);
|
||||
n = (v0 * 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();
|
||||
n = (v0 * 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;
|
||||
vbo.clear();
|
||||
vbo.init();
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
int hseg = sh + 1, wlseg = swl + 1;
|
||||
float crw, crl, a, ch, twl;
|
||||
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 {
|
||||
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]);
|
||||
@@ -178,43 +181,43 @@ void GLPrimitiveEllipsoid::init() {
|
||||
|
||||
|
||||
void GLPrimitiveAxis::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
float bs = 1.f;
|
||||
float as = 0.1f;
|
||||
float aw = 0.07f;
|
||||
float bs = 1.f;
|
||||
float as = 0.1f;
|
||||
float aw = 0.07f;
|
||||
float cr_x = 0.8f, cg_y = 0.75f, cb_z = 0.8f;
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(cr_x, 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-as, -aw, 0);
|
||||
glVertex3f(bs - as, -aw, 0);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs-as, 0, aw);
|
||||
glVertex3f(bs - as, 0, aw);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs-as, 0, -aw);
|
||||
glVertex3f(bs - as, 0, -aw);
|
||||
glColor3f(0, cg_y, 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-as, -aw);
|
||||
glVertex3f(0, bs - as, -aw);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(aw, bs-as, 0);
|
||||
glVertex3f(aw, bs - as, 0);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(-aw, bs-as, 0);
|
||||
glVertex3f(-aw, bs - as, 0);
|
||||
glColor3f(0, 0, cb_z);
|
||||
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(-aw, 0, bs-as);
|
||||
glVertex3f(-aw, 0, bs - as);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(0, aw, bs-as);
|
||||
glVertex3f(0, aw, bs - as);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(0, -aw, bs-as);
|
||||
glVertex3f(0, -aw, bs - as);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -22,51 +22,53 @@
|
||||
#include "globject.h"
|
||||
|
||||
|
||||
class GLPrimitivePoint: public GLObjectBase
|
||||
{
|
||||
class GLPrimitivePoint: public GLObjectBase {
|
||||
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);
|
||||
|
||||
private:
|
||||
double sz;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class GLPrimitiveLine: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveLine: public GLObjectBase {
|
||||
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);
|
||||
QVector3D point0() const {return p0;}
|
||||
QVector3D point1() const {return p1;}
|
||||
void setPoint0(const QVector3D & p) {p0 = p;}
|
||||
void setPoint1(const QVector3D & p) {p1 = p;}
|
||||
QVector3D point0() const { return p0; }
|
||||
QVector3D point1() const { return p1; }
|
||||
void setPoint0(const QVector3D & p) { p0 = p; }
|
||||
void setPoint1(const QVector3D & p) { p1 = p; }
|
||||
|
||||
private:
|
||||
QVector3D p0, p1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class GLPrimitiveCube: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveCube: public GLObjectBase {
|
||||
public:
|
||||
GLPrimitiveCube(float width = 1., float length = 1., float height = 1., QVector3D pos = QVector3D());
|
||||
virtual void init();
|
||||
|
||||
private:
|
||||
float w, l, h;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class GLPrimitiveEllipsoid: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveEllipsoid: public GLObjectBase {
|
||||
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();
|
||||
|
||||
private:
|
||||
void putTriangle(const QVector3D & v0, const QVector3D & v1, const QVector3D & v2);
|
||||
float w, l, h;
|
||||
@@ -74,10 +76,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class GLPrimitiveAxis: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveAxis: public GLObjectBase {
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "glrendererbase.h"
|
||||
|
||||
#include "globject.h"
|
||||
#include "qglview.h"
|
||||
|
||||
@@ -25,7 +26,7 @@ GLRendererBase::GLRendererBase(QGLView * view_): view(*view_) {
|
||||
white_image = QImage(1, 1, QImage::Format_ARGB32);
|
||||
white_image.fill(0xFFFFFFFF);
|
||||
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_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 dir[] = {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[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y();
|
||||
pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z();
|
||||
pos[3] = l.light_type == Light::Directional ? 0. : 1.;
|
||||
dir[0] = ld.x();
|
||||
dir[1] = ld.y();
|
||||
dir[2] = ld.z();
|
||||
col[0] = l.visible_ ? l.color().redF() * 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;
|
||||
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[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z();
|
||||
pos[3] = l.light_type == Light::Directional ? 0. : 1.;
|
||||
dir[0] = ld.x();
|
||||
dir[1] = ld.y();
|
||||
dir[2] = ld.z();
|
||||
col[0] = l.visible_ ? l.color().redF() * 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;
|
||||
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_SPECULAR, col);
|
||||
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) {
|
||||
glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
|
||||
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 {
|
||||
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) {
|
||||
/*foreach (QOpenGLShaderProgram * i, view.shaders_ppl) {
|
||||
i->bind();
|
||||
i->setUniformValue("lightsCount", lights_count);
|
||||
i->setUniformValue("acc_light", lights_count > 0);
|
||||
//i->setUniformValue("mat", mvm);
|
||||
i->bind();
|
||||
i->setUniformValue("lightsCount", lights_count);
|
||||
i->setUniformValue("acc_light", lights_count > 0);
|
||||
//i->setUniformValue("mat", mvm);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
#define BIND_TEXTURE(ch, map) if (rp.prev_tex[ch] != mat.map.bitmap_id) { \
|
||||
rp.prev_tex[ch] = mat.map.bitmap_id; \
|
||||
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());}
|
||||
#define BIND_TEXTURE(ch, map) \
|
||||
if (rp.prev_tex[ch] != mat.map.bitmap_id) { \
|
||||
rp.prev_tex[ch] = mat.map.bitmap_id; \
|
||||
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) {
|
||||
if (first_object) {
|
||||
@@ -99,12 +104,30 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
|
||||
setupShadersTextures(o, rp);
|
||||
Material & mat(o.material_);
|
||||
if (rp.light) {
|
||||
if (o.accept_light) {if (!rp.prev_light) {glSetLightEnabled(true); rp.prev_light = true;}}
|
||||
else {if (rp.prev_light) {glSetLightEnabled(false); rp.prev_light = false;}}
|
||||
if (o.accept_light) {
|
||||
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 (o.accept_fog) {if (!rp.prev_fog) {glSetFogEnabled(true); rp.prev_fog = true;}}
|
||||
else {if (rp.prev_fog) {glSetFogEnabled(false); rp.prev_fog = false;}}
|
||||
if (o.accept_fog) {
|
||||
if (!rp.prev_fog) {
|
||||
glSetFogEnabled(true);
|
||||
rp.prev_fog = true;
|
||||
}
|
||||
} else {
|
||||
if (rp.prev_fog) {
|
||||
glSetFogEnabled(false);
|
||||
rp.prev_fog = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rp.textures) {
|
||||
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) {
|
||||
int light_start, light_end, lmax;
|
||||
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);
|
||||
if (!view.lights_.isEmpty()) {
|
||||
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) {
|
||||
RenderingParameters rpl;
|
||||
rpl.pass = pass;
|
||||
rpl.pass = pass;
|
||||
rpl.light_pass = light_pass;
|
||||
rpl.shaders = shaders;
|
||||
rpl.textures = textures;
|
||||
rpl.shaders = shaders;
|
||||
rpl.textures = textures;
|
||||
rpl.light = rpl.prev_light = light;
|
||||
rpl.fog = rpl.prev_fog = fog;
|
||||
rpl.view_matrix = rp.view_matrix;
|
||||
rpl.prev_view_matrix = rp.prev_view_matrix;
|
||||
rpl.proj_matrix = rp.proj_matrix;
|
||||
rpl.prev_proj_matrix = rp.prev_proj_matrix;
|
||||
rpl.cam_offset_matrix = view.camera()->offsetMatrix();
|
||||
//qDebug() << "view:" << rp.view_matrix;
|
||||
for (int i = 0; i < 32; ++i) rpl.prev_tex[i] = 0;
|
||||
rpl.view_matrix = rp.view_matrix;
|
||||
rpl.prev_view_matrix = rp.prev_view_matrix;
|
||||
rpl.proj_matrix = rp.proj_matrix;
|
||||
rpl.prev_proj_matrix = rp.prev_proj_matrix;
|
||||
rpl.cam_offset_matrix = view.camera()->offsetMatrix();
|
||||
// qDebug() << "view:" << rp.view_matrix;
|
||||
for (int i = 0; i < 32; ++i)
|
||||
rpl.prev_tex[i] = 0;
|
||||
setupTextures(view.objects_, rpl, true);
|
||||
glSetLightEnabled(rpl.prev_light);
|
||||
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) {
|
||||
if (!o.isInit())
|
||||
o.init();
|
||||
if (!o.isTexturesLoaded())
|
||||
o.loadTextures();
|
||||
if (!o.isInit()) o.init();
|
||||
if (!o.isTexturesLoaded()) o.loadTextures();
|
||||
if (!o.visible_) return;
|
||||
if (rpl.pass == o.pass_) {
|
||||
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);
|
||||
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));
|
||||
glLineWidth(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);
|
||||
if (mat.reflectivity > 0.f) {
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
if (!mat.map_reflection.isEmpty()) mat.map_reflection.bind();
|
||||
else glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
} else glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
if (!mat.map_reflection.isEmpty())
|
||||
mat.map_reflection.bind();
|
||||
else
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
} else
|
||||
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};
|
||||
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);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, gm);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
///glLoadTransposeMatrixf(gm);
|
||||
/// glLoadTransposeMatrixf(gm);
|
||||
glScalef(-1., -1., -1.);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
if (rpl.shaders) {
|
||||
//qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram*)rpl.shaders, rpl.proj_matrix, curview, rpl.prev_proj_matrix, prevview);
|
||||
// qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram *)rpl.shaders, rpl.proj_matrix, curview, rpl.prev_proj_matrix, prevview);
|
||||
} else {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -245,60 +271,58 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri
|
||||
cam.rotateXY(-l->angle_end);
|
||||
cam.rotateZ(l->angle_end);
|
||||
l->dir1 = cam.direction() - rdir;*/
|
||||
//qDebug() << rdir << l->dir0 << l->dir1;
|
||||
// qDebug() << rdir << l->dir0 << l->dir1;
|
||||
RenderingParameters rpl;
|
||||
rpl.pass = GLObjectBase::Solid;
|
||||
rpl.shaders = prog;
|
||||
rpl.pass = GLObjectBase::Solid;
|
||||
rpl.shaders = prog;
|
||||
rpl.textures = rpl.light = rpl.fog = false;
|
||||
rpl.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
rpl.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
rpl.cam_offset_matrix = cam.offsetMatrix();
|
||||
rpl.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
rpl.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
rpl.cam_offset_matrix = cam.offsetMatrix();
|
||||
QMatrix4x4 mbias;
|
||||
mbias.scale(0.5, 0.5, 0.5);
|
||||
mbias.translate(1., 1., 1.);
|
||||
l->shadow_matrix = mbias*rpl.proj_matrix*rpl.view_matrix*rpl.cam_offset_matrix*mat;//;// * mbias;
|
||||
//qDebug() << mbias;
|
||||
//glPushMatrix();
|
||||
l->shadow_matrix = mbias * rpl.proj_matrix * rpl.view_matrix * rpl.cam_offset_matrix * mat; //;// * mbias;
|
||||
// qDebug() << mbias;
|
||||
// glPushMatrix();
|
||||
renderSingleShadow(view.objects_, rpl);
|
||||
//glPopMatrix();
|
||||
// glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters & rpl) {
|
||||
if (!o.isInit())
|
||||
o.init();
|
||||
if (!o.isInit()) o.init();
|
||||
if (!o.visible_) return;
|
||||
if (rpl.shaders) {
|
||||
//qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram*)rpl.shaders, rpl.proj_matrix, rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
|
||||
// qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram *)rpl.shaders, rpl.proj_matrix, rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
|
||||
} else {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
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_);
|
||||
glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_);
|
||||
o.draw((QOpenGLShaderProgram*)rpl.shaders, true);
|
||||
foreach (GLObjectBase * i, o.children_)
|
||||
o.draw((QOpenGLShaderProgram *)rpl.shaders, true);
|
||||
foreach(GLObjectBase * i, o.children_)
|
||||
renderSingleShadow(*i, rpl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
GLRendererBase::RenderingParameters::RenderingParameters() {
|
||||
shaders = nullptr;
|
||||
shaders = nullptr;
|
||||
cur_shader = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void GLRendererBase::RenderingParameters::prepare() {
|
||||
proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
viewproj_matrix = proj_matrix * view_matrix;
|
||||
normal_matrix = view_matrix.normalMatrix();
|
||||
proj_matrix_i = proj_matrix.inverted();
|
||||
view_matrix_i = view_matrix.inverted();
|
||||
proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
viewproj_matrix = proj_matrix * view_matrix;
|
||||
normal_matrix = view_matrix.normalMatrix();
|
||||
proj_matrix_i = proj_matrix.inverted();
|
||||
view_matrix_i = view_matrix.inverted();
|
||||
viewproj_matrix_i = viewproj_matrix.inverted();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLRENDERERBASE_H
|
||||
@@ -22,13 +22,15 @@
|
||||
#include "glcamera.h"
|
||||
#include "glshaders.h"
|
||||
|
||||
class GLRendererBase: public QObject , protected QOpenGLExtraFunctions
|
||||
{
|
||||
class GLRendererBase
|
||||
: public QObject
|
||||
, protected QOpenGLExtraFunctions {
|
||||
friend class QGLView;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GLRendererBase(QGLView * view_);
|
||||
virtual void prepareScene() {;}
|
||||
virtual void prepareScene() { ; }
|
||||
virtual void renderScene() = 0;
|
||||
|
||||
struct RenderingParameters {
|
||||
@@ -74,7 +76,6 @@ protected:
|
||||
QGLView & view;
|
||||
QImage white_image, violent_image;
|
||||
GLuint white_image_id, violent_image_id;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLRENDERERBASE_H
|
||||
|
||||
@@ -32,77 +32,74 @@ const char qgl_vertex_head[] =
|
||||
"in vec3 qgl_Vertex;\n"
|
||||
"vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * vec4(qgl_Vertex, 1);}\n";
|
||||
|
||||
const char qgl_fragment_head[] =
|
||||
"in vec2 qgl_FragTexture;\n"
|
||||
"in vec4 qgl_FragColor;\n"
|
||||
"out vec4 qgl_FragData[gl_MaxDrawBuffers];\n";
|
||||
const char qgl_fragment_head[] = "in vec2 qgl_FragTexture;\n"
|
||||
"in vec4 qgl_FragColor;\n"
|
||||
"out vec4 qgl_FragData[gl_MaxDrawBuffers];\n";
|
||||
|
||||
const char qgl_uniform[] =
|
||||
"uniform mat4 qgl_ModelViewMatrix;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrix;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrix;\n"
|
||||
"uniform mat3 qgl_NormalMatrix;\n"
|
||||
"uniform mat4 qgl_ModelViewMatrixInverse;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrixInverse;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrixInverse;\n"
|
||||
"uniform mat4 qgl_ModelViewMatrixTranspose;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrixTranspose;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrixTranspose;\n"
|
||||
"uniform mat4 qgl_ModelViewMatrixInverseTranspose;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n";
|
||||
const char qgl_uniform[] = "uniform mat4 qgl_ModelViewMatrix;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrix;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrix;\n"
|
||||
"uniform mat3 qgl_NormalMatrix;\n"
|
||||
"uniform mat4 qgl_ModelViewMatrixInverse;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrixInverse;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrixInverse;\n"
|
||||
"uniform mat4 qgl_ModelViewMatrixTranspose;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrixTranspose;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrixTranspose;\n"
|
||||
"uniform mat4 qgl_ModelViewMatrixInverseTranspose;\n"
|
||||
"uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n"
|
||||
"uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n";
|
||||
|
||||
const char qgl_structs[] =
|
||||
"const int qgl_MaxLights = 8;\n"
|
||||
"struct QGLLight {\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 position;\n"
|
||||
" vec4 direction;\n"
|
||||
" float intensity;\n"
|
||||
" float startAngle;\n"
|
||||
" float startAngleCos;\n"
|
||||
" float endAngle;\n"
|
||||
" float endAngleCos;\n"
|
||||
" float constantAttenuation;\n"
|
||||
" float linearAttenuation;\n"
|
||||
" float quadraticAttenuation;\n"
|
||||
" sampler2DShadow shadow;\n"
|
||||
//" sampler2D shadowColor\n"
|
||||
" mat4 shadowMatrix;\n"
|
||||
//" vec4 shadowDir0;\n"
|
||||
//" vec4 shadowDir1;\n"
|
||||
"};\n"
|
||||
"struct QGLMap {\n"
|
||||
" float offset;\n"
|
||||
" float amount;\n"
|
||||
" vec2 scale;\n"
|
||||
" sampler2D map;\n"
|
||||
"};\n"
|
||||
"struct QGLMaterial {\n"
|
||||
" float transparency;\n"
|
||||
" float reflectivity;\n"
|
||||
" float iof;\n"
|
||||
" float dispersion;\n"
|
||||
" vec4 color_diffuse;\n"
|
||||
" vec4 color_specular;\n"
|
||||
" vec4 color_self_illumination;\n"
|
||||
" QGLMap map_diffuse;\n"
|
||||
" QGLMap map_normal;\n"
|
||||
" QGLMap map_relief;\n"
|
||||
" QGLMap map_self_illumination;\n"
|
||||
" QGLMap map_specularity;\n"
|
||||
" QGLMap map_specular;\n"
|
||||
"};\n"
|
||||
"uniform QGLLight qgl_AmbientLight;\n"
|
||||
"uniform QGLLight qgl_Light[qgl_MaxLights];\n"
|
||||
"uniform QGLMaterial qgl_Material;\n";
|
||||
const char qgl_structs[] = "const int qgl_MaxLights = 8;\n"
|
||||
"struct QGLLight {\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 position;\n"
|
||||
" vec4 direction;\n"
|
||||
" float intensity;\n"
|
||||
" float startAngle;\n"
|
||||
" float startAngleCos;\n"
|
||||
" float endAngle;\n"
|
||||
" float endAngleCos;\n"
|
||||
" float constantAttenuation;\n"
|
||||
" float linearAttenuation;\n"
|
||||
" float quadraticAttenuation;\n"
|
||||
" sampler2DShadow shadow;\n"
|
||||
//" sampler2D shadowColor\n"
|
||||
" mat4 shadowMatrix;\n"
|
||||
//" vec4 shadowDir0;\n"
|
||||
//" vec4 shadowDir1;\n"
|
||||
"};\n"
|
||||
"struct QGLMap {\n"
|
||||
" float offset;\n"
|
||||
" float amount;\n"
|
||||
" vec2 scale;\n"
|
||||
" sampler2D map;\n"
|
||||
"};\n"
|
||||
"struct QGLMaterial {\n"
|
||||
" float transparency;\n"
|
||||
" float reflectivity;\n"
|
||||
" float iof;\n"
|
||||
" float dispersion;\n"
|
||||
" vec4 color_diffuse;\n"
|
||||
" vec4 color_specular;\n"
|
||||
" vec4 color_self_illumination;\n"
|
||||
" QGLMap map_diffuse;\n"
|
||||
" QGLMap map_normal;\n"
|
||||
" QGLMap map_relief;\n"
|
||||
" QGLMap map_self_illumination;\n"
|
||||
" QGLMap map_specularity;\n"
|
||||
" QGLMap map_specular;\n"
|
||||
"};\n"
|
||||
"uniform QGLLight qgl_AmbientLight;\n"
|
||||
"uniform QGLLight qgl_Light[qgl_MaxLights];\n"
|
||||
"uniform QGLMaterial qgl_Material;\n";
|
||||
|
||||
|
||||
QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file) {
|
||||
QFile f(file);
|
||||
if (!f.open(QIODevice::ReadOnly)) return "";
|
||||
QString all = QString::fromUtf8(f.readAll());
|
||||
int i = all.indexOf("#version");
|
||||
QString all = QString::fromUtf8(f.readAll());
|
||||
int i = all.indexOf("#version");
|
||||
QString version = all.mid(i + 8, all.indexOf("\n", i) - i - 8).trimmed();
|
||||
if (version.toInt() >= 150) {
|
||||
int ip = all.indexOf("\n", i);
|
||||
@@ -117,7 +114,7 @@ QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType ty
|
||||
all.insert(ip + 1, qgl_uniform);
|
||||
}
|
||||
prog->addShaderFromSourceCode(type, all);
|
||||
//qDebug() << "********" << all;
|
||||
// qDebug() << "********" << all;
|
||||
return all;
|
||||
}
|
||||
|
||||
@@ -126,20 +123,20 @@ bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QStrin
|
||||
prog->removeAllShaders();
|
||||
QDir d(dir);
|
||||
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);
|
||||
foreach (const QFileInfo & i, sl) {
|
||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
|
||||
foreach(const QFileInfo & i, sl) {
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
|
||||
loadShaderFile(prog, QOpenGLShader::Geometry, i.absoluteFilePath());
|
||||
}
|
||||
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
foreach (const QFileInfo & i, sl) {
|
||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
|
||||
foreach(const QFileInfo & i, sl) {
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
|
||||
loadShaderFile(prog, QOpenGLShader::Vertex, i.absoluteFilePath());
|
||||
}
|
||||
sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
foreach (const QFileInfo & i, sl) {
|
||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
|
||||
foreach(const QFileInfo & i, sl) {
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
|
||||
loadShaderFile(prog, QOpenGLShader::Fragment, i.absoluteFilePath());
|
||||
}
|
||||
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) {
|
||||
if (!prog) return;
|
||||
if (!prog->isLinked()) return;
|
||||
QMatrix4x4 mvpm = proj * view;
|
||||
QMatrix4x4 mvpm = proj * view;
|
||||
QMatrix4x4 pmvpm = prevproj * prevview;
|
||||
QMatrix3x3 nm = view.normalMatrix();
|
||||
//nm.in;
|
||||
QMatrix3x3 nm = view.normalMatrix();
|
||||
// nm.in;
|
||||
prog->setUniformValue("qgl_ModelViewMatrix", view);
|
||||
prog->setUniformValue("qgl_ProjectionMatrix", proj);
|
||||
prog->setUniformValue("prev_ModelViewProjectioMatrix", pmvpm);
|
||||
prog->setUniformValue("prev_ModelViewMatrix", prevview);
|
||||
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
|
||||
prog->setUniformValue("qgl_NormalMatrix", nm);
|
||||
//prog->setUniformValue("qgl_BumpMatrix", nm.);
|
||||
// prog->setUniformValue("qgl_BumpMatrix", nm.);
|
||||
prog->setUniformValue("qgl_ModelViewMatrixTranspose", view.transposed());
|
||||
prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj.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) {
|
||||
if (!prog) return;
|
||||
if (!prog->isLinked()) return;
|
||||
QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions();
|
||||
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
mat_diffuse[0] = mat.color_diffuse.redF();
|
||||
mat_diffuse[1] = mat.color_diffuse.greenF();
|
||||
mat_diffuse[2] = mat.color_diffuse.blueF();
|
||||
mat_diffuse[3] = mat.color_diffuse.alphaF() * (1.f - mat.transparency);
|
||||
QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions();
|
||||
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
mat_diffuse[0] = mat.color_diffuse.redF();
|
||||
mat_diffuse[1] = mat.color_diffuse.greenF();
|
||||
mat_diffuse[2] = mat.color_diffuse.blueF();
|
||||
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]);
|
||||
prog->setUniformValue("qgl_Material.transparency", mat.transparency);
|
||||
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_specularity", mat.map_specularity, 4, 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)
|
||||
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->isLinked()) return;
|
||||
QMatrix4x4 m = mat * light->worldTransform();
|
||||
QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1);//, dir0(light->dir0), dir1(light->dir1);
|
||||
pos = m * pos;
|
||||
dir = ((m * dir) - pos).normalized();
|
||||
QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1); //, dir0(light->dir0), dir1(light->dir1);
|
||||
pos = m * pos;
|
||||
dir = ((m * dir) - pos).normalized();
|
||||
float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f;
|
||||
if (light->light_type == Light::Omni)
|
||||
ang_start = ang_end = 180.;
|
||||
//qDebug() << "light" << light->name() << ulightn << pos;
|
||||
if (light->light_type == Light::Omni) ang_start = ang_end = 180.;
|
||||
// qDebug() << "light" << light->name() << ulightn << pos;
|
||||
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
|
||||
prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir);
|
||||
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 + ".shadowColor").toLatin1().constData(), shadow);
|
||||
prog->setUniformValue((ulightn + ".shadowMatrix").toLatin1().constData(), light->shadow_matrix);
|
||||
//qDebug() << light->shadow_matrix;
|
||||
//prog->setUniformValue((ulightn + ".shadowDir0").toLatin1().constData(), (mat * dir0));
|
||||
//prog->setUniformValue((ulightn + ".shadowDir1").toLatin1().constData(), (mat * dir1));
|
||||
//qDebug() << light->direction << light->dir0 << light->dir1;
|
||||
// qDebug() << light->shadow_matrix;
|
||||
// prog->setUniformValue((ulightn + ".shadowDir0").toLatin1().constData(), (mat * dir0));
|
||||
// prog->setUniformValue((ulightn + ".shadowDir1").toLatin1().constData(), (mat * dir1));
|
||||
// qDebug() << light->direction << light->dir0 << light->dir1;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,13 @@ class Light;
|
||||
|
||||
QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file);
|
||||
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 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);
|
||||
#endif // GLSHADERS_H
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
|
||||
bool GLTextureManager::loadTextures() {
|
||||
//glGenTextures();
|
||||
// glGenTextures();
|
||||
QFileInfoList fil;
|
||||
Animation anim;
|
||||
for (int i = 0; i < anim_pathes.size(); ++i) {
|
||||
anim.path = anim_pathes[i].second;
|
||||
anim.bitmaps.clear();
|
||||
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;
|
||||
anim.bitmaps << loadTexture(fi.filePath(), false);
|
||||
}
|
||||
@@ -35,7 +35,7 @@ bool GLTextureManager::loadTextures() {
|
||||
anim_ids << QPair<QString, Animation>(anim_pathes[i].second, anim);
|
||||
}
|
||||
anim_pathes.clear();
|
||||
foreach (const QString & i, tex_pathes)
|
||||
foreach(const QString & i, tex_pathes)
|
||||
loadTexture(i, true);
|
||||
tex_pathes.clear();
|
||||
return true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user