code format

This commit is contained in:
2022-12-14 14:14:33 +03:00
parent 09e5342956
commit cdb02fc9be
278 changed files with 15371 additions and 12176 deletions

View File

@@ -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;
}

View File

@@ -1,61 +1,61 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -1,43 +1,45 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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;

View File

@@ -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

View File

@@ -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));

View File

@@ -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

View File

@@ -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;

View File

@@ -1,34 +1,34 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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:
};

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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());
}

View File

@@ -1,42 +1,43 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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;

View File

@@ -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_;
};

View File

@@ -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;
}

View File

@@ -1,52 +1,53 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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;

View File

@@ -1,20 +1,20 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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;

View File

@@ -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());
}

View File

@@ -1,49 +1,50 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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;

View File

@@ -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);
}

View File

@@ -1,38 +1,41 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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;

View File

@@ -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);
}
}

View File

@@ -1,50 +1,53 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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;
};

View File

@@ -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);
}

View File

@@ -1,45 +1,45 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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);
}

View File

@@ -1,20 +1,20 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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);

View File

@@ -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();
};

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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"

View File

@@ -1,28 +1,29 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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);

View File

@@ -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

View File

@@ -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

View File

@@ -1,46 +1,47 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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");

View File

@@ -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);
}

View File

@@ -1,54 +1,61 @@
/*
QAD - Qt ADvanced
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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);

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -1,43 +1,43 @@
/*
PIQt - PIP <-> Qt convertions
PIQt - PIP <-> Qt convertions
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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);

View File

@@ -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

View File

@@ -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)));
}

View File

@@ -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

View File

@@ -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]));
}

View File

@@ -1,32 +1,33 @@
/*
PIQt Utils - Qt utilites for PIP
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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;
}

View File

@@ -1,20 +1,20 @@
/*
PIQt Utils - Qt utilites for PIP
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -1,28 +1,29 @@
/*
PIQt Utils - Qt utilites for PIP
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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();
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -1,20 +1,20 @@
/*
PIQt Utils - Qt utilites for PIP
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -1,20 +1,20 @@
/*
PIQt Utils - Qt utilites for PIP
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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()));

View File

@@ -1,20 +1,20 @@
/*
PIQt Utils - Qt utilites for PIP
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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