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 "aboutwindow.h"
#include "ui_aboutwindow.h"
#include "qad_types.h" #include "qad_types.h"
#include "qpiconfig.h" #include "qpiconfig.h"
#include "ui_aboutwindow.h"
#include <QApplication> #include <QApplication>
#include <QFile> #include <QFile>
#if QT_VERSION < 0x050000 #if QT_VERSION < 0x050000
@@ -23,13 +25,11 @@ AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWin
#ifdef ANDROID #ifdef ANDROID
QDialog::setStyleSheet("font: 12pt \"DejaVu Sans\";"); QDialog::setStyleSheet("font: 12pt \"DejaVu Sans\";");
#endif #endif
if (!stylesheet.isEmpty()) if (!stylesheet.isEmpty()) QDialog::setStyleSheet(stylesheet);
QDialog::setStyleSheet(stylesheet);
ui->setupUi(this); ui->setupUi(this);
ui->labelAuthors->setOpenExternalLinks(true); ui->labelAuthors->setOpenExternalLinks(true);
QImage logo_im = logo; QImage logo_im = logo;
if (logo_im.isNull()) if (logo_im.isNull()) logo_im.load(":/icons/splash.png");
logo_im.load(":/icons/splash.png");
setWindowTitle(QApplication::applicationName() + " - " + tr("About")); setWindowTitle(QApplication::applicationName() + " - " + tr("About"));
QIcon ic = QApplication::windowIcon(); QIcon ic = QApplication::windowIcon();
if (ic.isNull()) { if (ic.isNull()) {
@@ -40,8 +40,7 @@ AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWin
break; break;
} }
} }
if (ic.isNull()) if (ic.isNull()) ic = QIcon(QPixmap::fromImage(logo_im));
ic = QIcon(QPixmap::fromImage(logo_im));
setWindowIcon(ic); setWindowIcon(ic);
QFormLayout * lay = (QFormLayout *)(ui->groupVersions->layout()); QFormLayout * lay = (QFormLayout *)(ui->groupVersions->layout());
foreach(SSPair p, versions) { foreach(SSPair p, versions) {
@@ -80,8 +79,7 @@ AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWin
r.moveCenter(scr->availableGeometry().center()); r.moveCenter(scr->availableGeometry().center());
} }
# endif # endif
if (r.isValid()) if (r.isValid()) setGeometry(r);
setGeometry(r);
#endif #endif
} }
@@ -208,8 +206,7 @@ QString AboutWindow::authors() {
QString name, mail; QString name, mail;
name = l.left(l.indexOf("<")); name = l.left(l.indexOf("<"));
mail = l.mid(name.size() + 1); mail = l.mid(name.size() + 1);
if (mail.endsWith(">")) if (mail.endsWith(">")) mail.chop(1);
mail.chop(1);
name = name.trimmed(); name = name.trimmed();
mail = mail.trimmed(); mail = mail.trimmed();
addAuthor(ret, name, mail); addAuthor(ret, name, mail);
@@ -217,4 +214,3 @@ QString AboutWindow::authors() {
} }
return ret; return ret;
} }

View File

@@ -20,9 +20,10 @@
#ifndef ABOUTWINDOW_H #ifndef ABOUTWINDOW_H
#define ABOUTWINDOW_H #define ABOUTWINDOW_H
#include <QDialog>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QDialog>
#define ADD_ABOUT_VERSION(lib) \ #define ADD_ABOUT_VERSION(lib) \
{ \ { \
@@ -48,14 +49,13 @@ namespace Ui {
class AboutWindow; class AboutWindow;
} }
class QAD_APPLICATION_EXPORT AboutWindow: public QDialog class QAD_APPLICATION_EXPORT AboutWindow: public QDialog {
{
Q_OBJECT Q_OBJECT
typedef QPair<QString, QString> SSPair; typedef QPair<QString, QString> SSPair;
explicit AboutWindow(QWidget * parent = 0); explicit AboutWindow(QWidget * parent = 0);
~AboutWindow(); ~AboutWindow();
public:
public:
static void setLogo(QImage im); static void setLogo(QImage im);
static void setLogo(QString path); static void setLogo(QString path);
static void addVersion(QString name, QString version); static void addVersion(QString name, QString version);
@@ -77,7 +77,6 @@ private:
static QImage logo; static QImage logo;
static QVector<SSPair> versions, builds; static QVector<SSPair> versions, builds;
static QString stylesheet, comment; static QString stylesheet, comment;
}; };
#endif // ABOUTWINDOW_H #endif // ABOUTWINDOW_H

View File

@@ -1,5 +1,7 @@
#include "edockwidget.h" #include "edockwidget.h"
#include "qad_types.h" #include "qad_types.h"
#include <QEvent> #include <QEvent>
#include <QStyle> #include <QStyle>
@@ -40,7 +42,8 @@ bool EDockWidget::event(QEvent * e) {
void EDockWidget::init() { void EDockWidget::init() {
header = new QFrame(); header = new QFrame();
header->setFrameShape(QFrame::StyledPanel); header->setFrameShape(QFrame::StyledPanel);
QBoxLayout * lay = new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); QBoxLayout * lay =
new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
lay->setContentsMargins(2, 2, 2, 2); lay->setContentsMargins(2, 2, 2, 2);
lay->setSpacing(2); lay->setSpacing(2);
lbl_icon = new QLabel(); lbl_icon = new QLabel();

View File

@@ -20,23 +20,33 @@
#ifndef EDOCKWIDGET_H #ifndef EDOCKWIDGET_H
#define EDOCKWIDGET_H #define EDOCKWIDGET_H
#include <QDockWidget>
#include <QLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QIcon>
#include <QToolButton>
#include <QDebug>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QDebug>
#include <QDockWidget>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QLayout>
#include <QToolButton>
class QAD_APPLICATION_EXPORT EDockWidget: public QDockWidget
{ class QAD_APPLICATION_EXPORT EDockWidget: public QDockWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(title, parent, flags) {init();} explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags())
: QDockWidget(title, parent, flags) {
init();
}
explicit EDockWidget(QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(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;} ~EDockWidget() {
delete btn_hide;
delete btn_dock;
delete lbl_title;
delete lbl_icon;
delete header;
}
void setFeatures(QDockWidget::DockWidgetFeatures features); void setFeatures(QDockWidget::DockWidgetFeatures features);
void setWindowTitle(const QString & title); void setWindowTitle(const QString & title);
@@ -53,7 +63,6 @@ private:
private slots: private slots:
void dockClicked() { setFloating(!isFloating()); } void dockClicked() { setFloating(!isFloating()); }
}; };
#endif // EDOCKWIDGET_H #endif // EDOCKWIDGET_H

View File

@@ -1,12 +1,18 @@
#include "emainwindow.h" #include "emainwindow.h"
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox>
#include <QMenu>
#include <QLabel> #include <QLabel>
#include <QMenu>
#include <QMessageBox>
EMainWindow::EMainWindow(QWidget * parent): QMainWindow(parent), action_show_all_tools(this), action_hide_all_tools(this), EMainWindow::EMainWindow(QWidget * parent)
action_show_all_docks(this), action_hide_all_docks(this), first_show(true) { : QMainWindow(parent)
, 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; menu_recent = 0;
action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this); action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this);
connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent())); connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent()));
@@ -26,8 +32,7 @@ action_show_all_docks(this), action_hide_all_docks(this), first_show(true) {
} }
EMainWindow::~EMainWindow() { EMainWindow::~EMainWindow() {}
}
void EMainWindow::setRecentFiles(const QStringList & rl) { void EMainWindow::setRecentFiles(const QStringList & rl) {
@@ -67,8 +72,10 @@ void EMainWindow::showEvent(QShowEvent * e) {
void EMainWindow::closeEvent(QCloseEvent * e) { void EMainWindow::closeEvent(QCloseEvent * e) {
if (!checkSave()) e->ignore(); if (!checkSave())
else saveSession(); e->ignore();
else
saveSession();
} }
@@ -123,8 +130,7 @@ void EMainWindow::changeEvent(QEvent * e) {
action_hide_all_docks.setText(tr("Hide all")); action_hide_all_docks.setText(tr("Hide all"));
action_clear_recent->setText(tr("Clear recent list")); action_clear_recent->setText(tr("Clear recent list"));
break; break;
default: default: break;
break;
} }
} }
@@ -302,8 +308,7 @@ void EMainWindow::changedDock() {
// qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock; // qDebug() << i << t->tabText(i) << t->isTabVisible(i) << dock;
if (!dock) continue; if (!dock) continue;
if (!docks.contains(dock)) continue; if (!docks.contains(dock)) continue;
if (!geom.intersects(t->geometry())) if (!geom.intersects(t->geometry())) invalid_tab_docks << dock;
invalid_tab_docks << dock;
#ifndef Q_OS_MACOS #ifndef Q_OS_MACOS
QSize is = dockTabsIconSize(); QSize is = dockTabsIconSize();
if (t->iconSize() != is) t->setIconSize(is); if (t->iconSize() != is) t->setIconSize(is);
@@ -356,8 +361,7 @@ void EMainWindow::recentTriggered() {
QString path = a->data().toString(); QString path = a->data().toString();
if (path.isEmpty()) return; if (path.isEmpty()) return;
if (!checkSave()) return; if (!checkSave()) return;
if (load(path)) if (load(path)) addToRecent(path);
addToRecent(path);
} }
@@ -379,8 +383,7 @@ void EMainWindow::openFile() {
if (!checkSave()) return; if (!checkSave()) return;
QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter()); QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter());
if (ret.isEmpty()) return; if (ret.isEmpty()) return;
if (load(ret)) if (load(ret)) addToRecent(ret);
addToRecent(ret);
} }
@@ -388,22 +391,24 @@ void EMainWindow::openFiles() {
if (!checkSave()) return; if (!checkSave()) return;
QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter()); QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter());
foreach(QString s, ret) { foreach(QString s, ret) {
if (load(s)) if (load(s)) addToRecent(s);
addToRecent(s);
} }
} }
bool EMainWindow::saveFile(bool ask) { bool EMainWindow::saveFile(bool ask) {
if (ask) { if (ask) {
int ret = QMessageBox::question(this, windowTitle(), tr("Save changes%1?").arg(!file_name.isEmpty() ? (tr(" in") + " \"" + file_name + "\"") : ""), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); int ret = QMessageBox::question(this,
windowTitle(),
tr("Save changes%1?").arg(!file_name.isEmpty() ? (tr(" in") + " \"" + file_name + "\"") : ""),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save);
if (ret == QMessageBox::Cancel) return false; if (ret == QMessageBox::Cancel) return false;
if (ret == QMessageBox::Save) return saveFile(); if (ret == QMessageBox::Save) return saveFile();
return true; return true;
} }
if (file_name.isEmpty()) return saveAsFile(); if (file_name.isEmpty()) return saveAsFile();
if (save(file_name)) if (save(file_name)) addToRecent(file_name);
addToRecent(file_name);
return true; return true;
} }
@@ -411,8 +416,7 @@ bool EMainWindow::saveFile(bool ask) {
bool EMainWindow::saveAsFile() { bool EMainWindow::saveAsFile() {
QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter()); QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter());
if (ret.isEmpty()) return false; if (ret.isEmpty()) return false;
if (save(ret)) if (save(ret)) addToRecent(ret);
addToRecent(ret);
return true; return true;
} }

View File

@@ -20,22 +20,24 @@
#ifndef EMAINWINDOW_H #ifndef EMAINWINDOW_H
#define EMAINWINDOW_H #define EMAINWINDOW_H
#include "qad_application_export.h"
#include "ribbon.h"
#include "session_manager.h"
#include <QClipboard>
#include <QColorDialog>
#include <QInputDialog>
#include <QRadioButton>
#include <QSplitter>
#include <QThread>
#include <QTime>
#include <QTranslator> #include <QTranslator>
#include <QUrl> #include <QUrl>
#include <QInputDialog>
#include <QClipboard>
#include <QRadioButton>
#include <QThread>
#include <QColorDialog>
#include <QTime>
#include <QSplitter>
#include "session_manager.h"
#include "ribbon.h"
#include "qad_application_export.h"
class QAD_APPLICATION_EXPORT UAction: public QAction { class QAD_APPLICATION_EXPORT UAction: public QAction {
Q_OBJECT Q_OBJECT
public: public:
UAction(int ind, const QString & text, QObject * parent): QAction(text, parent) { UAction(int ind, const QString & text, QObject * parent): QAction(text, parent) {
index = ind; index = ind;
@@ -54,6 +56,7 @@ public slots:
void hide() { setVisible(false); } void hide() { setVisible(false); }
void setCheckedTrue() { setChecked(true); } void setCheckedTrue() { setChecked(true); }
void setCheckedFalse() { setChecked(false); } void setCheckedFalse() { setChecked(false); }
private: private:
int index; int index;
private slots: private slots:
@@ -67,10 +70,10 @@ signals:
}; };
class QAD_APPLICATION_EXPORT EMainWindow: public QMainWindow class QAD_APPLICATION_EXPORT EMainWindow: public QMainWindow {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems) Q_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems)
public: public:
EMainWindow(QWidget * parent = 0); EMainWindow(QWidget * parent = 0);
~EMainWindow(); ~EMainWindow();
@@ -96,7 +99,12 @@ protected:
void addToRecent(const QString & path); void addToRecent(const QString & path);
void prepareRecent(); void prepareRecent();
void init(const QString & config) {session.setFile(config); initMenus(); initSession(); loadSession();} // unusable void init(const QString & config) {
session.setFile(config);
initMenus();
initSession();
loadSession();
} // unusable
void saveSession(); void saveSession();
void loadSession(); void loadSession();
virtual void savingSession(QPIConfig & conf) {} virtual void savingSession(QPIConfig & conf) {}
@@ -106,7 +114,10 @@ protected:
virtual QString saveFilter() { return "All files(*)"; } virtual QString saveFilter() { return "All files(*)"; }
bool checkSave(); bool checkSave();
void setChanged(bool yes = true) {isChanged = yes; setWindowModified(yes);} void setChanged(bool yes = true) {
isChanged = yes;
setWindowModified(yes);
}
void initMenus(); void initMenus();
void initSession(); void initSession();
@@ -141,7 +152,6 @@ public slots:
void clearRecent(); void clearRecent();
signals: signals:
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@@ -12,7 +12,8 @@ void ETabWidget::retranslate() {
buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/); buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/);
QList<QToolButton *> bl = findChildren<QToolButton *>(); QList<QToolButton *> bl = findChildren<QToolButton *>();
foreach(QToolButton * i, bl) foreach(QToolButton * i, bl)
i->setToolTip(QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/)); i->setToolTip(
QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/));
} }
@@ -43,12 +44,10 @@ int ETabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label
void ETabWidget::setButtonVisible(int role, bool yes) { void ETabWidget::setButtonVisible(int role, bool yes) {
QList<QToolButton *> bl = findChildren<QToolButton *>(); QList<QToolButton *> bl = findChildren<QToolButton *>();
foreach(QToolButton * i, bl) foreach(QToolButton * i, bl)
if (i->property("buttonRole").toInt() == role) if (i->property("buttonRole").toInt() == role) i->setVisible(yes);
i->setVisible(yes);
QWidget * w; QWidget * w;
for (int i = 0; i < buttons.size(); ++i) { for (int i = 0; i < buttons.size(); ++i) {
if (buttons[i].role == role) if (buttons[i].role == role) buttons[i].visible = yes;
buttons[i].visible = yes;
w = tabBar()->tabButton(i, QTabBar::RightSide); w = tabBar()->tabButton(i, QTabBar::RightSide);
if (w != 0) w->adjustSize(); if (w != 0) w->adjustSize();
} }
@@ -94,11 +93,8 @@ bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
void ETabWidget::changeEvent(QEvent * e) { void ETabWidget::changeEvent(QEvent * e) {
QTabWidget::changeEvent(e); QTabWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: retranslate(); break;
retranslate(); default: break;
break;
default:
break;
} }
} }

View File

@@ -20,22 +20,23 @@
#ifndef ETABWIDGET_H #ifndef ETABWIDGET_H
#define ETABWIDGET_H #define ETABWIDGET_H
#include <QTabWidget>
#include <QDebug>
#include <QTabBar>
#include <QMouseEvent>
#include <QEvent>
#include <QToolButton>
#include <QPushButton>
#include <QLayout>
#include <QHBoxLayout>
#include <QApplication>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QApplication>
#include <QDebug>
#include <QEvent>
#include <QHBoxLayout>
#include <QLayout>
#include <QMouseEvent>
#include <QPushButton>
#include <QTabBar>
#include <QTabWidget>
#include <QToolButton>
class QAD_APPLICATION_EXPORT ETabWidget: public QTabWidget
{ class QAD_APPLICATION_EXPORT ETabWidget: public QTabWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit ETabWidget(QWidget * parent = 0); explicit ETabWidget(QWidget * parent = 0);
@@ -52,7 +53,13 @@ private:
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
struct QAD_APPLICATION_EXPORT TabButton { struct QAD_APPLICATION_EXPORT TabButton {
TabButton(int r, const QIcon & i, const QString & t) {role = r; icon = i; visible = true; srcToolTip = t; toolTip = QApplication::translate("MainWindow", t.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);} TabButton(int r, const QIcon & i, const QString & t) {
role = r;
icon = i;
visible = true;
srcToolTip = t;
toolTip = QApplication::translate("MainWindow", t.toUtf8(), 0 /*, QCoreApplication::UnicodeUTF8*/);
}
int role; int role;
bool visible; bool visible;
QIcon icon; QIcon icon;
@@ -69,7 +76,6 @@ signals:
void countChanged(); void countChanged();
void tabHovered(int tab); void tabHovered(int tab);
void tabButtonClicked(int tab, int role); void tabButtonClicked(int tab, int role);
}; };
#endif // ETABWIDGET_H #endif // ETABWIDGET_H

View File

@@ -1,6 +1,7 @@
#include "historyview.h" #include "historyview.h"
#include <QScrollBar>
#include <QEvent> #include <QEvent>
#include <QScrollBar>
HistoryView::HistoryView(QWidget * parent): QListWidget(parent) { HistoryView::HistoryView(QWidget * parent): QListWidget(parent) {
@@ -19,8 +20,7 @@ HistoryView::HistoryView(QWidget* parent): QListWidget(parent) {
} }
HistoryView::~HistoryView() { HistoryView::~HistoryView() {}
}
QByteArray HistoryView::current() const { QByteArray HistoryView::current() const {
@@ -37,8 +37,7 @@ void HistoryView::addEntry(int action, int count_, const QString & suffix) {
QByteArray ba; QByteArray ba;
emit commandRequest(ba); emit commandRequest(ba);
if (!duplicates_) if (!duplicates_)
if (current() == ba) if (current() == ba) return;
return;
int cnt = count(); int cnt = count();
for (int i = index; i < cnt; ++i) for (int i = index; i < cnt; ++i)
if (i >= 0) delete takeItem(index); if (i >= 0) delete takeItem(index);
@@ -94,11 +93,8 @@ void HistoryView::checkLimit() {
void HistoryView::changeEvent(QEvent * e) { void HistoryView::changeEvent(QEvent * e) {
QListWidget::changeEvent(e); QListWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: actions_[-1].text = tr("History cleared"); break;
actions_[-1].text = tr("History cleared"); default: break;
break;
default:
break;
} }
} }

View File

@@ -20,18 +20,19 @@
#ifndef HISTORYVIEW_H #ifndef HISTORYVIEW_H
#define HISTORYVIEW_H #define HISTORYVIEW_H
#include <QListWidget>
#include <QDebug>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QDebug>
#include <QListWidget>
class QAD_APPLICATION_EXPORT HistoryView: public QListWidget
{ class QAD_APPLICATION_EXPORT HistoryView: public QListWidget {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive) Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled) Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled)
Q_PROPERTY(int limit READ limit WRITE setLimit) Q_PROPERTY(int limit READ limit WRITE setLimit)
Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor) Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor)
public: public:
explicit HistoryView(QWidget * parent = 0); explicit HistoryView(QWidget * parent = 0);
~HistoryView(); ~HistoryView();
@@ -95,7 +96,6 @@ signals:
void commandRequest(QByteArray & s); void commandRequest(QByteArray & s);
void commandExecute(const QByteArray & s); void commandExecute(const QByteArray & s);
void changed(); void changed();
}; };
#endif // HISTORYVIEW_H #endif // HISTORYVIEW_H

View File

@@ -1,15 +1,17 @@
#include "logview.h" #include "logview.h"
#include "ui_logview.h"
#include "qad_types.h"
#include "ecombobox.h" #include "ecombobox.h"
#include <QTextDocument> #include "qad_types.h"
#include "ui_logview.h"
#include <QAbstractTextDocumentLayout> #include <QAbstractTextDocumentLayout>
#include <QTextEdit>
#include <QTextBlock>
#include <QScrollBar>
#include <QPixmap>
#include <QEvent> #include <QEvent>
#include <QPixmap>
#include <QScrollBar>
#include <QTextBlock>
#include <QTextBlockUserData> #include <QTextBlockUserData>
#include <QTextDocument>
#include <QTextEdit>
class TextBlockData: public QTextBlockUserData { class TextBlockData: public QTextBlockUserData {
@@ -19,8 +21,6 @@ public:
}; };
LogView::Category::Category() { LogView::Category::Category() {
bold = false; bold = false;
} }
@@ -104,7 +104,12 @@ int LogView::linesLimit() const {
} }
void LogView::registerCategory(const QString & label, QString keyword, const QImage & icon, QBrush text_brush, QBrush background, bool bold) { void LogView::registerCategory(const QString & label,
QString keyword,
const QImage & icon,
QBrush text_brush,
QBrush background,
bool bold) {
QRegularExpression regexp(keyword, QRegularExpression regexp(keyword,
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption) QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
@@ -116,7 +121,12 @@ void LogView::registerCategory(const QString & label, QString keyword, const QIm
} }
void LogView::registerCategory(const QString & label, QRegularExpression regexp, const QImage & icon, QBrush text_brush, QBrush background, bool bold) { void LogView::registerCategory(const QString & label,
QRegularExpression regexp,
const QImage & icon,
QBrush text_brush,
QBrush background,
bool bold) {
if (!regexp.isValid() || regexp.pattern().isEmpty()) return; if (!regexp.isValid() || regexp.pattern().isEmpty()) return;
removeCategory(regexp); removeCategory(regexp);
Category c; Category c;
@@ -126,9 +136,11 @@ void LogView::registerCategory(const QString & label, QRegularExpression regexp,
c.text_brush = text_brush; c.text_brush = text_brush;
c.background = background; c.background = background;
c.bold = bold; c.bold = bold;
c.makeIcon(iconImageSize(), preferredIconSize(1., this) c.makeIcon(iconImageSize(),
preferredIconSize(1., this)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
, devicePixelRatioF() ,
devicePixelRatioF()
#endif #endif
); );
categories.append(c); categories.append(c);
@@ -153,7 +165,8 @@ void LogView::removeCategory(QRegularExpression regexp) {
c.regexp = regexp; c.regexp = regexp;
categories.removeAll(c); categories.removeAll(c);
for (int i = 1; i < ui->comboCategory->count(); ++i) { for (int i = 1; i < ui->comboCategory->count(); ++i) {
if (ui->comboCategory->itemData(i). if (ui->comboCategory->itemData(i)
.
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
toRegularExpression() toRegularExpression()
#else #else
@@ -191,13 +204,10 @@ void LogView::addText(const QString & text, const QString & keyword, bool insert
bool at_end = (bar->value() == bar->maximum()) || bar->isHidden(); bool at_end = (bar->value() == bar->maximum()) || bar->isHidden();
for (int i = 0; i < sl.size(); ++i) { for (int i = 0; i < sl.size(); ++i) {
tc.insertText(sl[i]); tc.insertText(sl[i]);
if (!keyword.isEmpty()) if (!keyword.isEmpty()) tc.block().setUserData(new TextBlockData(keyword));
tc.block().setUserData(new TextBlockData(keyword)); if ((i < sl.size() - 1) || insert_newline) newLine(keyword);
if ((i < sl.size() - 1) || insert_newline)
newLine(keyword);
} }
if (at_end) if (at_end) scrollToBottom();
scrollToBottom();
} }
@@ -215,9 +225,11 @@ void LogView::changeEvent(QEvent * e) {
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this)); ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
QSize is = iconImageSize(), is_i = preferredIconSize(1., this); QSize is = iconImageSize(), is_i = preferredIconSize(1., this);
for (int i = 0; i < categories.size(); ++i) for (int i = 0; i < categories.size(); ++i)
categories[i].makeIcon(is, is_i categories[i].makeIcon(is,
is_i
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
, devicePixelRatioF() ,
devicePixelRatioF()
#endif #endif
); );
} break; } break;
@@ -234,17 +246,16 @@ void LogView::newLine(const QString & keyword) {
QImage icon; QImage icon;
foreach(const Category & c, categories) { foreach(const Category & c, categories) {
bool matched = false; bool matched = false;
if (keyword.isEmpty()) matched = line.contains(c.regexp); if (keyword.isEmpty())
else matched = (keyword == c.regexp.pattern()); matched = line.contains(c.regexp);
else
matched = (keyword == c.regexp.pattern());
if (matched) { if (matched) {
QTextCharFormat cf = def_cf; QTextCharFormat cf = def_cf;
QTextBlockFormat bf = def_bf; QTextBlockFormat bf = def_bf;
if (c.text_brush != Qt::NoBrush) if (c.text_brush != Qt::NoBrush) cf.setForeground(c.text_brush);
cf.setForeground(c.text_brush); if (c.background != Qt::NoBrush) bf.setBackground(c.background);
if (c.background != Qt::NoBrush) if (c.bold) cf.setFontWeight(QFont::Bold);
bf.setBackground(c.background);
if (c.bold)
cf.setFontWeight(QFont::Bold);
tc.setCharFormat(cf); tc.setCharFormat(cf);
tc.setBlockFormat(bf); tc.setBlockFormat(bf);
icon = c.icon_image; icon = c.icon_image;
@@ -262,8 +273,7 @@ void LogView::newLine(const QString & keyword) {
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp(); ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
#endif #endif
QString fs = ui->lineEdit->text(); QString fs = ui->lineEdit->text();
if (isFilterVisible()) if (isFilterVisible()) filterBlock(tc.block(), fs, regexp);
filterBlock(tc.block(), fs, regexp);
tc.movePosition(QTextCursor::End); tc.movePosition(QTextCursor::End);
tc.setCharFormat(def_cf); tc.setCharFormat(def_cf);
tc.insertBlock(); tc.insertBlock();
@@ -281,8 +291,7 @@ void LogView::filterBlock(QTextBlock block, const QString & fs, const QRegularEx
bool vis = true; //, pvis = block.isVisible(); bool vis = true; //, pvis = block.isVisible();
QString line = block.text(); QString line = block.text();
if (!line.isEmpty()) { if (!line.isEmpty()) {
if (line[0] == QChar::ObjectReplacementCharacter) if (line[0] == QChar::ObjectReplacementCharacter) line.remove(0, 1);
line.remove(0, 1);
} }
if (regexp.isValid() && !regexp.pattern().isEmpty()) { if (regexp.isValid() && !regexp.pattern().isEmpty()) {
QString kw; QString kw;

View File

@@ -20,10 +20,10 @@
#ifndef LOGVIEW_H #ifndef LOGVIEW_H
#define LOGVIEW_H #define LOGVIEW_H
#include <QWidget>
#include <QIcon> #include <QIcon>
#include <QImage> #include <QImage>
#include <QTextBlockFormat> #include <QTextBlockFormat>
#include <QWidget>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QRegularExpression> # include <QRegularExpression>
#else #else
@@ -40,12 +40,12 @@ namespace Ui {
class LogView; class LogView;
} }
class QAD_APPLICATION_EXPORT LogView: public QWidget class QAD_APPLICATION_EXPORT LogView: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool filterVisible READ isFilterVisible WRITE setFilterVisible) Q_PROPERTY(bool filterVisible READ isFilterVisible WRITE setFilterVisible)
Q_PROPERTY(int linesLimit READ linesLimit WRITE setLinesLimit) Q_PROPERTY(int linesLimit READ linesLimit WRITE setLinesLimit)
Q_PROPERTY(QFont logFont READ logFont WRITE setLogFont) Q_PROPERTY(QFont logFont READ logFont WRITE setLogFont)
public: public:
explicit LogView(QWidget * parent = 0); explicit LogView(QWidget * parent = 0);
~LogView(); ~LogView();
@@ -112,7 +112,6 @@ private slots:
void filter(); void filter();
signals: signals:
}; };

View File

@@ -1,5 +1,7 @@
#include "edockwidget.h"
#include "edockwidgetplugin.h" #include "edockwidgetplugin.h"
#include "edockwidget.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ EDockWidgetPlugin::EDockWidgetPlugin(QObject * parent): QObject(parent) {
void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString EDockWidgetPlugin::domXml() const {
QString EDockWidgetPlugin::includeFile() const { QString EDockWidgetPlugin::includeFile() const {
return QLatin1String("edockwidget.h"); return QLatin1String("edockwidget.h");
} }

View File

@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class EDockWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface class EDockWidgetPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif #endif

View File

@@ -1,5 +1,7 @@
#include "emainwindow.h"
#include "emainwindowplugin.h" #include "emainwindowplugin.h"
#include "emainwindow.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ EMainWindowPlugin::EMainWindowPlugin(QObject * parent): QObject(parent) {
void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString EMainWindowPlugin::domXml() const {
QString EMainWindowPlugin::includeFile() const { QString EMainWindowPlugin::includeFile() const {
return QLatin1String("emainwindow.h"); return QLatin1String("emainwindow.h");
} }

View File

@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class EMainWindowPlugin: public QObject, public QDesignerCustomWidgetInterface class EMainWindowPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif #endif

View File

@@ -1,5 +1,7 @@
#include "historyview.h"
#include "historyviewplugin.h" #include "historyviewplugin.h"
#include "historyview.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ HistoryViewPlugin::HistoryViewPlugin(QObject * parent): QObject(parent) {
void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString HistoryViewPlugin::domXml() const {
QString HistoryViewPlugin::includeFile() const { QString HistoryViewPlugin::includeFile() const {
return QLatin1String("historyview.h"); return QLatin1String("historyview.h");
} }

View File

@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class HistoryViewPlugin: public QObject, public QDesignerCustomWidgetInterface class HistoryViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif // HISTORYVIEWPLUGIN_H #endif // HISTORYVIEWPLUGIN_H

View File

@@ -1,5 +1,7 @@
#include "logview.h"
#include "logviewplugin.h" #include "logviewplugin.h"
#include "logview.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ LogViewPlugin::LogViewPlugin(QObject * parent): QObject(parent) {
void LogViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void LogViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString LogViewPlugin::domXml() const {
QString LogViewPlugin::includeFile() const { QString LogViewPlugin::includeFile() const {
return QLatin1String("logview.h"); return QLatin1String("logview.h");
} }

View File

@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class LogViewPlugin: public QObject, public QDesignerCustomWidgetInterface class LogViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif // LOGVIEWPLUGIN_H #endif // LOGVIEWPLUGIN_H

View File

@@ -1,4 +1,5 @@
#include "qad_application.h" #include "qad_application.h"
#include "edockwidgetplugin.h" #include "edockwidgetplugin.h"
#include "emainwindowplugin.h" #include "emainwindowplugin.h"
#include "historyviewplugin.h" #include "historyviewplugin.h"

View File

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

View File

@@ -1,6 +1,7 @@
#include <QDebug>
#include "qsingleapplication.h" #include "qsingleapplication.h"
#include <QDebug>
#define QSA_SHMSIZE 4096 #define QSA_SHMSIZE 4096
#define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32)) #define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32))
@@ -13,8 +14,7 @@ QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
if (!first) { if (!first) {
shm.detach(); shm.detach();
first = !shm.attach(); first = !shm.attach();
if (!first) if (!first) return;
return;
} }
shm.create(QSA_SHMSIZE); shm.create(QSA_SHMSIZE);
shm.attach(); shm.attach();
@@ -31,8 +31,7 @@ QSingleApplication::~QSingleApplication() {
if (first) { if (first) {
exiting = true; exiting = true;
quit(); quit();
if (!wait(100)) if (!wait(100)) terminate();
terminate();
} }
if (shm.isAttached()) shm.detach(); if (shm.isAttached()) shm.detach();
} }

View File

@@ -20,14 +20,15 @@
#ifndef QSINGLEAPPLICATION_H #ifndef QSINGLEAPPLICATION_H
#define QSINGLEAPPLICATION_H #define QSINGLEAPPLICATION_H
#include <QThread>
#include <QSharedMemory>
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QSharedMemory>
#include <QThread>
class QAD_APPLICATION_EXPORT QSingleApplication: public QThread
{ class QAD_APPLICATION_EXPORT QSingleApplication: public QThread {
Q_OBJECT Q_OBJECT
public: public:
QSingleApplication(const QString & app_name = QString("qapp")); QSingleApplication(const QString & app_name = QString("qapp"));
~QSingleApplication(); ~QSingleApplication();
@@ -45,7 +46,6 @@ public slots:
signals: signals:
void messageReceived(QByteArray); void messageReceived(QByteArray);
}; };
#endif // QSINGLEAPPLICATION_H #endif // QSINGLEAPPLICATION_H

View File

@@ -1,5 +1,7 @@
#include "ribbon.h" #include "ribbon.h"
#include "qad_types.h" #include "qad_types.h"
#include <QScrollBar> #include <QScrollBar>
@@ -13,37 +15,31 @@ Ribbon::Ribbon(QMainWindow * parent_): QToolBar() {
setProperty("ribbon", true); setProperty("ribbon", true);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
parent = parent_; parent = parent_;
if (parent_) if (parent_) parent_->installEventFilter(this);
parent_->installEventFilter(this);
init(); init();
} }
Ribbon::~Ribbon() { Ribbon::~Ribbon() {}
}
bool Ribbon::eventFilter(QObject * o, QEvent * e) { bool Ribbon::eventFilter(QObject * o, QEvent * e) {
// qDebug() << e; // qDebug() << e;
if (o == parent) { if (o == parent) {
if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate) if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate) _resize();
_resize(); if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) _setIconsSize();
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish)
_setIconsSize();
return QToolBar::eventFilter(o, e); return QToolBar::eventFilter(o, e);
} }
if (e->type() == QEvent::ActionChanged) { if (e->type() == QEvent::ActionChanged) {
QToolButton * b = qobject_cast<QToolButton *>((QObject *)o->property("ribbonButton").toLongLong()); QToolButton * b = qobject_cast<QToolButton *>((QObject *)o->property("ribbonButton").toLongLong());
if (b != 0) if (b != 0) b->setEnabled(qobject_cast<QAction *>(o)->isEnabled());
b->setEnabled(qobject_cast<QAction * >(o)->isEnabled());
} }
return QToolBar::eventFilter(o, e); return QToolBar::eventFilter(o, e);
} }
void Ribbon::timerEvent(QTimerEvent * e) { void Ribbon::timerEvent(QTimerEvent * e) {
if (hovers.value(e->timerId(), -1) == hovered) if (hovers.value(e->timerId(), -1) == hovered) tab->setCurrentIndex(hovered);
tab->setCurrentIndex(hovered);
hovers.remove(e->timerId()); hovers.remove(e->timerId());
killTimer(e->timerId()); killTimer(e->timerId());
} }
@@ -52,11 +48,8 @@ void Ribbon::timerEvent(QTimerEvent * e) {
void Ribbon::changeEvent(QEvent * e) { void Ribbon::changeEvent(QEvent * e) {
QToolBar::changeEvent(e); QToolBar::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: retranslate(); break;
retranslate(); default: break;
break;
default:
break;
} }
} }
@@ -86,7 +79,6 @@ void Ribbon::_setButtonText(QToolButton * b, QAction * a) {
sc += "\n" + s.toString(QKeySequence::NativeText); sc += "\n" + s.toString(QKeySequence::NativeText);
} }
b->setToolTip(a->text() + sc); b->setToolTip(a->text() + sc);
} }
@@ -104,8 +96,7 @@ void Ribbon::init() {
QList<QAction *> lm = parent->menuBar()->actions(), la; QList<QAction *> lm = parent->menuBar()->actions(), la;
QString prev_tab; QString prev_tab;
if (tab) { if (tab) {
if (tab->currentIndex() >= 0) if (tab->currentIndex() >= 0) prev_tab = tab->tabText(tab->currentIndex());
prev_tab = tab->tabText(tab->currentIndex());
tab->deleteLater(); tab->deleteLater();
} }
clear(); clear();
@@ -152,7 +143,8 @@ void Ribbon::init() {
#else #else
tl->setContentsMargins(2, 0, 2, 2); tl->setContentsMargins(2, 0, 2, 2);
#endif #endif
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel); g = new QFrame();
g->setFrameShape(QFrame::StyledPanel);
l = new QBoxLayout(QBoxLayout::LeftToRight); l = new QBoxLayout(QBoxLayout::LeftToRight);
g->setLayout(l); g->setLayout(l);
l->setSpacing(2); l->setSpacing(2);
@@ -161,7 +153,8 @@ void Ribbon::init() {
if (j->isSeparator()) { if (j->isSeparator()) {
if (l->isEmpty()) continue; if (l->isEmpty()) continue;
tl->addWidget(g); tl->addWidget(g);
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel); g = new QFrame();
g->setFrameShape(QFrame::StyledPanel);
l = new QBoxLayout(QBoxLayout::LeftToRight); l = new QBoxLayout(QBoxLayout::LeftToRight);
l->setSpacing(2); l->setSpacing(2);
l->setContentsMargins(2, 2, 2, 2); l->setContentsMargins(2, 2, 2, 2);
@@ -208,8 +201,7 @@ void Ribbon::init() {
tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed)); tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
// sa->widget()->setLayout(tl); // sa->widget()->setLayout(tl);
tab->widget(tab->count() - 1)->setLayout(tl); tab->widget(tab->count() - 1)->setLayout(tl);
if (i->text() == prev_tab) if (i->text() == prev_tab) tab->setCurrentIndex(tab->count() - 1);
tab->setCurrentIndex(tab->count() - 1);
} }
setFloatable(false); setFloatable(false);
setMovable(false); setMovable(false);

View File

@@ -20,23 +20,24 @@
#ifndef RIBBON_H #ifndef RIBBON_H
#define RIBBON_H #define RIBBON_H
#include <QMainWindow>
#include <QActionGroup>
#include <QWidgetAction>
#include <QMenuBar>
#include <QTabWidget>
#include <QGroupBox>
#include <QDockWidget>
#include <QToolBar>
#include <QToolButton>
#include <QScrollArea>
#include "etabwidget.h" #include "etabwidget.h"
#include "qad_application_export.h" #include "qad_application_export.h"
#include <QActionGroup>
#include <QDockWidget>
#include <QGroupBox>
#include <QMainWindow>
#include <QMenuBar>
#include <QScrollArea>
#include <QTabWidget>
#include <QToolBar>
#include <QToolButton>
#include <QWidgetAction>
class QAD_APPLICATION_EXPORT Ribbon: public QToolBar
{ class QAD_APPLICATION_EXPORT Ribbon: public QToolBar {
Q_OBJECT Q_OBJECT
public: public:
explicit Ribbon(QMainWindow * parent = 0); explicit Ribbon(QMainWindow * parent = 0);
~Ribbon(); ~Ribbon();
@@ -45,10 +46,16 @@ public:
void retranslate(); void retranslate();
void setIconSize(const QSize & size); void setIconSize(const QSize & size);
void setTabIconSize(const QSize & size); void setTabIconSize(const QSize & size);
void setButtonStyle(const Qt::ToolButtonStyle & style) {foreach (QToolButton * i, buttons) i->setToolButtonStyle(style);} void setButtonStyle(const Qt::ToolButtonStyle & style) {
foreach(QToolButton * i, buttons)
i->setToolButtonStyle(style);
}
void setAutoSwitchEnabled(bool yes) { delay_e = yes; } void setAutoSwitchEnabled(bool yes) { delay_e = yes; }
void setAutoSwitchDelay(float delay_s) { delay = delay_s * 1000; } void setAutoSwitchDelay(float delay_s) { delay = delay_s * 1000; }
void setCurrentTab(int tab_) {if (tab_ < 0 || tab_ >= tab->count()) return; tab->setCurrentIndex(tab_);} void setCurrentTab(int tab_) {
if (tab_ < 0 || tab_ >= tab->count()) return;
tab->setCurrentIndex(tab_);
}
int currentTab() const { return tab->currentIndex(); } int currentTab() const { return tab->currentIndex(); }
QTabWidget * tabWidget() const { return tab; } QTabWidget * tabWidget() const { return tab; }
@@ -69,7 +76,12 @@ private:
QMainWindow * parent; QMainWindow * parent;
private slots: private slots:
void tabHovered(int tab) {if (!delay_e) return; hovers.clear(); hovered = tab; hovers.insert(startTimer(delay), tab);} void tabHovered(int tab) {
if (!delay_e) return;
hovers.clear();
hovered = tab;
hovers.insert(startTimer(delay), tab);
}
public slots: public slots:
void setVisible(bool yes); void setVisible(bool yes);
@@ -79,7 +91,6 @@ public slots:
signals: signals:
void currentTabChanged(int); void currentTabChanged(int);
}; };
#endif // RIBBON_H #endif // RIBBON_H

View File

@@ -1,8 +1,10 @@
#include "alignedtextitem.h" #include "alignedtextitem.h"
#include "blockbase.h" #include "blockbase.h"
#include <QApplication> #include <QApplication>
#include <QPainter>
#include <QDebug> #include <QDebug>
#include <QPainter>
AlignedTextItem::AlignedTextItem(QGraphicsItem * parent): QGraphicsItem(parent), text_(this) { AlignedTextItem::AlignedTextItem(QGraphicsItem * parent): QGraphicsItem(parent), text_(this) {

View File

@@ -20,11 +20,12 @@
#ifndef ALIGNEDTEXTITEM_H #ifndef ALIGNEDTEXTITEM_H
#define ALIGNEDTEXTITEM_H #define ALIGNEDTEXTITEM_H
#include <QGraphicsSimpleTextItem> #include "qad_blockview_export.h"
#include <QPen>
#include <QBrush> #include <QBrush>
#include <QFont> #include <QFont>
#include "qad_blockview_export.h" #include <QGraphicsSimpleTextItem>
#include <QPen>
class QAD_BLOCKVIEW_EXPORT AlignedTextItem: public QGraphicsItem { class QAD_BLOCKVIEW_EXPORT AlignedTextItem: public QGraphicsItem {
@@ -32,11 +33,23 @@ public:
AlignedTextItem(QGraphicsItem * parent = 0); AlignedTextItem(QGraphicsItem * parent = 0);
AlignedTextItem(const QString & text, QGraphicsItem * parent = 0); AlignedTextItem(const QString & text, QGraphicsItem * parent = 0);
void setText(const QString & t) {text_.setText(t); _move();} void setText(const QString & t) {
text_.setText(t);
_move();
}
void setFont(const QFont & f); void setFont(const QFont & f);
void setPen(const QPen & p) {text_.setPen(p); _move();} void setPen(const QPen & p) {
void setBrush(const QBrush & b) {text_.setBrush(b); _move();} text_.setPen(p);
void setAlignment(Qt::Alignment align) {align_ = align; _move();} _move();
}
void setBrush(const QBrush & b) {
text_.setBrush(b);
_move();
}
void setAlignment(Qt::Alignment align) {
align_ = align;
_move();
}
QString text() const { return text_.text(); } QString text() const { return text_.text(); }
QFont font() const { return font_; } QFont font() const { return font_; }
@@ -46,7 +59,9 @@ public:
void clear() { setText(QString()); } void clear() { setText(QString()); }
enum {Type = UserType + 0x100}; enum {
Type = UserType + 0x100
};
static QFont sceneFont(const QFont & f); static QFont sceneFont(const QFont & f);
@@ -61,7 +76,6 @@ protected:
QGraphicsSimpleTextItem text_; QGraphicsSimpleTextItem text_;
Qt::Alignment align_; Qt::Alignment align_;
QFont font_; QFont font_;
}; };

View File

@@ -1,4 +1,5 @@
#include "blockbase.h" #include "blockbase.h"
#include "alignedtextitem.h" #include "alignedtextitem.h"
#include "qvariantedit.h" #include "qvariantedit.h"
@@ -39,7 +40,8 @@ QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item) { QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item) {
int type_; s >> type_; int type_;
s >> type_;
if (type_ < 0) { if (type_ < 0) {
item = 0; item = 0;
return s; return s;
@@ -54,56 +56,164 @@ QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item) {
item = 0; item = 0;
switch (type_) { switch (type_) {
case 0: case 0:
nrect = new QGraphicsRectItem(); item = nrect; nrect = new QGraphicsRectItem();
{QPen _v; s >> _v; nrect->setPen(_v);} item = nrect;
{QBrush _v; s >> _v; nrect->setBrush(_v);} {
{QRectF _v; s >> _v; nrect->setRect(_v);} QPen _v;
s >> _v;
nrect->setPen(_v);
}
{
QBrush _v;
s >> _v;
nrect->setBrush(_v);
}
{
QRectF _v;
s >> _v;
nrect->setRect(_v);
}
break; break;
case 1: case 1:
nell = new QGraphicsEllipseItem(); item = nell; nell = new QGraphicsEllipseItem();
{QPen _v; s >> _v; nell->setPen(_v);} item = nell;
{QBrush _v; s >> _v; nell->setBrush(_v);} {
{QRectF _v; s >> _v; nell->setRect(_v);} QPen _v;
s >> _v;
nell->setPen(_v);
}
{
QBrush _v;
s >> _v;
nell->setBrush(_v);
}
{
QRectF _v;
s >> _v;
nell->setRect(_v);
}
break; break;
case 2: case 2:
ntext = new QGraphicsSimpleTextItem(); item = ntext; ntext = new QGraphicsSimpleTextItem();
{QPen _v; s >> _v; ntext->setPen(_v);} item = ntext;
{QBrush _v; s >> _v; ntext->setBrush(_v);} {
{QFont _v; s >> _v; ntext->setFont(_v);} QPen _v;
{QString _v; s >> _v; ntext->setText(_v);} s >> _v;
ntext->setPen(_v);
}
{
QBrush _v;
s >> _v;
ntext->setBrush(_v);
}
{
QFont _v;
s >> _v;
ntext->setFont(_v);
}
{
QString _v;
s >> _v;
ntext->setText(_v);
}
break; break;
case 6: case 6:
natext = new AlignedTextItem(); item = natext; natext = new AlignedTextItem();
{QPen _v; s >> _v; natext->setPen(_v);} item = natext;
{QBrush _v; s >> _v; natext->setBrush(_v);} {
{QFont _v; s >> _v; natext->setFont(_v);} QPen _v;
{QString _v; s >> _v; natext->setText(_v);} s >> _v;
{int _v; s >> _v; natext->setAlignment((Qt::AlignmentFlag)_v);} natext->setPen(_v);
}
{
QBrush _v;
s >> _v;
natext->setBrush(_v);
}
{
QFont _v;
s >> _v;
natext->setFont(_v);
}
{
QString _v;
s >> _v;
natext->setText(_v);
}
{
int _v;
s >> _v;
natext->setAlignment((Qt::AlignmentFlag)_v);
}
break; break;
case 3: case 3:
nline = new QGraphicsLineItem(); item = nline; nline = new QGraphicsLineItem();
{QPen _v; s >> _v; nline->setPen(_v);} item = nline;
{QLineF _v; s >> _v; nline->setLine(_v);} {
QPen _v;
s >> _v;
nline->setPen(_v);
}
{
QLineF _v;
s >> _v;
nline->setLine(_v);
}
break; break;
case 4: case 4:
npath = new QGraphicsPathItem(); item = npath; npath = new QGraphicsPathItem();
{QPen _v; s >> _v; npath->setPen(_v);} item = npath;
{QPainterPath _v; s >> _v; npath->setPath(_v);} {
QPen _v;
s >> _v;
npath->setPen(_v);
}
{
QPainterPath _v;
s >> _v;
npath->setPath(_v);
}
break; break;
case 5: case 5:
npixmap = new QGraphicsPixmapItem(); item = npixmap; npixmap = new QGraphicsPixmapItem();
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);} item = npixmap;
{
QPixmap _v;
s >> _v;
npixmap->setPixmap(_v);
}
break; break;
case 7: case 7:
npixmap = new QGraphicsPixmapItem(); item = npixmap; npixmap = new QGraphicsPixmapItem();
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);} item = npixmap;
{QTransform _t; s >> _t; npixmap->setTransform(_t);} {
QPixmap _v;
s >> _v;
npixmap->setPixmap(_v);
}
{
QTransform _t;
s >> _t;
npixmap->setTransform(_t);
}
break; break;
} }
if (item) { if (item) {
{QPointF _v; s >> _v; item->setPos(_v);} {
{qreal _v; s >> _v; item->setRotation(_v);} QPointF _v;
{int _v; s >> _v; item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);} s >> _v;
item->setPos(_v);
}
{
qreal _v;
s >> _v;
item->setRotation(_v);
}
{
int _v;
s >> _v;
item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);
}
} }
return s; return s;
} }

View File

@@ -20,16 +20,17 @@
#ifndef BLOCKBASE_H #ifndef BLOCKBASE_H
#define BLOCKBASE_H #define BLOCKBASE_H
#include <QGraphicsView> #include "qad_blockview_export.h"
#include <QGraphicsScene> #include "qad_types.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QGraphicsEllipseItem> #include <QGraphicsScene>
#include <QGraphicsSceneHoverEvent> #include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QStack> #include <QStack>
#include "qad_types.h"
#include "qad_blockview_export.h"
static const int _blockitem_current_version_ = 1; static const int _blockitem_current_version_ = 1;
@@ -61,12 +62,11 @@ QAD_BLOCKVIEW_EXPORT QDataStream & operator <<(QDataStream & s, const QGraphicsI
QAD_BLOCKVIEW_EXPORT QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item); QAD_BLOCKVIEW_EXPORT QDataStream & operator>>(QDataStream & s, QGraphicsItem *& item);
class QAD_BLOCKVIEW_EXPORT BlockItemBase: public QObject class QAD_BLOCKVIEW_EXPORT BlockItemBase: public QObject {
{
Q_OBJECT Q_OBJECT
Q_ENUMS(Action) Q_ENUMS(Action)
public:
public:
enum Action { enum Action {
BlockAdd = 1, BlockAdd = 1,
BlockMove, BlockMove,
@@ -82,7 +82,6 @@ public:
BusSegmentRemove, BusSegmentRemove,
Paste Paste
}; };
}; };
#endif // BLOCKBASE_H #endif // BLOCKBASE_H

View File

@@ -1,12 +1,15 @@
#include "blockview.h" #include "blockview.h"
#include <QApplication> #include <QApplication>
BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() { BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() {
temp_ = temp; temp_ = temp;
_init(); _init();
if (!temp) setData(bvidType, bvitBus); if (!temp)
else hide(); setData(bvidType, bvitBus);
else
hide();
} }
@@ -33,21 +36,29 @@ void BlockBusItem::_init() {
setZValue(1.); setZValue(1.);
setBusType(-1); setBusType(-1);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
ph.setColor(Qt::blue); ph.setJoinStyle(Qt::MiterJoin); ph.setColor(Qt::blue);
bh.setColor(Qt::blue); bh.setStyle(Qt::SolidPattern); ph.setJoinStyle(Qt::MiterJoin);
pu = pa = pr = ph; bu = ba = br = bh; bh.setColor(Qt::blue);
bh.setStyle(Qt::SolidPattern);
pu = pa = pr = ph;
bu = ba = br = bh;
grid_step = 10.; grid_step = 10.;
pu.setWidth(1); pu.setWidth(1);
pu.setColor(Qt::black); bu.setColor(Qt::black); pu.setColor(Qt::black);
pa.setColor(Qt::darkGreen); ba.setColor(Qt::darkGreen); bu.setColor(Qt::black);
pr.setColor(Qt::darkRed); br.setColor(Qt::darkRed); pa.setColor(Qt::darkGreen);
pn.setColor(Qt::gray); pn.setStyle(Qt::DashLine); ba.setColor(Qt::darkGreen);
pr.setColor(Qt::darkRed);
br.setColor(Qt::darkRed);
pn.setColor(Qt::gray);
pn.setStyle(Qt::DashLine);
if (temp_) { if (temp_) {
pu.setStyle(Qt::DashLine); pu.setStyle(Qt::DashLine);
pu.setColor(Qt::darkGray); pu.setColor(Qt::darkGray);
bu.setColor(Qt::darkGray); bu.setColor(Qt::darkGray);
} }
setPen(pu); setBrush(bu); setPen(pu);
setBrush(bu);
square_node = false; square_node = false;
max_ep = 0; max_ep = 0;
selPoint = selSegment = state_ = -1; selPoint = selSegment = state_ = -1;
@@ -122,32 +133,33 @@ void BlockBusItem::removePoint(int index) {
if (index < 0 || index > pol.size() - 1) return; if (index < 0 || index > pol.size() - 1) return;
int sc = 0, fs = -1, ss = -1; int sc = 0, fs = -1, ss = -1;
for (int i = 0; i < segments.size(); ++i) for (int i = 0; i < segments.size(); ++i)
if (segments[i].first == index || if (segments[i].first == index || segments[i].second == index) {
segments[i].second == index) {
sc++; sc++;
if (fs < 0) fs = i; if (fs < 0)
else ss = i; fs = i;
else
ss = i;
} }
int ei(0); int ei(0);
switch (sc) { switch (sc) {
case 1: case 1: segments.removeAt(fs); break;
segments.removeAt(fs);
break;
case 2: case 2:
if (segments[ss].first == index) ei = segments[ss].second; if (segments[ss].first == index)
else ei = segments[ss].first; ei = segments[ss].second;
if (segments[fs].first == index) segments[fs].first = ei; else
else segments[fs].second = ei; ei = segments[ss].first;
if (segments[fs].first == index)
segments[fs].first = ei;
else
segments[fs].second = ei;
segments.removeAt(ss); segments.removeAt(ss);
break; break;
default: return; default: return;
} }
pol.remove(index); pol.remove(index);
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (segments[i].first >= index) if (segments[i].first >= index) segments[i].first--;
segments[i].first--; if (segments[i].second >= index) segments[i].second--;
if (segments[i].second >= index)
segments[i].second--;
} }
selPoint = -1; selPoint = -1;
checkDelete(); checkDelete();
@@ -162,25 +174,19 @@ void BlockBusItem::removeSegment(int index) {
if (pif > pis) qSwap<int>(pif, pis); if (pif > pis) qSwap<int>(pif, pis);
int scf = 0, scs = 0; int scf = 0, scs = 0;
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (segments[i].first == pif || if (segments[i].first == pif || segments[i].second == pif) scf++;
segments[i].second == pif) if (segments[i].first == pis || segments[i].second == pis) scs++;
scf++;
if (segments[i].first == pis ||
segments[i].second == pis)
scs++;
} }
if (scs <= 2) removePoint(pis); if (scs <= 2) removePoint(pis);
if (scf <= 2) removePoint(pif); if (scf <= 2) removePoint(pif);
if (scs <= 2 || scf <= 2) selSegment = -1; if (scs <= 2 || scf <= 2) selSegment = -1;
if (scene() != 0) scene()->update(); if (scene() != 0) scene()->update();
} }
void BlockBusItem::appendPoint(const QPointF & p) { void BlockBusItem::appendPoint(const QPointF & p) {
pol << p; pol << p;
if (pol.size() > 1) if (pol.size() > 1) segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
updateGeometry(); updateGeometry();
} }
@@ -266,17 +272,23 @@ void BlockBusItem::simplify(bool full) {
int s0 = segs[0], s1 = segs[1]; int s0 = segs[0], s1 = segs[1];
QPointF cp = pol[p], sp[2]; QPointF cp = pol[p], sp[2];
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
if (segments[segs[i]].first == p) sp[i] = pol[segments[segs[i]].second]; if (segments[segs[i]].first == p)
else sp[i] = pol[segments[segs[i]].first]; sp[i] = pol[segments[segs[i]].second];
else
sp[i] = pol[segments[segs[i]].first];
} }
QLineF l0(sp[0], cp), l1(cp, sp[1]); QLineF l0(sp[0], cp), l1(cp, sp[1]);
if (qAbs(l0.angle() - l1.angle()) > 0.1) continue; if (qAbs(l0.angle() - l1.angle()) > 0.1) continue;
if (segments[s0].first == p) { if (segments[s0].first == p) {
if (segments[s1].first == p) segments[s0].first = segments[s1].second; if (segments[s1].first == p)
else segments[s0].first = segments[s1].first; segments[s0].first = segments[s1].second;
else
segments[s0].first = segments[s1].first;
} else { } else {
if (segments[s1].first == p) segments[s0].second = segments[s1].second; if (segments[s1].first == p)
else segments[s0].second = segments[s1].first; segments[s0].second = segments[s1].second;
else
segments[s0].second = segments[s1].first;
} }
segments.removeAt(s1); segments.removeAt(s1);
pol.remove(p); pol.remove(p);
@@ -292,8 +304,7 @@ void BlockBusItem::simplify(bool full) {
} }
void BlockBusItem::adjustLine() { void BlockBusItem::adjustLine() {}
}
int BlockBusItem::endpointCount() const { int BlockBusItem::endpointCount() const {
@@ -350,9 +361,8 @@ void BlockBusItem::clearBusState() {
QByteArray BlockBusItem::save() const { QByteArray BlockBusItem::save() const {
ChunkStream cs; ChunkStream cs;
cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen()) cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen()) << cs.chunk(5, brush())
<< cs.chunk(5, brush()) << cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props) << cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props) << cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale);
<< cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale);
return cs.data(); return cs.data();
} }
@@ -441,8 +451,7 @@ QVector<int> BlockBusItem::endpoints() const {
counts[segments[i].second]++; counts[segments[i].second]++;
} }
for (int i = 0; i < counts.size(); ++i) { for (int i = 0; i < counts.size(); ++i) {
if (counts[i] == 1) if (counts[i] == 1) ret << i;
ret << i;
} }
return ret; return ret;
} }
@@ -472,7 +481,6 @@ QVector<int> BlockBusItem::endpointLine(int ep, double angle) const {
np = neighborSegmentPoint(np, &seg); np = neighborSegmentPoint(np, &seg);
} }
return ret; return ret;
} }
@@ -492,8 +500,14 @@ int BlockBusItem::neighborSegmentPoint(int point, int * seg) const {
if (point < 0 || !seg) return -1; if (point < 0 || !seg) return -1;
for (int i = 0; i < segments.size(); ++i) { for (int i = 0; i < segments.size(); ++i) {
if (i == *seg) continue; if (i == *seg) continue;
if (segments[i].first == point) {*seg = i; return segments[i].second;} if (segments[i].first == point) {
if (segments[i].second == point) {*seg = i; return segments[i].first ;} *seg = i;
return segments[i].second;
}
if (segments[i].second == point) {
*seg = i;
return segments[i].first;
}
} }
return -1; return -1;
} }
@@ -520,8 +534,8 @@ void BlockBusItem::testPoint(QPointF pos, int * sel_point, int * sel_segment, bo
void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n") tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n") +
+ tr("Add point: Ctrl + LeftClick\n" tr("Add point: Ctrl + LeftClick\n"
"Remove point\\segment: Ctrl + RightClick\n" "Remove point\\segment: Ctrl + RightClick\n"
"Remove connection: Shift + RightClick\n" "Remove connection: Shift + RightClick\n"
"Move point\\segment: Shift + LeftPress\n" "Move point\\segment: Shift + LeftPress\n"
@@ -546,7 +560,8 @@ void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
setPointSize(0); setPointSize(0);
anim_point_size.start(); anim_point_size.start();
} }
} else setPointSize(anim_point_size.endValue().toDouble()); } else
setPointSize(anim_point_size.endValue().toDouble());
} }
if (selPoint >= 0 || selSegment >= 0) { if (selPoint >= 0 || selSegment >= 0) {
@@ -585,14 +600,13 @@ void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
if (temp_) return; if (temp_) return;
selPoint = selSegment = -1; selPoint = selSegment = -1;
setPen(pu); setBrush(bu); setPen(pu);
setBrush(bu);
setToolTip(QString()); setToolTip(QString());
anim_point_size.stop(); anim_point_size.stop();
BlockView * bv = 0; BlockView * bv = 0;
if (!scene()->views().isEmpty()) if (!scene()->views().isEmpty()) bv = qobject_cast<BlockView *>(scene()->views().back());
bv = qobject_cast<BlockView*>(scene()->views().back()); if (bv && (QApplication::mouseButtons() == 0)) bv->cur_bus = 0;
if (bv && (QApplication::mouseButtons() == 0))
bv->cur_bus = 0;
update(); update();
QGraphicsObject::hoverLeaveEvent(e); QGraphicsObject::hoverLeaveEvent(e);
} }
@@ -601,15 +615,13 @@ void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
if (temp_) return; if (temp_) return;
lp = quantize(e->scenePos(), grid_step); lp = quantize(e->scenePos(), grid_step);
if (e->button() != Qt::RightButton) if (e->button() != Qt::RightButton) bpol = pol;
bpol = pol;
BlockView * bv = 0; BlockView * bv = 0;
if (!scene()->views().isEmpty()) { if (!scene()->views().isEmpty()) {
bv = qobject_cast<BlockView *>(scene()->views().back()); bv = qobject_cast<BlockView *>(scene()->views().back());
} }
if (bv) { if (bv) {
if (selPoint >= 0 || selSegment >= 0) if (selPoint >= 0 || selSegment >= 0) bv->cur_bus = this;
bv->cur_bus = this;
} }
if (new_segment) { if (new_segment) {
qobject_cast<BlockView *>(scene()->views().back())->newBranchCancel(); qobject_cast<BlockView *>(scene()->views().back())->newBranchCancel();
@@ -637,7 +649,8 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
} }
if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) { if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) {
if (selSegment >= 0) if (selSegment >= 0)
press_pos = quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], e->scenePos()), grid_step); press_pos =
quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], e->scenePos()), grid_step);
else { else {
if (selPoint >= 0) if (selPoint >= 0)
press_pos = pol[selPoint]; press_pos = pol[selPoint];
@@ -646,8 +659,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
} }
if (max_ep >= 2) { if (max_ep >= 2) {
if (endpointCount() >= max_ep) if (endpointCount() >= max_ep)
if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) return;
return;
} }
qobject_cast<BlockView *>(scene()->views().back())->newBranch(this); qobject_cast<BlockView *>(scene()->views().back())->newBranch(this);
new_segment = true; new_segment = true;
@@ -673,8 +685,7 @@ void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
} }
} }
if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) { if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) {
if (addPoint(e->scenePos()) >= 0) if (addPoint(e->scenePos()) >= 0) emitAction(BlockItemBase::BusPointAdd);
emitAction(BlockItemBase::BusPointAdd);
return; return;
} }
} }
@@ -707,8 +718,7 @@ void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
} else { } else {
if (e->buttons().testFlag(Qt::LeftButton)) { if (e->buttons().testFlag(Qt::LeftButton)) {
lm_point = selPoint >= 0; lm_point = selPoint >= 0;
if (selPoint >= 0 && selPoint <= pol.size() - 1) if (selPoint >= 0 && selPoint <= pol.size() - 1) pol[selPoint] += lp;
pol[selPoint] += lp;
if (selSegment >= 0 && selSegment <= segments.size() - 1) { if (selSegment >= 0 && selSegment <= segments.size() - 1) {
pol[segments[selSegment].first] += lp; pol[segments[selSegment].first] += lp;
pol[segments[selSegment].second] += lp; pol[segments[selSegment].second] += lp;

View File

@@ -24,11 +24,14 @@
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
class QAD_BLOCKVIEW_EXPORT BlockBusItem: public QGraphicsObject, public PropertyStorage { class QAD_BLOCKVIEW_EXPORT BlockBusItem
: public QGraphicsObject
, public PropertyStorage {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QGraphicsItem) Q_INTERFACES(QGraphicsItem)
Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false)
friend class BlockView; friend class BlockView;
public: public:
BlockBusItem(bool temp = false); BlockBusItem(bool temp = false);
BlockBusItem(const BlockBusItem & other); BlockBusItem(const BlockBusItem & other);
@@ -47,9 +50,19 @@ public:
void setGridStep(double gs) { grid_step = gs; } void setGridStep(double gs) { grid_step = gs; }
void setEndpointsNumber(int num) { max_ep = num; } void setEndpointsNumber(int num) { max_ep = num; }
void setImages(const QImage & bus, const QImage & end = QImage()) {im_bus = bus; im_end = end; update();} void setImages(const QImage & bus, const QImage & end = QImage()) {
void setBusImageScale(double s) {im_bus_scale = s; update();} im_bus = bus;
void setEndpointImageScale(double s) {im_end_scale = s; update();} im_end = end;
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 setBusType(int type_) { bus_type = type_; }
void setBusName(const QString & name) { bus_name = name; } void setBusName(const QString & name) { bus_name = name; }
int busType() const { return bus_type; } int busType() const { return bus_type; }
@@ -60,9 +73,15 @@ public:
void appendPoint(qreal x, qreal y); void appendPoint(qreal x, qreal y);
void movePolyline(const QPointF & dp); void movePolyline(const QPointF & dp);
void clear(); void clear();
void setPen(const QPen & p) {p_ = p; update();} void setPen(const QPen & p) {
p_ = p;
update();
}
QPen pen() const { return p_; } QPen pen() const { return p_; }
void setBrush(const QBrush & b) {b_ = b; update();} void setBrush(const QBrush & b) {
b_ = b;
update();
}
QBrush brush() const { return b_; } QBrush brush() const { return b_; }
double width() const { return pen_width; } double width() const { return pen_width; }
void setWidth(const double & w); void setWidth(const double & w);
@@ -90,7 +109,9 @@ public:
void saveState(); void saveState();
void restoreState(); void restoreState();
enum {Type = UserType + 2}; enum {
Type = UserType + 2
};
protected: protected:
void _init(); void _init();
@@ -143,9 +164,13 @@ private:
}; };
inline QDataStream & operator <<(QDataStream & s, const BlockBusItem * b) {s << b->save(); return s;} inline QDataStream & operator<<(QDataStream & s, const BlockBusItem * b) {
s << b->save();
return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockBusItem *& b) { inline QDataStream & operator>>(QDataStream & s, BlockBusItem *& b) {
QByteArray ba; s >> ba; QByteArray ba;
s >> ba;
b = new BlockBusItem(); b = new BlockBusItem();
b->load(ba); b->load(ba);
return s; return s;

View File

@@ -1,12 +1,14 @@
#include "blockeditor.h" #include "blockeditor.h"
#include "ui_blockeditor.h"
#include "drawtools.h"
#include "blockview.h" #include "blockview.h"
#include <QToolBar> #include "drawtools.h"
#include "ui_blockeditor.h"
#include <QComboBox> #include <QComboBox>
#include <QFileDialog>
#include <QFile> #include <QFile>
#include <QFileDialog>
#include <QTimer> #include <QTimer>
#include <QToolBar>
BlockEditor::BlockEditor(QWidget * parent): QWidget(parent), ui(new Ui::BlockEditor) { BlockEditor::BlockEditor(QWidget * parent): QWidget(parent), ui(new Ui::BlockEditor) {
@@ -21,7 +23,9 @@ BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEdi
ui->blockView->viewport()->installEventFilter(this); ui->blockView->viewport()->installEventFilter(this);
DrawTools * drawtools = new DrawTools(ui->blockView); DrawTools * drawtools = new DrawTools(ui->blockView);
connect(drawtools, SIGNAL(itemCreated(QGraphicsItem *)), this, SLOT(addItem(QGraphicsItem *))); connect(drawtools, SIGNAL(itemCreated(QGraphicsItem *)), this, SLOT(addItem(QGraphicsItem *)));
drawtools->textEditCombo()->addItems(QStringList() << "%name" << "%value" << "%id"); drawtools->textEditCombo()->addItems(QStringList() << "%name"
<< "%value"
<< "%id");
ui->layoutProperties->addWidget(drawtools->propertyWidget()); ui->layoutProperties->addWidget(drawtools->propertyWidget());
ui->actionRemove_items->setEnabled(false); ui->actionRemove_items->setEnabled(false);
ui->button_color->setColor(Qt::lightGray); ui->button_color->setColor(Qt::lightGray);
@@ -138,9 +142,13 @@ void BlockEditor::updateBlock() {
void BlockEditor::treePinsClear() { void BlockEditor::treePinsClear() {
ui->treePins->blockSignals(true); ui->treePins->blockSignals(true);
ui->treePins->clear(); ui->treePins->clear();
QFont bf(font()); bf.setBold(true); QFont bf(font());
bf.setBold(true);
QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom; QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom;
QStringList an = QStringList() << "Left" << "Right" << "Top" << "Bottom"; QStringList an = QStringList() << "Left"
<< "Right"
<< "Top"
<< "Bottom";
pin_tli.clear(); pin_tli.clear();
for (int i = 0; i < al.size(); ++i) { for (int i = 0; i < al.size(); ++i) {
QTreeWidgetItem * ti = new QTreeWidgetItem(); QTreeWidgetItem * ti = new QTreeWidgetItem();
@@ -176,9 +184,7 @@ bool BlockEditor::eventFilter(QObject *o, QEvent *e) {
void BlockEditor::changeEvent(QEvent * e) { void BlockEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this);
break;
default: break; default: break;
} }
} }
@@ -233,10 +239,10 @@ void BlockEditor::on_buttonClear_clicked() {
} }
void BlockEditor::on_buttonPinAdd_clicked() { void BlockEditor::on_buttonPinAdd_clicked() {
ui->treePins->blockSignals(true); ui->treePins->blockSignals(true);
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << "" << "0"); QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << ""
<< "0");
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled); ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
ti->setData(0, Qt::UserRole, qulonglong(block.addPin(Qt::AlignLeft, ti->text(1).toInt(), ti->text(0)))); ti->setData(0, Qt::UserRole, qulonglong(block.addPin(Qt::AlignLeft, ti->text(1).toInt(), ti->text(0))));
ti->setData(0, Qt::UserRole + 1, (int)Qt::AlignLeft); ti->setData(0, Qt::UserRole + 1, (int)Qt::AlignLeft);
@@ -297,7 +303,6 @@ void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
} }
void BlockEditor::arrangePins() { void BlockEditor::arrangePins() {
QVector<BlockItemPin *> pins = block.pins(); QVector<BlockItemPin *> pins = block.pins();
QList<QTreeWidgetItem *> tli = pin_tli.values(); QList<QTreeWidgetItem *> tli = pin_tli.values();
@@ -326,10 +331,14 @@ void BlockEditor::arrangePins() {
QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const { QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QComboBox * combo = new QComboBox(parent); QComboBox * combo = new QComboBox(parent);
int cv = index.data().toInt(); int cv = index.data().toInt();
combo->addItem("Left", int(Qt::AlignLeft)); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0); combo->addItem("Left", int(Qt::AlignLeft));
combo->addItem("Right", int(Qt::AlignRight)); if (cv == Qt::AlignRight) combo->setCurrentIndex(1); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0);
combo->addItem("Top", int(Qt::AlignTop)); if (cv == Qt::AlignTop) combo->setCurrentIndex(2); combo->addItem("Right", int(Qt::AlignRight));
combo->addItem("Bottom", int(Qt::AlignBottom)); if (cv == Qt::AlignBottom) combo->setCurrentIndex(3); if (cv == Qt::AlignRight) combo->setCurrentIndex(1);
combo->addItem("Top", int(Qt::AlignTop));
if (cv == Qt::AlignTop) combo->setCurrentIndex(2);
combo->addItem("Bottom", int(Qt::AlignBottom));
if (cv == Qt::AlignBottom) combo->setCurrentIndex(3);
combo->setGeometry(option.rect); combo->setGeometry(option.rect);
return combo; return combo;
} }
@@ -376,4 +385,3 @@ QString PinBusDelegate::displayText(const QVariant & value, const QLocale & loca
void PinBusDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const { void PinBusDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
model->setData(index, ((QSpinBox *)editor)->value()); model->setData(index, ((QSpinBox *)editor)->value());
} }

View File

@@ -20,23 +20,24 @@
#ifndef BLOCKEDITOR_H #ifndef BLOCKEDITOR_H
#define BLOCKEDITOR_H #define BLOCKEDITOR_H
#include <QWidget>
#include <QTreeWidgetItem>
#include <QStyledItemDelegate>
#include "blockitem.h" #include "blockitem.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QStyledItemDelegate>
#include <QTreeWidgetItem>
#include <QWidget>
namespace Ui { namespace Ui {
class BlockEditor; class BlockEditor;
} }
class QAD_BLOCKVIEW_EXPORT BlockEditor : public QWidget class QAD_BLOCKVIEW_EXPORT BlockEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool editorMode READ editorMode WRITE setEditorMode) Q_PROPERTY(bool editorMode READ editorMode WRITE setEditorMode)
Q_PROPERTY(bool pinsEditable READ pinsEditable WRITE setPinsEditable) Q_PROPERTY(bool pinsEditable READ pinsEditable WRITE setPinsEditable)
public: public:
explicit BlockEditor(QWidget * parent = 0); explicit BlockEditor(QWidget * parent = 0);
~BlockEditor(); ~BlockEditor();
@@ -83,9 +84,9 @@ private:
}; };
class QAD_BLOCKVIEW_EXPORT PinAlignDelegate: public QStyledItemDelegate { class QAD_BLOCKVIEW_EXPORT PinAlignDelegate: public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {} PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const; QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
@@ -97,12 +98,14 @@ public:
class QAD_BLOCKVIEW_EXPORT PinBusDelegate: public QStyledItemDelegate { class QAD_BLOCKVIEW_EXPORT PinBusDelegate: public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {} PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const; QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QString displayText(const QVariant & value, const QLocale & locale) const; QString displayText(const QVariant & value, const QLocale & locale) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { return QSize(60, 26); } QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { return QSize(60, 26); }
private: private:
typedef QPair<int, QString> ISPair; typedef QPair<int, QString> ISPair;
QVector<ISPair> buses; QVector<ISPair> buses;

View File

@@ -1,11 +1,11 @@
#include "blockview.h" #include "blockview.h"
#include <QApplication> #include <QApplication>
#define BLOCKITEM_DEFAULT_PIN_MARGIN 20 #define BLOCKITEM_DEFAULT_PIN_MARGIN 20
BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(), BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(), g_main(this), g_selection(this) {
g_main(this), g_selection(this) {
setData(bvidType, bvitBlock); setData(bvidType, bvitBlock);
setZValue(2.); setZValue(2.);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
@@ -58,11 +58,9 @@ void BlockItem::_resize(QSizeF s) {
void BlockItem::_moveToTop(bool only_decors) { void BlockItem::_moveToTop(bool only_decors) {
qreal dy = -g_main.rect().center().y() + 10; qreal dy = -g_main.rect().center().y() + 10;
if (!only_decors) if (!only_decors) moveBy(0., dy);
moveBy(0., dy);
foreach(QGraphicsItem * d, decors_) foreach(QGraphicsItem * d, decors_)
d->moveBy(0., -dy); d->moveBy(0., -dy);
} }
@@ -70,8 +68,7 @@ BlockItemPin * BlockItem::addPin(BlockItemPin * pin, bool update_) {
pin->setParentItem(this); pin->setParentItem(this);
if (!pins_[pin->alignment()].contains(pin)) pins_[pin->alignment()] << pin; if (!pins_[pin->alignment()].contains(pin)) pins_[pin->alignment()] << pin;
pin->parent_ = this; pin->parent_ = this;
if (update_) if (update_) arrangePins();
arrangePins();
return pin; return pin;
} }
@@ -80,8 +77,7 @@ BlockItemPin * BlockItem::addPin(Qt::Alignment align, int bus_type, const QStrin
BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this); BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this);
pin->parent_ = this; pin->parent_ = this;
pins_[pin->alignment()] << pin; pins_[pin->alignment()] << pin;
if (update_) if (update_) arrangePins();
arrangePins();
return pin; return pin;
} }
@@ -92,8 +88,7 @@ void BlockItem::removePin(BlockItemPin * pin) {
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
QVector<BlockItemPin *> & pv(it.value()); QVector<BlockItemPin *> & pv(it.value());
if (pv.contains(pin)) if (pv.contains(pin)) pv.remove(it.value().indexOf(pin));
pv.remove(it.value().indexOf(pin));
} }
delete pin; delete pin;
arrangePins(); arrangePins();
@@ -105,7 +100,8 @@ void BlockItem::addDecor(QGraphicsItem * item) {
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item)) if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item))
qgraphicsitem_cast<QGraphicsPixmapItem *>(item)->setTransformationMode(Qt::SmoothTransformation); qgraphicsitem_cast<QGraphicsPixmapItem *>(item)->setTransformationMode(Qt::SmoothTransformation);
if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)) if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item))
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->setData(bvidDecorText, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->text()); qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)->setData(bvidDecorText,
qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)->text());
if (qgraphicsitem_cast<AlignedTextItem *>(item)) if (qgraphicsitem_cast<AlignedTextItem *>(item))
qgraphicsitem_cast<AlignedTextItem *>(item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(item)->text()); qgraphicsitem_cast<AlignedTextItem *>(item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(item)->text());
item->setData(bvidMoveParent, true); item->setData(bvidMoveParent, true);
@@ -120,7 +116,8 @@ void BlockItem::addDecor(QGraphicsItem & item) {
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(&item)) if (qgraphicsitem_cast<QGraphicsPixmapItem *>(&item))
qgraphicsitem_cast<QGraphicsPixmapItem *>(&item)->setTransformationMode(Qt::SmoothTransformation); qgraphicsitem_cast<QGraphicsPixmapItem *>(&item)->setTransformationMode(Qt::SmoothTransformation);
if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)) if (qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item))
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->setData(bvidDecorText, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->text()); qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)->setData(bvidDecorText,
qgraphicsitem_cast<QGraphicsSimpleTextItem *>(&item)->text());
if (qgraphicsitem_cast<AlignedTextItem *>(&item)) if (qgraphicsitem_cast<AlignedTextItem *>(&item))
qgraphicsitem_cast<AlignedTextItem *>(&item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(&item)->text()); qgraphicsitem_cast<AlignedTextItem *>(&item)->setData(bvidDecorText, qgraphicsitem_cast<AlignedTextItem *>(&item)->text());
item.setData(bvidMoveParent, true); item.setData(bvidMoveParent, true);
@@ -130,8 +127,7 @@ void BlockItem::addDecor(QGraphicsItem & item) {
void BlockItem::removeDecor(QGraphicsItem * item) { void BlockItem::removeDecor(QGraphicsItem * item) {
if (scene() && item) if (scene() && item) scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
decors_.removeAll(item); decors_.removeAll(item);
delete item; delete item;
} }
@@ -204,18 +200,19 @@ void BlockItem::loadModel(const QByteArray & data) {
case 4: setColor(cs.getData<QColor>()); break; case 4: setColor(cs.getData<QColor>()); break;
case 5: case 5:
cs.get(tp); cs.get(tp);
foreach (BlockItemPin * p, tp) addPin(p); foreach(BlockItemPin * p, tp)
addPin(p);
break; break;
case 6: case 6:
cs.get(dl); cs.get(dl);
foreach (QGraphicsItem * d, dl) addDecor(d); foreach(QGraphicsItem * d, dl)
addDecor(d);
break; break;
case 7: setPinsMargin(cs.getData<int>()); break; case 7: setPinsMargin(cs.getData<int>()); break;
case 0xFF: cs.get(version); break; case 0xFF: cs.get(version); break;
} }
} }
if (version <= 0) if (version <= 0) _moveToTop(true);
_moveToTop(true);
} }
@@ -227,7 +224,8 @@ QByteArray BlockItem::save() const {
pp[p->text()] = p->properties(); pp[p->text()] = p->properties();
} }
cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, props) << cs.chunk(5, pp) << cs.chunk(6, size()); cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, props) << cs.chunk(5, pp) << cs.chunk(6, size());
cs << cs.chunk(10, data(2000)) << cs.chunk(11, data(2001)) << cs.chunk(12, prop_bindings) << cs.chunk(0xFF, _blockitem_current_version_); cs << cs.chunk(10, data(2000)) << cs.chunk(11, data(2001)) << cs.chunk(12, prop_bindings)
<< cs.chunk(0xFF, _blockitem_current_version_);
return cs.data(); return cs.data();
} }
@@ -247,8 +245,7 @@ void BlockItem::load(const QByteArray & data) {
// qDebug() << "load pins" << _p.size(); // qDebug() << "load pins" << _p.size();
foreach(BlockItemPin * p, pins()) { foreach(BlockItemPin * p, pins()) {
// qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text()); // qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text());
if (_p.contains(p->text())) if (_p.contains(p->text())) p->properties() = _p[p->text()];
p->properties() = _p[p->text()];
} }
break; break;
case 6: setSize(cs.getData<QSizeF>()); break; case 6: setSize(cs.getData<QSizeF>()); break;
@@ -286,10 +283,11 @@ BlockItem * BlockItem::copy() const {
foreach(QGraphicsItem * i, decors_) { foreach(QGraphicsItem * i, decors_) {
ba.clear(); ba.clear();
QGraphicsItem * ni = 0; QGraphicsItem * ni = 0;
QDataStream s(&ba, QIODevice::ReadWrite); s << i; QDataStream s(&ba, QIODevice::ReadWrite);
QDataStream s2(ba); s2 >> ni; s << i;
if (ni) QDataStream s2(ba);
ret->addDecor(ni); s2 >> ni;
if (ni) ret->addDecor(ni);
} }
return ret; return ret;
} }
@@ -305,8 +303,7 @@ QList<BlockBusItem * > BlockItem::connectedBuses() const {
BlockItemPin * BlockItem::pinByText(const QString & t) const { BlockItemPin * BlockItem::pinByText(const QString & t) const {
foreach(BlockItemPin * p, pins()) foreach(BlockItemPin * p, pins())
if (p->text() == t) if (p->text() == t) return p;
return p;
return 0; return 0;
} }
@@ -314,8 +311,7 @@ BlockItemPin * BlockItem::pinByText(const QString & t) const {
BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const { BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const {
if (bus == 0) return 0; if (bus == 0) return 0;
foreach(BlockItemPin * p, pins()) foreach(BlockItemPin * p, pins())
if (p->connectedBuses().contains(bus)) if (p->connectedBuses().contains(bus)) return p;
return p;
return 0; return 0;
} }
@@ -337,7 +333,8 @@ void BlockItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
anim_thick.setStartValue(thickness()); anim_thick.setStartValue(thickness());
anim_thick.setEndValue(2.5); anim_thick.setEndValue(2.5);
anim_thick.start(); anim_thick.start();
} else setThickness(2.5); } else
setThickness(2.5);
emit blockHoverEnter(this); emit blockHoverEnter(this);
} }
@@ -349,7 +346,8 @@ void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
anim_thick.setStartValue(thickness()); anim_thick.setStartValue(thickness());
anim_thick.setEndValue(1); anim_thick.setEndValue(1);
anim_thick.start(); anim_thick.start();
} else setThickness(1); } else
setThickness(1);
emit blockHoverLeave(this); emit blockHoverLeave(this);
} }
@@ -362,13 +360,17 @@ void BlockItem::arrangePins() {
foreach(BlockItemPin * p, pl) foreach(BlockItemPin * p, pl)
pins_[p->alignment()] << p; pins_[p->alignment()] << p;
QVector<BlockItemPin *> cp = pins_.value(Qt::AlignBottom); QVector<BlockItemPin *> cp = pins_.value(Qt::AlignBottom);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), bottom()); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(_POS(pins_margin), bottom());
cp = pins_.value(Qt::AlignTop); cp = pins_.value(Qt::AlignTop);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), top()); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(_POS(pins_margin), top());
cp = pins_.value(Qt::AlignLeft); cp = pins_.value(Qt::AlignLeft);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(left(), i * pins_margin); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(left(), i * pins_margin);
cp = pins_.value(Qt::AlignRight); cp = pins_.value(Qt::AlignRight);
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(right(), i * pins_margin); for (int i = 0; i < cp.size(); ++i)
cp[i]->setPos(right(), i * pins_margin);
} }
#undef _POS #undef _POS
@@ -490,4 +492,3 @@ QRectF BlockItem::selectionRect() const {
void BlockItem::setSelectionRect(const QRectF & r) { void BlockItem::setSelectionRect(const QRectF & r) {
g_selection.setRect(r); g_selection.setRect(r);
} }

View File

@@ -20,19 +20,22 @@
#ifndef BLOCKITEM_H #ifndef BLOCKITEM_H
#define BLOCKITEM_H #define BLOCKITEM_H
#include <QElapsedTimer>
#include "blockitempin.h" #include "blockitempin.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QElapsedTimer>
class QAD_BLOCKVIEW_EXPORT BlockItem: public QGraphicsObject, public PropertyStorage
{ class QAD_BLOCKVIEW_EXPORT BlockItem
: public QGraphicsObject
, public PropertyStorage {
friend class BlockView; friend class BlockView;
friend class BlockItemPin; friend class BlockItemPin;
friend class DrawTools; friend class DrawTools;
Q_OBJECT Q_OBJECT
Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false)
Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false)
public: public:
BlockItem(QGraphicsItem * parent = 0); BlockItem(QGraphicsItem * parent = 0);
~BlockItem(); ~BlockItem();
@@ -53,7 +56,10 @@ public:
BlockItemPin * pinByText(const QString & t) const; BlockItemPin * pinByText(const QString & t) const;
BlockItemPin * pinAtBus(BlockBusItem * bus) const; BlockItemPin * pinAtBus(BlockBusItem * bus) const;
QColor color() const { return col; } QColor color() const { return col; }
void setColor(QColor c) {col = c; _resize(size());} void setColor(QColor c) {
col = c;
_resize(size());
}
QSizeF size() const { return g_main.rect().size(); } QSizeF size() const { return g_main.rect().size(); }
QRectF sceneRect() const; QRectF sceneRect() const;
qreal width() const { return size().width(); } qreal width() const { return size().width(); }
@@ -63,7 +69,10 @@ public:
void setSize(qreal w, qreal h) { setSize(QSizeF(w, h)); } void setSize(qreal w, qreal h) { setSize(QSizeF(w, h)); }
void setWidth(qreal w) { setSize(QSizeF(w, size().height())); } void setWidth(qreal w) { setSize(QSizeF(w, size().height())); }
void setHeight(qreal h) { setSize(QSizeF(size().width(), h)); } void setHeight(qreal h) { setSize(QSizeF(size().width(), h)); }
void setPinsMargin(int marg) {if (marg > 1 && marg < 256) pins_margin = marg; arrangePins();} void setPinsMargin(int marg) {
if (marg > 1 && marg < 256) pins_margin = marg;
arrangePins();
}
QByteArray saveModel(); QByteArray saveModel();
void loadModel(const QByteArray & data); void loadModel(const QByteArray & data);
@@ -82,7 +91,9 @@ public:
QStringList getBindNames() const; QStringList getBindNames() const;
QStringList getBindProps() const; QStringList getBindProps() const;
enum {Type = UserType + 1}; enum {
Type = UserType + 1
};
protected: protected:
void _resize(QSizeF s); void _resize(QSizeF s);
@@ -123,7 +134,9 @@ signals:
inline QDataStream & operator<<(QDataStream & s, const BlockItemPin * p) { inline QDataStream & operator<<(QDataStream & s, const BlockItemPin * p) {
ChunkStream cs; ChunkStream cs;
cs << cs.chunk(1, int(p->alignment())) << cs.chunk(2, p->busType()) << cs.chunk(3, p->text()) << cs.chunk(4, p->toolTip()); cs << cs.chunk(1, int(p->alignment())) << cs.chunk(2, p->busType()) << cs.chunk(3, p->text()) << cs.chunk(4, p->toolTip());
s << cs.data(); return s;} s << cs.data();
return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockItemPin *& p) { inline QDataStream & operator>>(QDataStream & s, BlockItemPin *& p) {
ChunkStream cs(s); ChunkStream cs(s);
p = new BlockItemPin(); p = new BlockItemPin();
@@ -139,9 +152,13 @@ inline QDataStream & operator >>(QDataStream & s, BlockItemPin *& p) {
} }
inline QDataStream & operator <<(QDataStream & s, const BlockItem * b) {s << b->save(); return s;} inline QDataStream & operator<<(QDataStream & s, const BlockItem * b) {
s << b->save();
return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockItem *& b) { inline QDataStream & operator>>(QDataStream & s, BlockItem *& b) {
QByteArray ba; s >> ba; QByteArray ba;
s >> ba;
b = new BlockItem(); b = new BlockItem();
b->load(ba); b->load(ba);
return s; return s;

View File

@@ -1,8 +1,12 @@
#include "blockview.h" #include "blockview.h"
#include <QApplication> #include <QApplication>
BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsObject * _parent): QGraphicsObject(_parent), ell_item(this), text_item(this) { BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsObject * _parent)
: QGraphicsObject(_parent)
, ell_item(this)
, text_item(this) {
parent_ = 0; parent_ = 0;
setData(bvidType, bvitPin); setData(bvidType, bvitPin);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
@@ -61,8 +65,7 @@ void BlockItemPin::enlargePin(bool enlarge) {
resizePin(sz); resizePin(sz);
return; return;
} }
if (sz == anim_pin_size.endValue()) if (sz == anim_pin_size.endValue()) return;
return;
anim_pin_size.stop(); anim_pin_size.stop();
anim_pin_size.setStartValue(pinSize()); anim_pin_size.setStartValue(pinSize());
anim_pin_size.setEndValue(sz); anim_pin_size.setEndValue(sz);
@@ -98,14 +101,29 @@ void BlockItemPin::_init(bool affect_parent) {
text_item.setPos(0, -tbr.height() / 2.); text_item.setPos(0, -tbr.height() / 2.);
text_item.setTransformOriginPoint(0, tbr.height() / 2.); text_item.setTransformOriginPoint(0, tbr.height() / 2.);
switch (align) { switch (align) {
case Qt::AlignBottom: ell_item.setStartAngle(16*0); text_item.setRotation(-90.); text_item.moveBy(0, -r * 1.5); break; case Qt::AlignBottom:
case Qt::AlignRight: ell_item.setStartAngle(16*90); text_item.setRotation(0.); text_item.moveBy(-tbr.width() - r * 1.5, 0); break; ell_item.setStartAngle(16 * 0);
case Qt::AlignTop: ell_item.setStartAngle(16*180); text_item.setRotation(-90.); text_item.moveBy(0, tbr.width() + r * 1.5); break; text_item.setRotation(-90.);
case Qt::AlignLeft: ell_item.setStartAngle(16*270); text_item.setRotation(0.); text_item.moveBy(r * 1.5, 0); break; text_item.moveBy(0, -r * 1.5);
break;
case Qt::AlignRight:
ell_item.setStartAngle(16 * 90);
text_item.setRotation(0.);
text_item.moveBy(-tbr.width() - r * 1.5, 0);
break;
case Qt::AlignTop:
ell_item.setStartAngle(16 * 180);
text_item.setRotation(-90.);
text_item.moveBy(0, tbr.width() + r * 1.5);
break;
case Qt::AlignLeft:
ell_item.setStartAngle(16 * 270);
text_item.setRotation(0.);
text_item.moveBy(r * 1.5, 0);
break;
default: break; default: break;
} }
if (affect_parent && parent_) if (affect_parent && parent_) parent_->arrangePins();
parent_->arrangePins();
} }
@@ -132,8 +150,7 @@ QGraphicsView * BlockItemPin::_view() const {
QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) { QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
if (change == QGraphicsItem::ItemParentChange) if (change == QGraphicsItem::ItemParentChange) _reparent();
_reparent();
return QGraphicsItem::itemChange(change, value); return QGraphicsItem::itemChange(change, value);
} }
@@ -143,7 +160,10 @@ void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
bool m_pin_mc = false; bool m_pin_mc = false;
if (v) { if (v) {
qobject_cast<BlockView *>(v)->getPinMC(&m_pin_mc); qobject_cast<BlockView *>(v)->getPinMC(&m_pin_mc);
QMetaObject::invokeMethod(v, [this, v](){qobject_cast<BlockView*>(v)->pinHoverInOut(this);}, Qt::QueuedConnection); QMetaObject::invokeMethod(
v,
[this, v]() { qobject_cast<BlockView *>(v)->pinHoverInOut(this); },
Qt::QueuedConnection);
} }
if ((state() != Disconnected) && !m_pin_mc) return; if ((state() != Disconnected) && !m_pin_mc) return;
saveState(); saveState();

View File

@@ -20,31 +20,34 @@
#ifndef BLOCKITEMPIN_H #ifndef BLOCKITEMPIN_H
#define BLOCKITEMPIN_H #define BLOCKITEMPIN_H
#include <QGraphicsView> #include "alignedtextitem.h"
#include <QGraphicsScene> #include "blockbase.h"
#include <QGraphicsObject> #include "qad_blockview_export.h"
#include <QDebug>
#include <QGraphicsEllipseItem> #include <QGraphicsEllipseItem>
#include <QGraphicsObject>
#include <QGraphicsScene>
#include <QGraphicsSceneHoverEvent> #include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QStack> #include <QGraphicsView>
#include <QDebug>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QStack>
#include <qmath.h> #include <qmath.h>
#include "blockbase.h"
#include "alignedtextitem.h"
#include "qad_blockview_export.h"
class BlockItem; class BlockItem;
class BlockBusItem; class BlockBusItem;
class QAD_BLOCKVIEW_EXPORT BlockItemPin: public QGraphicsObject, public PropertyStorage class QAD_BLOCKVIEW_EXPORT BlockItemPin
{ : public QGraphicsObject
, public PropertyStorage {
friend class BlockView; friend class BlockView;
friend class BlockItem; friend class BlockItem;
Q_OBJECT Q_OBJECT
Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false) Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false)
public: public:
BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0); BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0);
@@ -75,12 +78,22 @@ public:
State state() const { return state_; } State state() const { return state_; }
void setBusType(int type_) { bus_type = type_; } void setBusType(int type_) { bus_type = type_; }
void setAlignment(Qt::Alignment a) {align = a; _init(true);} void setAlignment(Qt::Alignment a) {
void setText(const QString & t) {text_item.setText(t); _init(true);} align = a;
_init(true);
}
void setText(const QString & t) {
text_item.setText(t);
_init(true);
}
void setState(State s); void setState(State s);
void saveState() { sstate_.push(state_); } void saveState() { sstate_.push(state_); }
bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;} bool restoreState() {
if (sstate_.isEmpty()) return false;
setState(sstate_.pop());
return true;
}
void clearStateStack() { sstate_.clear(); } void clearStateStack() { sstate_.clear(); }
void enlargePin(bool enlarge); void enlargePin(bool enlarge);
@@ -88,14 +101,18 @@ public:
BlockItem * parent() const { return parent_; } BlockItem * parent() const { return parent_; }
QList<BlockBusItem *> connectedBuses() const { return buses_; } QList<BlockBusItem *> connectedBuses() const { return buses_; }
enum {Type = UserType + 3}; enum {
Type = UserType + 3
};
public slots: public slots:
void animAccept(); void animAccept();
protected: protected:
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {} void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {}
QRectF boundingRect() const {return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());} QRectF boundingRect() const {
return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());
}
int type() const { return Type; } int type() const { return Type; }
QVariant itemChange(GraphicsItemChange change, const QVariant & value); QVariant itemChange(GraphicsItemChange change, const QVariant & value);
void hoverEnterEvent(QGraphicsSceneHoverEvent * e); void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
@@ -122,7 +139,6 @@ private:
QPropertyAnimation anim_pin_size; QPropertyAnimation anim_pin_size;
QPropertyAnimation anim_accept; QPropertyAnimation anim_accept;
}; };

View File

@@ -1,15 +1,17 @@
#include "blockview.h" #include "blockview.h"
#include "qad_types.h" #include "qad_types.h"
#include <qmath.h>
#include <QScrollBar>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>
#include <QAction> #include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QElapsedTimer>
#include <QGraphicsSceneMouseEvent>
#include <QMimeData>
#include <QScrollBar>
#include <QShortcut> #include <QShortcut>
#include <QVector2D> #include <QVector2D>
#include <QClipboard> #include <qmath.h>
#include <QMimeData>
#include <QElapsedTimer>
const QString _BlockView_Mime_ = "_BlockView_copypaste_"; const QString _BlockView_Mime_ = "_BlockView_copypaste_";
@@ -24,8 +26,7 @@ BlockView::BlockView(QGraphicsScene * scene, QWidget * parent): QGraphicsView(sc
} }
BlockView::~BlockView() { BlockView::~BlockView() {}
}
void BlockView::_init() { void BlockView::_init() {
@@ -123,15 +124,9 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
QMouseEvent * me = (QMouseEvent *)e; QMouseEvent * me = (QMouseEvent *)e;
if (!me) return true; if (!me) return true;
switch (e->type()) { switch (e->type()) {
case QEvent::Paint: case QEvent::Paint: drawThumb(); return true;
drawThumb(); case QEvent::Enter: thumbShow(); break;
return true; case QEvent::Leave: restartTimer(timer_thumb, thumb_hide_delay); break;
case QEvent::Enter:
thumbShow();
break;
case QEvent::Leave:
restartTimer(timer_thumb, thumb_hide_delay);
break;
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:
thumb_press = me->pos(); thumb_press = me->pos();
widget_thumb.setCursor(Qt::ClosedHandCursor); widget_thumb.setCursor(Qt::ClosedHandCursor);
@@ -140,12 +135,9 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
scrollFromThumb(); scrollFromThumb();
} }
break; break;
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease: widget_thumb.setCursor(Qt::OpenHandCursor); break;
widget_thumb.setCursor(Qt::OpenHandCursor);
break;
case QEvent::MouseMove: case QEvent::MouseMove:
if (me->buttons() == 0) if (me->buttons() == 0) widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
if (me->buttons().testFlag(Qt::LeftButton)) { if (me->buttons().testFlag(Qt::LeftButton)) {
thumb_vr.translate(me->pos() - thumb_press); thumb_vr.translate(me->pos() - thumb_press);
scrollFromThumb(); scrollFromThumb();
@@ -169,12 +161,18 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
foreach(QGraphicsItem * i, mil) { foreach(QGraphicsItem * i, mil) {
if (i->data(bvidTmpItem).toBool()) continue; if (i->data(bvidTmpItem).toBool()) continue;
if (i->data(bvidType).toInt() == bvitBlock) { if (i->data(bvidType).toInt() == bvitBlock) {
QMetaObject::invokeMethod(this, [this, i](){blockDoubleClicked(qgraphicsitem_cast<BlockItem*>(i));}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this, i]() { blockDoubleClicked(qgraphicsitem_cast<BlockItem *>(i)); },
Qt::QueuedConnection);
return true; return true;
} }
if (i->data(bvidType).toInt() == bvitBus) { if (i->data(bvidType).toInt() == bvitBus) {
if (qgraphicsitem_cast<BlockBusItem *>(i)->isBusSelected()) { if (qgraphicsitem_cast<BlockBusItem *>(i)->isBusSelected()) {
QMetaObject::invokeMethod(this, [this, i](){busDoubleClicked(qgraphicsitem_cast<BlockBusItem*>(i));}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this, i]() { busDoubleClicked(qgraphicsitem_cast<BlockBusItem *>(i)); },
Qt::QueuedConnection);
return true; return true;
} }
} }
@@ -249,7 +247,8 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (mm_ci->data(bvidDTHandle).toBool()) return QGraphicsView::eventFilter(o, e); if (mm_ci->data(bvidDTHandle).toBool()) return QGraphicsView::eventFilter(o, e);
if (mm_ci->data(bvidTmpItem).toBool() || mm_ci->data(bvidItemSelection).toBool()) { if (mm_ci->data(bvidTmpItem).toBool() || mm_ci->data(bvidItemSelection).toBool()) {
mil.pop_front(); mil.pop_front();
} else break; } else
break;
} }
if (mil.isEmpty()) { if (mil.isEmpty()) {
mm_ci = 0; mm_ci = 0;
@@ -257,8 +256,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
while (mm_ci->data(bvidType).toInt() == bvitBus) { while (mm_ci->data(bvidType).toInt() == bvitBus) {
if (qgraphicsitem_cast<BlockBusItem *>(mm_ci)) if (qgraphicsitem_cast<BlockBusItem *>(mm_ci))
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci)->isBusSelected()) if (qgraphicsitem_cast<BlockBusItem *>(mm_ci)->isBusSelected()) break;
break;
if (mil.size() > 1) { if (mil.size() > 1) {
mm_ci = mil[1]; mm_ci = mil[1];
mil.pop_front(); mil.pop_front();
@@ -272,8 +270,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
mm_ci = mil[1]; mm_ci = mil[1];
mil.pop_front(); mil.pop_front();
if (mm_ci->data(bvidVisualizeSelection).toBool()) if (mm_ci->data(bvidVisualizeSelection).toBool())
if (mil.size() > 1) if (mil.size() > 1) mm_ci = mil[1];
mm_ci = mil[1];
} else } else
mm_ci = 0; mm_ci = 0;
} }
@@ -357,8 +354,10 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (hpin->state() == BlockItemPin::Accept) { if (hpin->state() == BlockItemPin::Accept) {
unhoverPins(hpin); unhoverPins(hpin);
hoverAcceptedPin(hpin, true); hoverAcceptedPin(hpin, true);
} else hpin = 0; } else
} else unhoverPins(); hpin = 0;
} else
unhoverPins();
if (new_branch) { if (new_branch) {
matchBus(); matchBus();
break; break;
@@ -399,7 +398,8 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
bi << qgraphicsitem_cast<BlockItem *>(i); bi << qgraphicsitem_cast<BlockItem *>(i);
BlockItem * ti = bi.back()->copy(); BlockItem * ti = bi.back()->copy();
ti->g_main.setPen(QPen(ti->g_main.pen().color(), ti->g_main.pen().widthF(), Qt::DashLine)); ti->g_main.setPen(QPen(ti->g_main.pen().color(), ti->g_main.pen().widthF(), Qt::DashLine));
QColor bc = ti->g_main.brush().color(); bc.setAlphaF(bc.alphaF() * 0.5); QColor bc = ti->g_main.brush().color();
bc.setAlphaF(bc.alphaF() * 0.5);
ti->g_main.setBrush(bc); ti->g_main.setBrush(bc);
copy_items << ti; copy_items << ti;
scene_->addItem(ti); scene_->addItem(ti);
@@ -432,8 +432,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (mm_ci == 0) { if (mm_ci == 0) {
scene_->addItem(&sel_rect); scene_->addItem(&sel_rect);
sel_rect.show(); sel_rect.show();
if (!mm_mods.testFlag(Qt::ControlModifier)) if (!mm_mods.testFlag(Qt::ControlModifier)) clearSelection();
clearSelection();
} else { } else {
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_ci->isSelected()) { if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_ci->isSelected()) {
clearSelection(); clearSelection();
@@ -442,8 +441,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
} }
saveSelState(); saveSelState();
if (mm_ci != 0) if (mm_ci != 0)
if (!sel_items.contains(mm_ci)) if (!sel_items.contains(mm_ci)) mm_ci = 0;
mm_ci = 0;
} }
} }
} }
@@ -452,39 +450,32 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
else { else {
if (mm_drag && mm_ci != 0) { if (mm_drag && mm_ci != 0) {
mdp = (me->scenePos() - scene_point); mdp = (me->scenePos() - scene_point);
if (grid_snap) if (grid_snap) mdp = quantize(mdp, grid_step);
mdp = quantize(mdp, grid_step);
if (!mdp.isNull()) { if (!mdp.isNull()) {
scene_point += mdp; scene_point += mdp;
copy_dp += mdp; copy_dp += mdp;
} }
if (mm_copy) { if (mm_copy) {
if (!mdp.isNull()) if (!mdp.isNull()) moved = true;
moved = true;
foreach(QGraphicsItem * i, copy_items) foreach(QGraphicsItem * i, copy_items)
i->setPos(i->pos() + mdp); i->setPos(i->pos() + mdp);
foreach(BlockBusItem * i, copy_buses) foreach(BlockBusItem * i, copy_buses)
i->movePolyline(mdp); i->movePolyline(mdp);
} }
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) { if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) {
if (!mdp.isNull()) if (!mdp.isNull()) moved = true;
moved = true;
foreach(QGraphicsItem * i, sel_items) foreach(QGraphicsItem * i, sel_items)
if (i->flags().testFlag(QGraphicsItem::ItemIsMovable)) if (i->flags().testFlag(QGraphicsItem::ItemIsMovable)) i->setPos(i->pos() + mdp);
i->setPos(i->pos() + mdp); if (!me->modifiers().testFlag(Qt::AltModifier)) moveBuses(sel_items, mdp);
if (!me->modifiers().testFlag(Qt::AltModifier))
moveBuses(sel_items, mdp);
setCursor(Qt::ClosedHandCursor); setCursor(Qt::ClosedHandCursor);
} }
return true; return true;
} }
} }
if (mm_ci) if (mm_ci)
if (mm_ci->data(bvidBlockDecor).toBool()) if (mm_ci->data(bvidBlockDecor).toBool()) return true;
return true;
} }
if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0) if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0) return true;
return true;
// qDebug() << "scene mouse"; // qDebug() << "scene mouse";
break; break;
case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseRelease:
@@ -532,8 +523,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
if (moved && pm_connect) { if (moved && pm_connect) {
QList<QGraphicsItem *> ci; QList<QGraphicsItem *> ci;
foreach(QGraphicsItem * b, sel_items) foreach(QGraphicsItem * b, sel_items)
if (b->data(bvidType).toInt() == bvitBlock) if (b->data(bvidType).toInt() == bvitBlock) ci << b;
ci << b;
simplifyBuses(); simplifyBuses();
emitActionEvent(BlockItemBase::BlockMove, ci); emitActionEvent(BlockItemBase::BlockMove, ci);
reconnectAll(); reconnectAll();
@@ -570,32 +560,26 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) {
switch (smode) { switch (smode) {
case SingleSelection: case SingleSelection:
clearSelection(); clearSelection();
if (mm_ci) if (mm_ci) mm_ci->setSelected(true);
mm_ci->setSelected(true);
break; break;
case MultiSelection: case MultiSelection:
if (mm_ci == 0 || !me->modifiers().testFlag(Qt::ControlModifier)) { if (mm_ci == 0 || !me->modifiers().testFlag(Qt::ControlModifier)) {
clearSelection(); clearSelection();
if (mm_ci) if (mm_ci) mm_ci->setSelected(true);
mm_ci->setSelected(true);
} else { } else {
if (mm_ci != 0) { if (mm_ci != 0) {
if (me->modifiers().testFlag(Qt::ControlModifier)) { if (me->modifiers().testFlag(Qt::ControlModifier)) {
if (mm_ci->data(bvidType).toInt() == bvitBlock) if (mm_ci->data(bvidType).toInt() == bvitBlock) mm_ci->setSelected(!mm_ci->isSelected());
mm_ci->setSelected(!mm_ci->isSelected());
} else } else
mm_ci->setSelected(true); mm_ci->setSelected(true);
} }
} }
break; break;
default: default: clearSelection(); break;
clearSelection();
break;
} }
} }
sel_rect.hide(); sel_rect.hide();
if (sel_rect.scene()) if (sel_rect.scene()) scene_->removeItem(&sel_rect);
scene_->removeItem(&sel_rect);
mm_drag = false; mm_drag = false;
mm_ci = 0; mm_ci = 0;
unsetCursor(); unsetCursor();
@@ -637,8 +621,7 @@ void BlockView::wheelEvent(QWheelEvent * e) {
#else #else
double scl = 1. - e->angleDelta().y() / 500.; double scl = 1. - e->angleDelta().y() / 500.;
#endif #endif
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) nav_target = _nav();
nav_target = _nav();
QRectF r = nav_target; QRectF r = nav_target;
double vw = viewport()->width(), vh = viewport()->height(); double vw = viewport()->width(), vh = viewport()->height();
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
@@ -661,8 +644,7 @@ void BlockView::mousePressEvent(QMouseEvent * event) {
press_point = event->pos(); press_point = event->pos();
if (event->buttons().testFlag(QT_MID_BUTTON) || event->buttons().testFlag(Qt::RightButton)) { if (event->buttons().testFlag(QT_MID_BUTTON) || event->buttons().testFlag(Qt::RightButton)) {
setCursor(Qt::ClosedHandCursor); setCursor(Qt::ClosedHandCursor);
if (sel_rect.scene()) if (sel_rect.scene()) scene_->removeItem(&sel_rect);
scene_->removeItem(&sel_rect);
} }
QGraphicsView::mousePressEvent(event); QGraphicsView::mousePressEvent(event);
} }
@@ -781,7 +763,10 @@ void BlockView::scrollContentsBy(int dx, int dy) {
thumbShow(); thumbShow();
restartTimer(timer_thumb, thumb_hide_delay); restartTimer(timer_thumb, thumb_hide_delay);
QWidget * w = &widget_thumb; QWidget * w = &widget_thumb;
QMetaObject::invokeMethod(this, [w](){w->update();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[w]() { w->update(); },
Qt::QueuedConnection);
} }
@@ -879,7 +864,9 @@ void BlockView::drawThumb() {
thumb_scl /= cur_scl; thumb_scl /= cur_scl;
QSizeF vs(size().width() - verticalScrollBar()->width(), size().height() - horizontalScrollBar()->height()); QSizeF vs(size().width() - verticalScrollBar()->width(), size().height() - horizontalScrollBar()->height());
QRectF vr(QPointF(horizontalScrollBar()->value() - horizontalScrollBar()->minimum(), QRectF vr(QPointF(horizontalScrollBar()->value() - horizontalScrollBar()->minimum(),
verticalScrollBar()->value() - verticalScrollBar()->minimum()) * thumb_scl, vs * thumb_scl); verticalScrollBar()->value() - verticalScrollBar()->minimum()) *
thumb_scl,
vs * thumb_scl);
vr.adjust(0, 0, -1, -1); vr.adjust(0, 0, -1, -1);
p.setBrush(Qt::lightGray); p.setBrush(Qt::lightGray);
@@ -941,8 +928,7 @@ void BlockView::clearSelection() {
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(false); if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(false);
block_emit_selection = pb; block_emit_selection = pb;
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
@@ -973,8 +959,7 @@ QList<BlockBusItem * > BlockView::buses() const {
QList<QGraphicsItem *> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if ((i->data(bvidType).toInt() == bvitBus) && !i->data(bvidTmpItem).toBool()) if ((i->data(bvidType).toInt() == bvitBus) && !i->data(bvidTmpItem).toBool())
if (!copy_buses.contains((BlockBusItem*)i)) if (!copy_buses.contains((BlockBusItem *)i)) ret << qgraphicsitem_cast<BlockBusItem *>(i);
ret << qgraphicsitem_cast<BlockBusItem*>(i);
return ret; return ret;
} }
@@ -989,8 +974,7 @@ QList<BlockBusItem * > BlockView::wrongConnectedBuses() const {
QPointF pp = p->scenePos(); QPointF pp = p->scenePos();
foreach(BlockBusItem * s, sl) foreach(BlockBusItem * s, sl)
if (s->pol.contains(pp)) if (s->pol.contains(pp))
if (!ret.contains(s)) if (!ret.contains(s)) ret << s;
ret << s;
} }
} }
return ret; return ret;
@@ -1001,8 +985,7 @@ QList<BlockItem * > BlockView::blocks() const {
QList<BlockItem *> ret; QList<BlockItem *> ret;
QList<QGraphicsItem *> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) if ((i->data(bvidType).toInt() == bvitBlock) && !i->data(bvidTmpItem).toBool()) ret << qgraphicsitem_cast<BlockItem *>(i);
ret << qgraphicsitem_cast<BlockItem*>(i);
return ret; return ret;
} }
@@ -1010,8 +993,8 @@ QList<BlockItem * > BlockView::blocks() const {
QList<QGraphicsItem *> BlockView::decors() const { QList<QGraphicsItem *> BlockView::decors() const {
QList<QGraphicsItem *> ret, gi = scene_->items(); QList<QGraphicsItem *> ret, gi = scene_->items();
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if ((i->data(bvidType).toInt() == bvitDecor) && !i->data(bvidTmpItem).toBool() && !i->data(bvidItemSelection).toBool() && (i->parentItem() == 0) if ((i->data(bvidType).toInt() == bvitDecor) && !i->data(bvidTmpItem).toBool() && !i->data(bvidItemSelection).toBool() &&
&& (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i)) (i->parentItem() == 0) && (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem *)i))
ret << i; ret << i;
return ret; return ret;
} }
@@ -1026,8 +1009,7 @@ BlockBusItem * BlockView::connectionBus(BlockItem * b0, BlockItem * b1) const {
QList<BlockBusItem *> BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const { QList<BlockBusItem *> BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const {
if (!b0 || !b1) return QList<BlockBusItem *>(); if (!b0 || !b1) return QList<BlockBusItem *>();
QSet<BlockBusItem * > bs0 = QList2QSet(b0->connectedBuses()), QSet<BlockBusItem *> bs0 = QList2QSet(b0->connectedBuses()), bs1 = QList2QSet(b1->connectedBuses());
bs1 = QList2QSet(b1->connectedBuses());
return (bs0 & bs1).values(); return (bs0 & bs1).values();
} }
@@ -1046,9 +1028,15 @@ bool BlockView::connectPins(BlockItemPin * p0, BlockItemPin * p1) {
if ((bl0.isEmpty() && !bl1.isEmpty()) || (bl1.isEmpty() && !bl0.isEmpty())) { // connect empty pin to existing bus if ((bl0.isEmpty() && !bl1.isEmpty()) || (bl1.isEmpty() && !bl0.isEmpty())) { // connect empty pin to existing bus
BlockItemPin * ep = 0; BlockItemPin * ep = 0;
BlockBusItem * eb = 0; BlockBusItem * eb = 0;
if (bl0.isEmpty()) {ep = p0; eb = bl1[0];} if (bl0.isEmpty()) {
else {ep = p1; eb = bl0[0];} ep = p0;
double md = -1; int mi = -1; eb = bl1[0];
} else {
ep = p1;
eb = bl0[0];
}
double md = -1;
int mi = -1;
QPointF sp = ep->scenePos(); QPointF sp = ep->scenePos();
if (eb->pol.size() == 2) { if (eb->pol.size() == 2) {
eb->selSegment = 0; eb->selSegment = 0;
@@ -1168,8 +1156,10 @@ QRectF BlockView::itemsBoundingRect() const {
if (!(i->data(bvidItemSelection).toBool()) && !i->data(bvidTmpItem).toBool()) { if (!(i->data(bvidItemSelection).toBool()) && !i->data(bvidTmpItem).toBool()) {
QRectF br = i->mapRectToScene(i->boundingRect()); QRectF br = i->mapRectToScene(i->boundingRect());
if (br.width() <= 1 || br.height() <= 1) continue; if (br.width() <= 1 || br.height() <= 1) continue;
if (f) ret = br; if (f)
else ret |= br; ret = br;
else
ret |= br;
f = false; f = false;
} }
} }
@@ -1199,8 +1189,7 @@ void BlockView::saveSelState() {
foreach(QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
i->setData(bvidSelected, i->isSelected()); i->setData(bvidSelected, i->isSelected());
i->setData(bvidItemPos, i->pos()); i->setData(bvidItemPos, i->pos());
if (i->data(bvidType).toInt() == bvitBus) if (i->data(bvidType).toInt() == bvitBus) qgraphicsitem_cast<BlockBusItem *>(i)->bpol = qgraphicsitem_cast<BlockBusItem *>(i)->pol;
qgraphicsitem_cast<BlockBusItem*>(i)->bpol = qgraphicsitem_cast<BlockBusItem*>(i)->pol;
} }
} }
@@ -1225,7 +1214,8 @@ void BlockView::applySelRect(QGraphicsSceneMouseEvent * me) {
bool add = me->modifiers().testFlag(Qt::ControlModifier); bool add = me->modifiers().testFlag(Qt::ControlModifier);
QList<QGraphicsItem *> sil = scene_->selectedItems(); QList<QGraphicsItem *> sil = scene_->selectedItems();
block_emit_selection = true; block_emit_selection = true;
if (!add) clearSelection(); if (!add)
clearSelection();
else { else {
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
i->setSelected(i->data(bvidSelected).toBool()); i->setSelected(i->data(bvidSelected).toBool());
@@ -1234,23 +1224,20 @@ void BlockView::applySelRect(QGraphicsSceneMouseEvent * me) {
i->setSelected(!i->isSelected()); i->setSelected(!i->isSelected());
} }
block_emit_selection = false; block_emit_selection = false;
if (sil != scene_->selectedItems()) if (sil != scene_->selectedItems()) emit selectionChanged();
emit selectionChanged();
} }
void BlockView::applyGridStep() { void BlockView::applyGridStep() {
QList<QGraphicsItem *> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->type() == QGraphicsItem::UserType + 2) if (i->type() == QGraphicsItem::UserType + 2) qgraphicsitem_cast<BlockBusItem *>(i)->setGridStep(grid_step);
qgraphicsitem_cast<BlockBusItem*>(i)->setGridStep(grid_step);
} }
void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) { void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) {
if (primary) { if (primary) {
if (hpin) if (hpin) scene_pos_to = hpin->scenePos();
scene_pos_to = hpin->scenePos();
last_trace_from = scene_pos_from; last_trace_from = scene_pos_from;
trace_to = scene_pos_to; trace_to = scene_pos_to;
} }
@@ -1302,8 +1289,7 @@ void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem
// qDebug() << "fill" << p0 << "->" << p1 << "in" << steps << sx << sy; // qDebug() << "fill" << p0 << "->" << p1 << "in" << steps << sx << sy;
for (int j = 0; j <= steps; ++j) { for (int j = 0; j <= steps; ++j) {
QPoint tp = quantize(cp, grid_step).toPoint() / grid_step + dp; QPoint tp = quantize(cp, grid_step).toPoint() / grid_step + dp;
if (tp != qpt) if (tp != qpt) wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
// qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked); // qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
cp += QPointF(sx, sy); cp += QPointF(sx, sy);
} }
@@ -1341,14 +1327,11 @@ void BlockView::matchBus() {
int sp = -1, ss = -1; int sp = -1, ss = -1;
QPointF point; QPointF point;
iconnect = false; iconnect = false;
if (!tmp_bus.pol.isEmpty()) if (!tmp_bus.pol.isEmpty()) point = tmp_bus.pol.back();
point = tmp_bus.pol.back();
foreach(QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i != bus_from) { if (i != bus_from) {
if (i->data(bvidType).toInt() == bvitBus) if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
buses << qgraphicsitem_cast<BlockBusItem*>(i); if (i->data(bvidType).toInt() == bvitBlock) blockl << qgraphicsitem_cast<BlockItem *>(i);
if (i->data(bvidType).toInt() == bvitBlock)
blockl << qgraphicsitem_cast<BlockItem*>(i);
} }
} }
foreach(BlockBusItem * b, buses) { foreach(BlockBusItem * b, buses) {
@@ -1361,7 +1344,6 @@ void BlockView::matchBus() {
foreach(BlockItem * b_, blockl) foreach(BlockItem * b_, blockl)
foreach(BlockItemPin * p_, b_->pins()) foreach(BlockItemPin * p_, b_->pins())
if (p_->scenePos() == point) { if (p_->scenePos() == point) {
return; return;
} }
} }
@@ -1416,8 +1398,7 @@ bool BlockView::connectTmpToBus(BlockBusItem * bus) {
if (!bus->busState()) return false; if (!bus->busState()) return false;
if (tmp_bus.pol.size() < 2) return false; if (tmp_bus.pol.size() < 2) return false;
int np = bus->selPoint; int np = bus->selPoint;
if (np < 0) if (np < 0) np = bus->addPoint(tmp_bus.pol.back());
np = bus->addPoint(tmp_bus.pol.back());
if (np < 0) return false; if (np < 0) return false;
tmp_bus.pol.pop_back(); tmp_bus.pol.pop_back();
int lp = bus->pol.size(); int lp = bus->pol.size();
@@ -1439,12 +1420,10 @@ void BlockView::markPins(int bus_type) {
BlockItemPin * p = qgraphicsitem_cast<BlockItemPin *>(i); BlockItemPin * p = qgraphicsitem_cast<BlockItemPin *>(i);
p->saveState(); p->saveState();
if (m_pin_mc) { if (m_pin_mc) {
if (p->busType() == bus_type) if (p->busType() == bus_type) p->setState(BlockItemPin::Accept);
p->setState(BlockItemPin::Accept);
} else { } else {
if (p->busType() == bus_type) { if (p->busType() == bus_type) {
if (p->state() == BlockItemPin::Disconnected) if (p->state() == BlockItemPin::Disconnected) p->setState(BlockItemPin::Accept);
p->setState(BlockItemPin::Accept);
} }
} }
} }
@@ -1459,7 +1438,8 @@ void BlockView::unmarkPins(bool to_normal) {
if (i->data(bvidType).toInt() == bvitPin) { if (i->data(bvidType).toInt() == bvitPin) {
qgraphicsitem_cast<BlockItemPin *>(i)->restoreState(); qgraphicsitem_cast<BlockItemPin *>(i)->restoreState();
if (to_normal) if (to_normal)
while (qgraphicsitem_cast<BlockItemPin*>(i)->restoreState()); while (qgraphicsitem_cast<BlockItemPin *>(i)->restoreState())
;
} }
} }
} }
@@ -1499,8 +1479,7 @@ void BlockView::moveBuses(const QList<QGraphicsItem * > & items, QPointF dp) {
if ((i->data(bvidType).toInt() == bvitBlock) && i->flags().testFlag(QGraphicsItem::ItemIsMovable)) if ((i->data(bvidType).toInt() == bvitBlock) && i->flags().testFlag(QGraphicsItem::ItemIsMovable))
pins << qgraphicsitem_cast<BlockItem *>(i)->pins(); pins << qgraphicsitem_cast<BlockItem *>(i)->pins();
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->data(bvidType).toInt() == bvitBus) if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
buses << qgraphicsitem_cast<BlockBusItem*>(i);
foreach(BlockBusItem * b, buses) { foreach(BlockBusItem * b, buses) {
QList<BlockItemPin *> bpins = b->connections_.values(); QList<BlockItemPin *> bpins = b->connections_.values();
if (!bpins.isEmpty()) { if (!bpins.isEmpty()) {
@@ -1517,10 +1496,22 @@ void BlockView::moveBuses(const QList<QGraphicsItem * > & items, QPointF dp) {
QPointF pdp = dp; QPointF pdp = dp;
double ang = 0.; double ang = 0.;
switch (p->alignment()) { switch (p->alignment()) {
case Qt::AlignRight : pdp.setX(0.); ang = 0.; break; case Qt::AlignRight:
case Qt::AlignTop : pdp.setY(0.); ang = 90.; break; pdp.setX(0.);
case Qt::AlignLeft : pdp.setX(0.); ang = 180.; break; ang = 0.;
case Qt::AlignBottom: pdp.setY(0.); ang = 270.; break; break;
case Qt::AlignTop:
pdp.setY(0.);
ang = 90.;
break;
case Qt::AlignLeft:
pdp.setX(0.);
ang = 180.;
break;
case Qt::AlignBottom:
pdp.setY(0.);
ang = 270.;
break;
default: break; default: break;
} }
QVector<int> epl = b->endpointLine(ends[i], ang); QVector<int> epl = b->endpointLine(ends[i], ang);
@@ -1541,8 +1532,7 @@ QList<BlockBusItem * > BlockView::internalBuses(const QList<BlockItem * > & item
foreach(BlockBusItem * bi, sbl) { foreach(BlockBusItem * bi, sbl) {
if (bi->connectedBlocks().isEmpty()) continue; if (bi->connectedBlocks().isEmpty()) continue;
QSet<BlockItem *> bis = QList2QSet(bi->connectedBlocks()); QSet<BlockItem *> bis = QList2QSet(bi->connectedBlocks());
if ((bis - sis).isEmpty()) if ((bis - sis).isEmpty()) ret << bi;
ret << bi;
} }
return ret; return ret;
} }
@@ -1571,8 +1561,7 @@ QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModif
if (np == cpin) break; if (np == cpin) break;
cpin = np; cpin = np;
if (cpin) { if (cpin) {
if (((cb != cpin->parent()) && !ab) || if (((cb != cpin->parent()) && !ab) || (cpin->state() != BlockItemPin::Disconnected)) {
(cpin->state() != BlockItemPin::Disconnected)) {
break; break;
} }
cb = cpin->parent(); cb = cpin->parent();
@@ -1586,8 +1575,7 @@ QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModif
BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const { BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const {
foreach(QGraphicsItem * i, list) { foreach(QGraphicsItem * i, list) {
if (i->data(bvidType).toInt() == bvitPin) if (i->data(bvidType).toInt() == bvitPin) return qgraphicsitem_cast<BlockItemPin *>(i);
return qgraphicsitem_cast<BlockItemPin*>(i);
} }
return 0; return 0;
} }
@@ -1620,8 +1608,7 @@ QList<BlockItem * > BlockView::selectedBlocks() const {
QList<BlockItem *> ret; QList<BlockItem *> ret;
QList<QGraphicsItem *> sil = scene()->selectedItems(); QList<QGraphicsItem *> sil = scene()->selectedItems();
foreach(QGraphicsItem * b, sil) foreach(QGraphicsItem * b, sil)
if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) if ((b->data(bvidType).toInt() == bvitBlock) && !b->data(bvidTmpItem).toBool()) ret << qgraphicsitem_cast<BlockItem *>(b);
ret << qgraphicsitem_cast<BlockItem*>(b);
return ret; return ret;
} }
@@ -1629,8 +1616,7 @@ QList<BlockItem * > BlockView::selectedBlocks() const {
QList<QGraphicsItem *> BlockView::selectedDecors() const { QList<QGraphicsItem *> BlockView::selectedDecors() const {
QList<QGraphicsItem *> ret, sil = decors(); QList<QGraphicsItem *> ret, sil = decors();
foreach(QGraphicsItem * b, sil) foreach(QGraphicsItem * b, sil)
if (b->isSelected()) if (b->isSelected()) ret << b;
ret << b;
return ret; return ret;
} }
@@ -1669,12 +1655,9 @@ void BlockView::adjustThumb() {
scl = thumb_size.height() / sr.height(); scl = thumb_size.height() / sr.height();
tr = sr * scl; tr = sr * scl;
int sx = 0, sy = 0; int sx = 0, sy = 0;
if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) sx = verticalScrollBar()->width();
sx = verticalScrollBar()->width(); if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) sy = horizontalScrollBar()->height();
if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) widget_thumb.setGeometry(QRect(QPoint(width() - tr.width() - 10 - sx, height() - tr.height() - 10 - sy), tr.toSize()));
sy = horizontalScrollBar()->height();
widget_thumb.setGeometry(QRect(QPoint(width() - tr.width() - 10 - sx,
height() - tr.height() - 10 - sy), tr.toSize()));
} }
@@ -1710,10 +1693,14 @@ void BlockView::pinHoverInOut(BlockItemPin * pin) {
void BlockView::checkPaste(bool queued) { void BlockView::checkPaste(bool queued) {
const QMimeData * mime = QApplication::clipboard()->mimeData(); const QMimeData * mime = QApplication::clipboard()->mimeData();
bool ret = false; bool ret = false;
if (mime) if (mime) ret = mime->hasFormat(_BlockView_Mime_);
ret = mime->hasFormat(_BlockView_Mime_); if (queued)
if (queued) QMetaObject::invokeMethod(this, [this, ret](){pasteEnabledChanged(ret);}, Qt::QueuedConnection); QMetaObject::invokeMethod(
else emit pasteEnabledChanged(ret); this,
[this, ret]() { pasteEnabledChanged(ret); },
Qt::QueuedConnection);
else
emit pasteEnabledChanged(ret);
} }
@@ -1726,7 +1713,6 @@ void BlockView::setBusSquareNodes(bool yes) {
} }
void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) { void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) {
trace(item->press_pos, to, &tmp_bus); trace(item->press_pos, to, &tmp_bus);
tmp_bus.show(); tmp_bus.show();
@@ -1740,13 +1726,14 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
tmp_bus.hide(); tmp_bus.hide();
if (tmp_bus.pol.size() < 2) return; if (tmp_bus.pol.size() < 2) return;
tmp_bus.pol.pop_front(); tmp_bus.pol.pop_front();
if ((tmp_bus.pol.size() == 1) && (tmp_bus.pol[0] == item->press_pos)) if ((tmp_bus.pol.size() == 1) && (tmp_bus.pol[0] == item->press_pos)) return;
return;
int np = item->addPoint(item->press_pos); int np = item->addPoint(item->press_pos);
if (np < 0) return; if (np < 0) return;
if (match_bus) { if (match_bus) {
if (iconnect) tmp_bus.pol.pop_back(); if (iconnect)
else return; tmp_bus.pol.pop_back();
else
return;
} }
if (item == match_bus) return; if (item == match_bus) return;
int snp = np; int snp = np;
@@ -1760,8 +1747,7 @@ void BlockView::newBranchAccept(BlockBusItem * item) {
if (match_bus != 0) { if (match_bus != 0) {
if (!iconnect) return; if (!iconnect) return;
np = match_bus->selPoint; np = match_bus->selPoint;
if (np < 0) if (np < 0) np = match_bus->addPoint(trace_to);
np = match_bus->addPoint(trace_to);
if (np < 0) return; if (np < 0) return;
lp = item->pol.size(); lp = item->pol.size();
item->pol << match_bus->pol; item->pol << match_bus->pol;
@@ -1823,17 +1809,21 @@ void BlockView::removeJunk() {
void BlockView::sceneSelectionChanged() { void BlockView::sceneSelectionChanged() {
bool ie = scene()->selectedItems().isEmpty(); bool ie = scene()->selectedItems().isEmpty();
emit copyEnabledChanged(!ie); emit copyEnabledChanged(!ie);
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
void BlockView::_setThumb(double v) { void BlockView::_setThumb(double v) {
_talpha = v; _talpha = v;
QWidget * w = &widget_thumb; QWidget * w = &widget_thumb;
QMetaObject::invokeMethod(this, [w](){w->update();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
if (_talpha <= 0.01) widget_thumb.hide(); this,
else widget_thumb.show(); [w]() { w->update(); },
Qt::QueuedConnection);
if (_talpha <= 0.01)
widget_thumb.hide();
else
widget_thumb.show();
} }
@@ -1871,10 +1861,8 @@ void BlockView::reconnectAll() {
QList<BlockItemPin *> pins; QList<BlockItemPin *> pins;
QList<BlockBusItem *> buses; QList<BlockBusItem *> buses;
foreach(QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidType).toInt() == bvitPin) if (i->data(bvidType).toInt() == bvitPin) pins << qgraphicsitem_cast<BlockItemPin *>(i);
pins << qgraphicsitem_cast<BlockItemPin*>(i); if (i->data(bvidType).toInt() == bvitBus) buses << qgraphicsitem_cast<BlockBusItem *>(i);
if (i->data(bvidType).toInt() == bvitBus)
buses << qgraphicsitem_cast<BlockBusItem*>(i);
} }
foreach(BlockItemPin * p, pins) { foreach(BlockItemPin * p, pins) {
p->clearStateStack(); p->clearStateStack();
@@ -1893,8 +1881,7 @@ void BlockView::reconnectAll() {
// qDebug() << "found"; // qDebug() << "found";
if (b->busType() == pins[j]->busType()) { if (b->busType() == pins[j]->busType()) {
b->connections_[conns[c]] = pins[j]; b->connections_[conns[c]] = pins[j];
if (!pins[j]->buses_.contains(b)) if (!pins[j]->buses_.contains(b)) pins[j]->buses_ << b;
pins[j]->buses_ << b;
pins[j]->setState(BlockItemPin::Connected); pins[j]->setState(BlockItemPin::Connected);
} else } else
pins[j]->setState(BlockItemPin::Reject); pins[j]->setState(BlockItemPin::Reject);
@@ -1908,12 +1895,13 @@ void BlockView::reconnectAll() {
void BlockView::zoom(double factor) { void BlockView::zoom(double factor) {
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running)) nav_target = _nav();
nav_target = _nav();
QRectF r = nav_target; QRectF r = nav_target;
QPoint mp; QPoint mp;
if (underMouse()) mp = mapFromGlobal(QCursor::pos()); if (underMouse())
else mp = QPoint(viewport()->width() / 2, viewport()->height() / 2); mp = mapFromGlobal(QCursor::pos());
else
mp = QPoint(viewport()->width() / 2, viewport()->height() / 2);
double cx = double(mp.x()) / viewport()->width(), cy = double(mp.y()) / viewport()->height(); double cx = double(mp.x()) / viewport()->width(), cy = double(mp.y()) / viewport()->height();
double pw = r.width(), ph = r.height(); double pw = r.width(), ph = r.height();
r.setWidth(r.width() / factor); r.setWidth(r.width() / factor);
@@ -1972,8 +1960,10 @@ void BlockView::pasteFromClipboard() {
br |= b->boundingRect().translated(b->pos()); br |= b->boundingRect().translated(b->pos());
gl << del; gl << del;
QPointF copy_dp; QPointF copy_dp;
if (underMouse()) copy_dp = mapToScene(mapFromGlobal(QCursor::pos())); if (underMouse())
else copy_dp = mapToScene(rect().center()); copy_dp = mapToScene(mapFromGlobal(QCursor::pos()));
else
copy_dp = mapToScene(rect().center());
copy_dp -= br.center(); copy_dp -= br.center();
copy_dp = quantize(copy_dp, grid_step); copy_dp = quantize(copy_dp, grid_step);
ae_enabled = false; ae_enabled = false;
@@ -1994,8 +1984,7 @@ void BlockView::selectNone() {
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
i->setSelected(false); i->setSelected(false);
block_emit_selection = pb; block_emit_selection = pb;
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
@@ -2004,11 +1993,9 @@ void BlockView::selectAll() {
block_emit_selection = true; block_emit_selection = true;
QList<QGraphicsItem *> gi = scene_->items(); QList<QGraphicsItem *> gi = scene_->items();
foreach(QGraphicsItem * i, gi) foreach(QGraphicsItem * i, gi)
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(true);
i->setSelected(true);
block_emit_selection = pb; block_emit_selection = pb;
if (!block_emit_selection) if (!block_emit_selection) emit selectionChanged();
emit selectionChanged();
} }
@@ -2017,13 +2004,12 @@ void BlockView::removeSelected() {
blockSignals(true); blockSignals(true);
QList<BlockBusItem *> sbuses = buses(), dbuses, wbuses = wrongConnectedBuses(); QList<BlockBusItem *> sbuses = buses(), dbuses, wbuses = wrongConnectedBuses();
foreach(BlockBusItem * i, sbuses) foreach(BlockBusItem * i, sbuses)
if (i->connectedBlocks().isEmpty()) if (i->connectedBlocks().isEmpty()) dbuses << i;
dbuses << i;
foreach(QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidTmpItem).toBool()) continue; if (i->data(bvidTmpItem).toBool()) continue;
if (i->data(bvidType).toInt() == bvitBlock) if (i->data(bvidType).toInt() == bvitBlock) ai << qgraphicsitem_cast<QGraphicsItem *>(i);
ai << qgraphicsitem_cast<QGraphicsItem*>(i); if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) ||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) || (i->data(bvidType).toInt() == bvitDecor)) { (i->data(bvidType).toInt() == bvitDecor)) {
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close)); scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
delete i; delete i;
} }
@@ -2031,8 +2017,7 @@ void BlockView::removeSelected() {
reconnectAll(); reconnectAll();
foreach(BlockBusItem * i, sbuses) foreach(BlockBusItem * i, sbuses)
if (i->connectedBlocks().isEmpty()) if (i->connectedBlocks().isEmpty())
if (!dbuses.contains(i)) if (!dbuses.contains(i)) delete i;
delete i;
blockSignals(false); blockSignals(false);
foreach(QGraphicsItem * i, ai) foreach(QGraphicsItem * i, ai)
@@ -2051,9 +2036,9 @@ void BlockView::removeAll() {
ghost_ = nullptr; ghost_ = nullptr;
foreach(QGraphicsItem * i, gi) { foreach(QGraphicsItem * i, gi) {
if (i->data(bvidTmpItem).toBool()) continue; if (i->data(bvidTmpItem).toBool()) continue;
if (i->data(bvidType).toInt() == bvitBlock) if (i->data(bvidType).toInt() == bvitBlock) ai << qgraphicsitem_cast<QGraphicsItem *>(i);
ai << qgraphicsitem_cast<QGraphicsItem*>(i); if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) ||
if ((i->data(bvidType).toInt() == bvitBlock) || (i->data(bvidType).toInt() == bvitBus) || (i->data(bvidType).toInt() == bvitDecor)) { (i->data(bvidType).toInt() == bvitDecor)) {
if ((i != &sel_rect) && (i != &tmp_bus) && (i->parentItem() == 0) && !(i->data(bvidItemSelection).toBool())) { if ((i != &sel_rect) && (i != &tmp_bus) && (i->parentItem() == 0) && !(i->data(bvidItemSelection).toBool())) {
// qDebug() << "delete" << i->data(1005).toInt(); // qDebug() << "delete" << i->data(1005).toInt();
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close)); scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));

View File

@@ -20,17 +20,18 @@
#ifndef BLOCKVIEW_H #ifndef BLOCKVIEW_H
#define BLOCKVIEW_H #define BLOCKVIEW_H
#include <QGraphicsView> #include "blockbusitem.h"
#include "blockviewwavetrace.h"
#include "qad_blockview_export.h"
#include <QDebug>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsView>
#include <QMouseEvent>
#include <QPainter> #include <QPainter>
#include <QPixmap> #include <QPixmap>
#include <QMouseEvent>
#include <QDebug>
#include <QTime>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include "blockviewwavetrace.h" #include <QTime>
#include "blockbusitem.h"
#include "qad_blockview_export.h"
Q_DECLARE_METATYPE(BlockItem *) Q_DECLARE_METATYPE(BlockItem *)
@@ -38,8 +39,7 @@ Q_DECLARE_METATYPE(BlockItemPin*)
Q_DECLARE_METATYPE(BlockBusItem *) Q_DECLARE_METATYPE(BlockBusItem *)
class QAD_BLOCKVIEW_EXPORT BlockView: public QGraphicsView class QAD_BLOCKVIEW_EXPORT BlockView: public QGraphicsView {
{
Q_OBJECT Q_OBJECT
Q_ENUMS(SelectionMode) Q_ENUMS(SelectionMode)
@@ -95,7 +95,10 @@ public:
SelectionMode selectionMode() const { return smode; } SelectionMode selectionMode() const { return smode; }
void setSelectionMode(SelectionMode mode) { smode = mode; } void setSelectionMode(SelectionMode mode) { smode = mode; }
void addItems(QList<QGraphicsItem * > items) {foreach (QGraphicsItem * i, items) addItem(i);} void addItems(QList<QGraphicsItem *> items) {
foreach(QGraphicsItem * i, items)
addItem(i);
}
QList<BlockBusItem *> buses() const; QList<BlockBusItem *> buses() const;
QList<BlockBusItem *> wrongConnectedBuses() const; QList<BlockBusItem *> wrongConnectedBuses() const;
QList<BlockItem *> blocks() const; QList<BlockItem *> blocks() const;
@@ -200,7 +203,8 @@ protected:
Qt::KeyboardModifiers mm_mods; Qt::KeyboardModifiers mm_mods;
QPropertyAnimation thumb_anim, nav_anim; QPropertyAnimation thumb_anim, nav_anim;
int timer_thumb, thumb_hide_delay, thick; int timer_thumb, thumb_hide_delay, thick;
bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim, is_block_anim, move_bus_point; bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim, is_block_anim,
move_bus_point;
bool grid_visible, grid_snap, pm_connect, navigation, m_connect, m_trace_with_buses, m_pin_mc, minimap, prev_tcb, wheel_zoom; bool grid_visible, grid_snap, pm_connect, navigation, m_connect, m_trace_with_buses, m_pin_mc, minimap, prev_tcb, wheel_zoom;
bool nav_prev_aa, nav_prev_imaa, nav_prev_grid, square_node, block_emit_selection; bool nav_prev_aa, nav_prev_imaa, nav_prev_grid, square_node, block_emit_selection;
double grid_step, grid_points, cur_scl, _talpha, thumb_scl; double grid_step, grid_points, cur_scl, _talpha, thumb_scl;
@@ -228,11 +232,24 @@ protected slots:
void checkPaste() { checkPaste(false); } void checkPaste() { checkPaste(false); }
public slots: public slots:
void setGridPen(const QPen & pen) {grid_pen = pen; _updateBack();} void setGridPen(const QPen & pen) {
void setGridVisible(bool yes) {grid_visible = yes; _updateBack();} grid_pen = pen;
_updateBack();
}
void setGridVisible(bool yes) {
grid_visible = yes;
_updateBack();
}
void setSnapToGrid(bool yes) { grid_snap = yes; } void setSnapToGrid(bool yes) { grid_snap = yes; }
void setGridStep(double step) {grid_step = step; applyGridStep(); _updateBack();} void setGridStep(double step) {
void setGridPointsWidth(double width_) {grid_points = width_; _updateBack();} grid_step = step;
applyGridStep();
_updateBack();
}
void setGridPointsWidth(double width_) {
grid_points = width_;
_updateBack();
}
void setPostMoveConnectEnabled(bool on) { pm_connect = on; } void setPostMoveConnectEnabled(bool on) { pm_connect = on; }
void setNavigationEnabled(bool on) { navigation = on; } void setNavigationEnabled(bool on) { navigation = on; }
void setNavigateAnimationEnabled(bool on) { is_nav_anim = on; } void setNavigateAnimationEnabled(bool on) { is_nav_anim = on; }
@@ -271,7 +288,6 @@ signals:
void copyEnabledChanged(bool); void copyEnabledChanged(bool);
void pasteEnabledChanged(bool); void pasteEnabledChanged(bool);
void selectionChanged(); void selectionChanged();
}; };
#endif // BLOCKVIEW_H #endif // BLOCKVIEW_H

View File

@@ -11,8 +11,7 @@ BlockViewWavetrace::BlockViewWavetrace(int width, int height) {
void BlockViewWavetrace::resize(int width, int height) { void BlockViewWavetrace::resize(int width, int height) {
wid = width; wid = width;
hei = height; hei = height;
if (field.size() != wid) if (field.size() != wid) field.resize(wid);
field.resize(wid);
for (int i = 0; i < wid; ++i) { for (int i = 0; i < wid; ++i) {
if (field[i].size() != hei) { if (field[i].size() != hei) {
field[i].resize(hei); field[i].resize(hei);
@@ -41,8 +40,7 @@ void BlockViewWavetrace::fill(const QRect & rect, short val) {
void BlockViewWavetrace::fill(int px, int py, short val) { void BlockViewWavetrace::fill(int px, int py, short val) {
short p = field[px][py].value; short p = field[px][py].value;
if ((val == HorizontalBus && p == VerticalBus ) || if ((val == HorizontalBus && p == VerticalBus) || (val == VerticalBus && p == HorizontalBus))
(val == VerticalBus && p == HorizontalBus))
field[px][py].value = Blocked; field[px][py].value = Blocked;
else else
field[px][py].value = val; field[px][py].value = val;
@@ -60,8 +58,7 @@ bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
QVector<QPoint> cpnts, npnts; QVector<QPoint> cpnts, npnts;
fill(st, cl); fill(st, cl);
cpnts.push_back(st); cpnts.push_back(st);
if (field[fn.x()][fn.y()].value == (short)Blocked) if (field[fn.x()][fn.y()].value == (short)Blocked) return false;
return false;
auto checkAndFill = [this, &npnts, &frect](int x, int y, short acc_dir, short c) { auto checkAndFill = [this, &npnts, &frect](int x, int y, short acc_dir, short c) {
if (!frect.contains(x, y)) return; if (!frect.contains(x, y)) return;
short p = field[x][y].value; short p = field[x][y].value;
@@ -73,11 +70,9 @@ bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
while (cpnts.size() > 0) { while (cpnts.size() > 0) {
npnts.clear(); npnts.clear();
cl++; cl++;
if (cl >= max_steps) if (cl >= max_steps) return false;
return false;
for (int i = 0; i < cpnts.size(); ++i) { for (int i = 0; i < cpnts.size(); ++i) {
if (cpnts[i] == fn) if (cpnts[i] == fn) return true;
return true;
checkAndFill(cpnts[i].x() - 1, cpnts[i].y(), (short)VerticalBus, cl); checkAndFill(cpnts[i].x() - 1, cpnts[i].y(), (short)VerticalBus, cl);
checkAndFill(cpnts[i].x() + 1, cpnts[i].y(), (short)VerticalBus, cl); checkAndFill(cpnts[i].x() + 1, cpnts[i].y(), (short)VerticalBus, cl);
checkAndFill(cpnts[i].x(), cpnts[i].y() - 1, (short)HorizontalBus, cl); checkAndFill(cpnts[i].x(), cpnts[i].y() - 1, (short)HorizontalBus, cl);
@@ -109,14 +104,11 @@ void BlockViewWavetrace::gatherPath() {
const Cell & cell(field[cx][cy]); const Cell & cell(field[cx][cy]);
if (cell.value == c) { if (cell.value == c) {
if (cell.direction == HorizontalBus || cell.direction == VerticalBus) { if (cell.direction == HorizontalBus || cell.direction == VerticalBus) {
if (dps[dir].x() == 0 && cell.direction == VerticalBus) if (dps[dir].x() == 0 && cell.direction == VerticalBus) return false;
return false; if (dps[dir].y() == 0 && cell.direction == HorizontalBus) return false;
if (dps[dir].y() == 0 && cell.direction == HorizontalBus)
return false;
} }
ca_ = QLineF(QPointF(cx, cy), cpnt).angle(); ca_ = QLineF(QPointF(cx, cy), cpnt).angle();
if (ca_ != pa_ && !first) if (ca_ != pa_ && !first) path_.push_front(cpnt);
path_.push_front(cpnt);
cpnt = QPoint(cx, cy); cpnt = QPoint(cx, cy);
first = false; first = false;
return true; return true;
@@ -132,7 +124,6 @@ void BlockViewWavetrace::gatherPath() {
if (checkAndStep(1, cl, ca, pa)) continue; if (checkAndStep(1, cl, ca, pa)) continue;
if (checkAndStep(2, cl, ca, pa)) continue; if (checkAndStep(2, cl, ca, pa)) continue;
if (checkAndStep(3, cl, ca, pa)) continue; if (checkAndStep(3, cl, ca, pa)) continue;
} }
path_.push_front(st); path_.push_front(st);
} }

View File

@@ -28,8 +28,17 @@ class QAD_BLOCKVIEW_EXPORT BlockViewWavetrace {
public: public:
BlockViewWavetrace(int width = 1, int height = 1); BlockViewWavetrace(int width = 1, int height = 1);
enum CellState {Empty = -1, Blocked = -2, HorizontalBus = -3, VerticalBus = -4}; enum CellState {
enum Direction {NoTrace, Horizontal, Vertical}; Empty = -1,
Blocked = -2,
HorizontalBus = -3,
VerticalBus = -4
};
enum Direction {
NoTrace,
Horizontal,
Vertical
};
int width() const { return wid; } int width() const { return wid; }
int height() const { return hei; } int height() const { return hei; }
@@ -65,7 +74,6 @@ private:
QVector<QPoint> path_; QVector<QPoint> path_;
QVector<QPoint> jumps; QVector<QPoint> jumps;
QPoint dps[4], st, fn; QPoint dps[4], st, fn;
}; };
#endif // BLOCKVIEWWAVETRACE_H #endif // BLOCKVIEWWAVETRACE_H

View File

@@ -1,14 +1,16 @@
#include "drawtools.h" #include "drawtools.h"
#include "ui_drawtools.h"
#include "alignedtextitem.h" #include "alignedtextitem.h"
#include <QGraphicsLineItem> #include "ui_drawtools.h"
#include <QLineEdit>
#include <QLabel>
#include <QMouseEvent>
#include <QFileDialog>
#include <QImageReader>
#include <QDialogButtonBox>
#include <QClipboard> #include <QClipboard>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QGraphicsLineItem>
#include <QImageReader>
#include <QLabel>
#include <QLineEdit>
#include <QMouseEvent>
_DTSizeItem::_DTSizeItem(): QGraphicsObject() { _DTSizeItem::_DTSizeItem(): QGraphicsObject() {
@@ -78,17 +80,27 @@ void _DTSizeItem::moveRects() {
QRectF rect = itemRect(cur_item); QRectF rect = itemRect(cur_item);
QPointF tl = rect.topLeft(), tr = rect.topRight(), bl = rect.bottomLeft(), br = rect.bottomRight(); QPointF tl = rect.topLeft(), tr = rect.topRight(), bl = rect.bottomLeft(), br = rect.bottomRight();
if (is_line) { if (is_line) {
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeAllCursor)); rects[0].setPos(tl);
rects[1].setPos(br); rects[1].setData(2001, int(Qt::SizeAllCursor)); rects[0].setData(2001, int(Qt::SizeAllCursor));
rects[1].setPos(br);
rects[1].setData(2001, int(Qt::SizeAllCursor));
} else { } else {
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeFDiagCursor)); rects[0].setPos(tl);
rects[1].setPos((tl + tr) / 2.); rects[1].setData(2001, int(Qt::SizeVerCursor)); rects[0].setData(2001, int(Qt::SizeFDiagCursor));
rects[2].setPos(tr); rects[2].setData(2001, int(Qt::SizeBDiagCursor)); rects[1].setPos((tl + tr) / 2.);
rects[3].setPos((tr + br) / 2.); rects[3].setData(2001, int(Qt::SizeHorCursor)); rects[1].setData(2001, int(Qt::SizeVerCursor));
rects[4].setPos(br); rects[4].setData(2001, int(Qt::SizeFDiagCursor)); rects[2].setPos(tr);
rects[5].setPos((br + bl) / 2.); rects[5].setData(2001, int(Qt::SizeVerCursor)); rects[2].setData(2001, int(Qt::SizeBDiagCursor));
rects[6].setPos(bl); rects[6].setData(2001, int(Qt::SizeBDiagCursor)); rects[3].setPos((tr + br) / 2.);
rects[7].setPos((bl + tl) / 2.); rects[7].setData(2001, int(Qt::SizeHorCursor)); rects[3].setData(2001, int(Qt::SizeHorCursor));
rects[4].setPos(br);
rects[4].setData(2001, int(Qt::SizeFDiagCursor));
rects[5].setPos((br + bl) / 2.);
rects[5].setData(2001, int(Qt::SizeVerCursor));
rects[6].setPos(bl);
rects[6].setData(2001, int(Qt::SizeBDiagCursor));
rects[7].setPos((bl + tl) / 2.);
rects[7].setData(2001, int(Qt::SizeHorCursor));
} }
} }
@@ -109,10 +121,16 @@ void _DTSizeItem::doubleClick() {
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item); AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem *>(cur_item);
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item); QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem *>(cur_item);
if (itext || iatext) { if (itext || iatext) {
QMetaObject::invokeMethod(this, [this](){textEditRequest();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this]() { textEditRequest(); },
Qt::QueuedConnection);
} }
if (ipixmap) { if (ipixmap) {
QMetaObject::invokeMethod(this, [this](){pixmapEditRequest();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this]() { pixmapEditRequest(); },
Qt::QueuedConnection);
} }
} }
@@ -166,11 +184,13 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
view_ = nullptr; view_ = nullptr;
switch (event->type()) { switch (event->type()) {
case QEvent::GraphicsSceneHoverEnter: case QEvent::GraphicsSceneHoverEnter:
if (watched->scene()) if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0]; if (watched->scene())
if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0];
if (view_) view_->setCursor(Qt::CursorShape(watched->data(2001).toInt())); if (view_) view_->setCursor(Qt::CursorShape(watched->data(2001).toInt()));
break; break;
case QEvent::GraphicsSceneHoverLeave: case QEvent::GraphicsSceneHoverLeave:
if (watched->scene()) if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0]; if (watched->scene())
if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0];
if (view_) view_->unsetCursor(); if (view_) view_->unsetCursor();
break; break;
case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMousePress:
@@ -221,10 +241,12 @@ bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
} }
DrawTools::DrawTools(BlockView * parent)
: QWidget(parent)
DrawTools::DrawTools(BlockView * parent): QWidget(parent), , actions_Z_up(this)
actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(this) { , actions_Z_top(this)
, actions_Z_down(this)
, actions_Z_bottom(this) {
widget_props = new QWidget(); widget_props = new QWidget();
ui = new Ui::DrawTools(); ui = new Ui::DrawTools();
ui->setupUi(widget_props); ui->setupUi(widget_props);
@@ -265,18 +287,19 @@ actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(
connect(bbox, SIGNAL(rejected()), &text_dlg, SLOT(reject())); connect(bbox, SIGNAL(rejected()), &text_dlg, SLOT(reject()));
text_dlg.layout()->addWidget(&text_edit); text_dlg.layout()->addWidget(&text_edit);
text_dlg.layout()->addWidget(bbox); text_dlg.layout()->addWidget(bbox);
actions_Z_up.setIcon(QIcon(":/icons/z-up.png")); actions_Z_up.setEnabled(false); actions_Z_up.setIcon(QIcon(":/icons/z-up.png"));
actions_Z_top.setIcon(QIcon(":/icons/z-top.png")); actions_Z_top.setEnabled(false); actions_Z_up.setEnabled(false);
actions_Z_down.setIcon(QIcon(":/icons/z-down.png")); actions_Z_down.setEnabled(false); actions_Z_top.setIcon(QIcon(":/icons/z-top.png"));
actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png")); actions_Z_bottom.setEnabled(false); actions_Z_top.setEnabled(false);
actions_add << newAction(QIcon(":/icons/draw-rectangle.png"), 1) actions_Z_down.setIcon(QIcon(":/icons/z-down.png"));
<< newAction(QIcon(":/icons/draw-ellipse.png"), 2) actions_Z_down.setEnabled(false);
<< newAction(QIcon(":/icons/draw-line.png"), 4) actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png"));
<< newAction(QIcon(":/icons/draw-text.png"), 0) actions_Z_bottom.setEnabled(false);
actions_add << newAction(QIcon(":/icons/draw-rectangle.png"), 1) << newAction(QIcon(":/icons/draw-ellipse.png"), 2)
<< newAction(QIcon(":/icons/draw-line.png"), 4) << newAction(QIcon(":/icons/draw-text.png"), 0)
<< newAction(QIcon(":/icons/view-preview.png"), 3); << newAction(QIcon(":/icons/view-preview.png"), 3);
buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR << ui->buttonAlignCL << ui->buttonAlignCC
<< ui->buttonAlignCL << ui->buttonAlignCC << ui->buttonAlignCR << ui->buttonAlignCR << ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR;
<< ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR;
foreach(QAction * a, actions_add) { foreach(QAction * a, actions_add) {
connect(a, SIGNAL(toggled(bool)), this, SLOT(toggleNewItem(bool))); connect(a, SIGNAL(toggled(bool)), this, SLOT(toggleNewItem(bool)));
} }
@@ -328,8 +351,7 @@ DrawTools::~DrawTools() {
void DrawTools::retranslate() { void DrawTools::retranslate() {
QStringList styles; QStringList styles;
styles << tr("NoPen") << tr("Solid") << tr("Dash") styles << tr("NoPen") << tr("Solid") << tr("Dash") << tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
for (int i = 0; i < styles.size(); i++) { for (int i = 0; i < styles.size(); i++) {
ui->comboLineStyle->setItemText(i, styles[i]); ui->comboLineStyle->setItemText(i, styles[i]);
} }
@@ -395,19 +417,14 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setText("Text"); qgraphicsitem_cast<AlignedTextItem *>(new_item)->setText("Text");
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp);
break; break;
case 1: case 1: new_item = new QGraphicsRectItem(); break;
new_item = new QGraphicsRectItem(); case 2: new_item = new QGraphicsEllipseItem(); break;
break;
case 2:
new_item = new QGraphicsEllipseItem();
break;
case 3: case 3:
new_item = new QGraphicsPixmapItem(QPixmap(":/icons/view-preview.png")); new_item = new QGraphicsPixmapItem(QPixmap(":/icons/view-preview.png"));
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2)); qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(
break; sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
case 4:
new_item = new QGraphicsLineItem(QLineF(sp, sp));
break; break;
case 4: new_item = new QGraphicsLineItem(QLineF(sp, sp)); break;
}; };
if (new_item) { if (new_item) {
if (new_type == 1 || new_type == 2) { if (new_type == 1 || new_type == 2) {
@@ -424,21 +441,14 @@ bool DrawTools::eventFilter(QObject * o, QEvent * e) {
if (new_item) { if (new_item) {
mr = new_item->mapRectFromScene(QRectF(pp, sp).normalized()); mr = new_item->mapRectFromScene(QRectF(pp, sp).normalized());
switch (new_type) { switch (new_type) {
case 0: case 0: qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); break;
qgraphicsitem_cast<AlignedTextItem *>(new_item)->setPos(sp); case 1: qgraphicsitem_cast<QGraphicsRectItem *>(new_item)->setRect(mr); break;
break; case 2: qgraphicsitem_cast<QGraphicsEllipseItem *>(new_item)->setRect(mr); break;
case 1:
qgraphicsitem_cast<QGraphicsRectItem *>(new_item)->setRect(mr);
break;
case 2:
qgraphicsitem_cast<QGraphicsEllipseItem *>(new_item)->setRect(mr);
break;
case 3: case 3:
qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2)); qgraphicsitem_cast<QGraphicsPixmapItem *>(new_item)->setPos(
break; sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
case 4:
qgraphicsitem_cast<QGraphicsLineItem *>(new_item)->setLine(QLineF(pp, sp));
break; break;
case 4: qgraphicsitem_cast<QGraphicsLineItem *>(new_item)->setLine(QLineF(pp, sp)); break;
}; };
return true; return true;
} }
@@ -571,8 +581,12 @@ void DrawTools::blockPropSignals(bool block_) {
void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) { void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
blockPropSignals(true); blockPropSignals(true);
if (vert) foreach (QAction * a, menu_ver.actions()) a->setChecked(false); if (vert)
else foreach (QAction * a, menu_hor.actions()) a->setChecked(false); foreach(QAction * a, menu_ver.actions())
a->setChecked(false);
else
foreach(QAction * a, menu_hor.actions())
a->setChecked(false);
align = align & (vert ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask); align = align & (vert ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask);
align |= value; align |= value;
qobject_cast<QAction *>(sender())->setChecked(true); qobject_cast<QAction *>(sender())->setChecked(true);
@@ -583,7 +597,9 @@ void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
void DrawTools::emitZAvailabe(QGraphicsItem * item) { void DrawTools::emitZAvailabe(QGraphicsItem * item) {
BlockView * view = nullptr; BlockView * view = nullptr;
if (item) if (item->scene()) if (!item->scene()->views().isEmpty()) view = qobject_cast<BlockView *>(item->scene()->views()[0]); if (item)
if (item->scene())
if (!item->scene()->views().isEmpty()) view = qobject_cast<BlockView *>(item->scene()->views()[0]);
if (!view) { if (!view) {
moveZUpAvailable(false); moveZUpAvailable(false);
moveZDownAvailable(false); moveZDownAvailable(false);
@@ -658,16 +674,36 @@ void DrawTools::selectionChanged() {
font_dlg.setCurrentFont(iatext->font()); font_dlg.setCurrentFont(iatext->font());
font_dlg.blockSignals(false); font_dlg.blockSignals(false);
setToolButtonsEnabled(true, false, false); setToolButtonsEnabled(true, false, false);
foreach (QAction * a, menu_hor.actions()) a->setChecked(false); foreach(QAction * a, menu_hor.actions())
foreach (QAction * a, menu_ver.actions()) a->setChecked(false); a->setChecked(false);
foreach(QAction * a, menu_ver.actions())
a->setChecked(false);
align = iatext->alignment(); align = iatext->alignment();
QString als; QString als;
if (align.testFlag(Qt::AlignTop)) {als += "T"; ui->actionTop->setChecked(true);} if (align.testFlag(Qt::AlignTop)) {
if (align.testFlag(Qt::AlignVCenter)) {als += "C"; ui->actionVCenter->setChecked(true);} als += "T";
if (align.testFlag(Qt::AlignBottom)) {als += "B"; ui->actionBottom->setChecked(true);} ui->actionTop->setChecked(true);
if (align.testFlag(Qt::AlignLeft)) {als += "L"; ui->actionLeft->setChecked(true);} }
if (align.testFlag(Qt::AlignHCenter)) {als += "C"; ui->actionHCenter->setChecked(true);} if (align.testFlag(Qt::AlignVCenter)) {
if (align.testFlag(Qt::AlignRight)) {als += "R"; ui->actionRight->setChecked(true);} als += "C";
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) { foreach(QToolButton * b, buttons_align) {
b->setChecked(false); b->setChecked(false);
} }
@@ -892,28 +928,32 @@ void DrawTools::actionZ_triggered() {
if (!cur_item) return; if (!cur_item) return;
if (cur_item->data(bvidType).toInt() == bvitDecor) { if (cur_item->data(bvidType).toInt() == bvitDecor) {
BlockView * view = nullptr; BlockView * view = nullptr;
if (cur_item->scene()) if (!cur_item->scene()->views().isEmpty()) { if (cur_item->scene())
if (!cur_item->scene()->views().isEmpty()) {
view = qobject_cast<BlockView *>(cur_item->scene()->views()[0]); view = qobject_cast<BlockView *>(cur_item->scene()->views()[0]);
} }
if (!view) return; if (!view) return;
QGraphicsScene * scene = view->scene(); QGraphicsScene * scene = view->scene();
QList<QGraphicsItem *> dl = view->decors(); QList<QGraphicsItem *> dl = view->decors();
scene->blockSignals(true); scene->blockSignals(true);
foreach (QGraphicsItem * d, dl) scene->removeItem(d); foreach(QGraphicsItem * d, dl)
scene->removeItem(d);
int ind = dl.indexOf(cur_item); int ind = dl.indexOf(cur_item);
dl.removeAt(ind); dl.removeAt(ind);
if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item); if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item);
if (sender() == &actions_Z_top) dl.append(cur_item); if (sender() == &actions_Z_top) dl.append(cur_item);
if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item); if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item);
if (sender() == &actions_Z_bottom) dl.prepend(cur_item); if (sender() == &actions_Z_bottom) dl.prepend(cur_item);
foreach (QGraphicsItem * d, dl) scene->addItem(d); foreach(QGraphicsItem * d, dl)
scene->addItem(d);
scene->blockSignals(false); scene->blockSignals(false);
} }
if (cur_item->data(bvidBlockDecor).toBool()) { if (cur_item->data(bvidBlockDecor).toBool()) {
BlockItem * bi = qgraphicsitem_cast<BlockItem *>(cur_item->parentItem()); BlockItem * bi = qgraphicsitem_cast<BlockItem *>(cur_item->parentItem());
if (!bi) return; if (!bi) return;
QList<QGraphicsItem *> dl = bi->decors_; QList<QGraphicsItem *> dl = bi->decors_;
foreach (QGraphicsItem * d, dl) d->setParentItem(nullptr); foreach(QGraphicsItem * d, dl)
d->setParentItem(nullptr);
int ind = dl.indexOf(cur_item); int ind = dl.indexOf(cur_item);
dl.removeAt(ind); dl.removeAt(ind);
if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item); if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item);
@@ -921,7 +961,8 @@ void DrawTools::actionZ_triggered() {
if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item); if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item);
if (sender() == &actions_Z_bottom) dl.prepend(cur_item); if (sender() == &actions_Z_bottom) dl.prepend(cur_item);
bi->decors_ = dl; bi->decors_ = dl;
foreach (QGraphicsItem * d, dl) d->setParentItem(bi); foreach(QGraphicsItem * d, dl)
d->setParentItem(bi);
} }
size_item.assignObject(cur_item); size_item.assignObject(cur_item);
emitZAvailabe(cur_item); emitZAvailabe(cur_item);

View File

@@ -20,22 +20,23 @@
#ifndef DRAWTOOLS_H #ifndef DRAWTOOLS_H
#define DRAWTOOLS_H #define DRAWTOOLS_H
#include <QObject>
#include <QAction>
#include <QFontDialog>
#include <QToolButton>
#include <QPlainTextEdit>
#include <QMenu>
#include "blockview.h" #include "blockview.h"
#include "qad_blockview_export.h" #include "qad_blockview_export.h"
#include <QAction>
#include <QFontDialog>
#include <QMenu>
#include <QObject>
#include <QPlainTextEdit>
#include <QToolButton>
class QComboBox; class QComboBox;
class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject {
{
Q_OBJECT Q_OBJECT
public: public:
_DTSizeItem(); _DTSizeItem();
~_DTSizeItem(); ~_DTSizeItem();
@@ -64,7 +65,6 @@ signals:
void sizeChanged(); void sizeChanged();
void textEditRequest(); void textEditRequest();
void pixmapEditRequest(); void pixmapEditRequest();
}; };
@@ -73,10 +73,10 @@ namespace Ui {
} }
class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool resizeHandlesEnabled READ isResizeHandlesEnabled WRITE setResizeHandlesEnabled) Q_PROPERTY(bool resizeHandlesEnabled READ isResizeHandlesEnabled WRITE setResizeHandlesEnabled)
public: public:
explicit DrawTools(BlockView * parent = 0); explicit DrawTools(BlockView * parent = 0);
~DrawTools(); ~DrawTools();
@@ -88,7 +88,9 @@ public:
QComboBox * textEditCombo() const; QComboBox * textEditCombo() const;
QList<QAction *> actionsForAdd() const { return actions_add; } QList<QAction *> actionsForAdd() const { return actions_add; }
QList<QAction * > actionsForZ() const {return QList<QAction * >() << &actions_Z_bottom << &actions_Z_down << &actions_Z_up << &actions_Z_top;} QList<QAction *> actionsForZ() const {
return QList<QAction *>() << &actions_Z_bottom << &actions_Z_down << &actions_Z_up << &actions_Z_top;
}
QWidget * propertyWidget() const { return widget_props; } QWidget * propertyWidget() const { return widget_props; }
protected: protected:
@@ -126,9 +128,17 @@ private slots:
void sizeChanged(); void sizeChanged();
void propertyChanged(); void propertyChanged();
void comboLineStyleChanged(); void comboLineStyleChanged();
void changeFinished() {if (cur_item) emit itemEdited(cur_item);} void changeFinished() {
void moveZUpAvailable(bool yes) {actions_Z_up.setEnabled(yes); actions_Z_top.setEnabled(yes);} if (cur_item) emit itemEdited(cur_item);
void moveZDownAvailable(bool yes) {actions_Z_down.setEnabled(yes); actions_Z_bottom.setEnabled(yes);} }
void moveZUpAvailable(bool yes) {
actions_Z_up.setEnabled(yes);
actions_Z_top.setEnabled(yes);
}
void moveZDownAvailable(bool yes) {
actions_Z_down.setEnabled(yes);
actions_Z_bottom.setEnabled(yes);
}
void buttonImage_clicked(); void buttonImage_clicked();
void buttonImagePaste_clicked(); void buttonImagePaste_clicked();

View File

@@ -1,5 +1,7 @@
#include "blockview.h"
#include "blockviewplugin.h" #include "blockviewplugin.h"
#include "blockview.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -9,8 +11,7 @@ BlockViewPlugin::BlockViewPlugin(QObject * parent): QObject(parent) {
void BlockViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void BlockViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -66,4 +67,3 @@ QString BlockViewPlugin::domXml() const {
QString BlockViewPlugin::includeFile() const { QString BlockViewPlugin::includeFile() const {
return QLatin1String("blockview.h"); return QLatin1String("blockview.h");
} }

View File

@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class BlockViewPlugin: public QObject, public QDesignerCustomWidgetInterface class BlockViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif // BLOCKVIEWPLUGIN_H #endif // BLOCKVIEWPLUGIN_H

View File

@@ -1,8 +1,8 @@
#include "qad_blockview.h" #include "qad_blockview.h"
#include "blockviewplugin.h" #include "blockviewplugin.h"
QADBlockView::QADBlockView(QObject * parent): QObject(parent) QADBlockView::QADBlockView(QObject * parent): QObject(parent) {
{
m_widgets.append(new BlockViewPlugin(this)); m_widgets.append(new BlockViewPlugin(this));
} }

View File

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

View File

@@ -1,6 +1,7 @@
#include "markdown.h" #include "markdown.h"
#include <QIODevice>
#include <QDebug> #include <QDebug>
#include <QIODevice>
#ifndef NO_MARKDOWN #ifndef NO_MARKDOWN
extern "C" { extern "C" {
# include MARKDOWN_HEADER # include MARKDOWN_HEADER
@@ -29,8 +30,7 @@ extern "C" {
static QString markdown_css = "table { margin: 5px; background-color: #cccccc; }" static QString markdown_css = "table { margin: 5px; background-color: #cccccc; }"
"table tr { background-color: white; }" "table tr { background-color: white; }"
"table td { vertical-align: middle; padding: 5px;}" "table td { vertical-align: middle; padding: 5px;}"
"table th { padding: 5px; };" "table th { padding: 5px; };";
;
QString md2html(const QByteArray & src) { QString md2html(const QByteArray & src) {
static bool _is_mkd_init = false; static bool _is_mkd_init = false;

View File

@@ -20,9 +20,10 @@
#ifndef QAD_MARKDOWN_H #ifndef QAD_MARKDOWN_H
#define QAD_MARKDOWN_H #define QAD_MARKDOWN_H
#include <QString>
#include "qad_doc_export.h" #include "qad_doc_export.h"
#include <QString>
QAD_DOC_EXPORT QString md2html(const QByteArray & src); QAD_DOC_EXPORT QString md2html(const QByteArray & src);

View File

@@ -29,10 +29,10 @@
#ifndef gif_h #ifndef gif_h
#define gif_h #define gif_h
#include <stdbool.h> // for bool macros
#include <stdint.h> // for integer typedefs
#include <stdio.h> // for FILE* #include <stdio.h> // for FILE*
#include <string.h> // for memcpy and bzero #include <string.h> // for memcpy and bzero
#include <stdint.h> // for integer typedefs
#include <stdbool.h> // for bool macros
// Define these macros to hook into a custom memory allocator. // Define these macros to hook into a custom memory allocator.
// TEMP_MALLOC and TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs // TEMP_MALLOC and TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs
@@ -62,8 +62,7 @@
const int kGifTransIndex = 0; const int kGifTransIndex = 0;
typedef struct typedef struct {
{
int bitDepth; int bitDepth;
uint8_t r[256]; uint8_t r[256];
@@ -78,19 +77,23 @@ typedef struct
} GifPalette; } GifPalette;
// max, min, and abs functions // max, min, and abs functions
int GifIMax(int l, int r) { return l>r?l:r; } int GifIMax(int l, int r) {
int GifIMin(int l, int r) { return l<r?l:r; } return l > r ? l : r;
int GifIAbs(int i) { return i<0?-i:i; } }
int GifIMin(int l, int r) {
return l < r ? l : r;
}
int GifIAbs(int i) {
return i < 0 ? -i : i;
}
// walks the k-d tree to pick the palette entry for a desired color. // walks the k-d tree to pick the palette entry for a desired color.
// Takes as in/out parameters the current best color and its error - // Takes as in/out parameters the current best color and its error -
// only changes them if it finds a better color in its subtree. // only changes them if it finds a better color in its subtree.
// this is the major hotspot in the code at the moment. // this is the major hotspot in the code at the moment.
void GifGetClosestPaletteColor( GifPalette* pPal, int r, int g, int b, int* bestInd, int* bestDiff, int treeRoot ) void GifGetClosestPaletteColor(GifPalette * pPal, int r, int g, int b, int * bestInd, int * bestDiff, int treeRoot) {
{
// base case, reached the bottom of the tree // base case, reached the bottom of the tree
if(treeRoot > (1<<pPal->bitDepth)-1) if (treeRoot > (1 << pPal->bitDepth) - 1) {
{
int ind = treeRoot - (1 << pPal->bitDepth); int ind = treeRoot - (1 << pPal->bitDepth);
if (ind == kGifTransIndex) return; if (ind == kGifTransIndex) return;
@@ -100,8 +103,7 @@ void GifGetClosestPaletteColor( GifPalette* pPal, int r, int g, int b, int* best
int b_err = b - ((int32_t)pPal->b[ind]); int b_err = b - ((int32_t)pPal->b[ind]);
int diff = GifIAbs(r_err) + GifIAbs(g_err) + GifIAbs(b_err); int diff = GifIAbs(r_err) + GifIAbs(g_err) + GifIAbs(b_err);
if(diff < *bestDiff) if (diff < *bestDiff) {
{
*bestInd = ind; *bestInd = ind;
*bestDiff = diff; *bestDiff = diff;
} }
@@ -110,32 +112,29 @@ void GifGetClosestPaletteColor( GifPalette* pPal, int r, int g, int b, int* best
} }
// take the appropriate color (r, g, or b) for this node of the k-d tree // take the appropriate color (r, g, or b) for this node of the k-d tree
int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b; int comps[3];
comps[0] = r;
comps[1] = g;
comps[2] = b;
int splitComp = comps[pPal->treeSplitElt[treeRoot]]; int splitComp = comps[pPal->treeSplitElt[treeRoot]];
int splitPos = pPal->treeSplit[treeRoot]; int splitPos = pPal->treeSplit[treeRoot];
if(splitPos > splitComp) if (splitPos > splitComp) {
{
// check the left subtree // check the left subtree
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2); GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
if( *bestDiff > splitPos - splitComp ) if (*bestDiff > splitPos - splitComp) {
{
// cannot prove there's not a better value in the right subtree, check that too // 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); GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1);
} }
} } else {
else
{
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1); GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1);
if( *bestDiff > splitComp - splitPos ) if (*bestDiff > splitComp - splitPos) {
{
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2); GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
} }
} }
} }
void GifSwapPixels(uint8_t* image, int pixA, int pixB) void GifSwapPixels(uint8_t * image, int pixA, int pixB) {
{
uint8_t rA = image[pixA * 4]; uint8_t rA = image[pixA * 4];
uint8_t gA = image[pixA * 4 + 1]; uint8_t gA = image[pixA * 4 + 1];
uint8_t bA = image[pixA * 4 + 2]; uint8_t bA = image[pixA * 4 + 2];
@@ -158,24 +157,18 @@ void GifSwapPixels(uint8_t* image, int pixA, int pixB)
} }
// just the partition operation from quicksort // just the partition operation from quicksort
int GifPartition(uint8_t* image, const int left, const int right, const int elt, int pivotIndex) int GifPartition(uint8_t * image, const int left, const int right, const int elt, int pivotIndex) {
{
const int pivotValue = image[(pivotIndex)*4 + elt]; const int pivotValue = image[(pivotIndex)*4 + elt];
GifSwapPixels(image, pivotIndex, right - 1); GifSwapPixels(image, pivotIndex, right - 1);
int storeIndex = left; int storeIndex = left;
bool split = 0; bool split = 0;
for(int ii=left; ii<right-1; ++ii) for (int ii = left; ii < right - 1; ++ii) {
{
int arrayVal = image[ii * 4 + elt]; int arrayVal = image[ii * 4 + elt];
if( arrayVal < pivotValue ) if (arrayVal < pivotValue) {
{
GifSwapPixels(image, ii, storeIndex); GifSwapPixels(image, ii, storeIndex);
++storeIndex; ++storeIndex;
} } else if (arrayVal == pivotValue) {
else if( arrayVal == pivotValue ) if (split) {
{
if(split)
{
GifSwapPixels(image, ii, storeIndex); GifSwapPixels(image, ii, storeIndex);
++storeIndex; ++storeIndex;
} }
@@ -187,43 +180,41 @@ int GifPartition(uint8_t* image, const int left, const int right, const int elt,
} }
// Perform an incomplete sort, finding all elements above and below the desired median // Perform an incomplete sort, finding all elements above and below the desired median
void GifPartitionByMedian(uint8_t* image, int left, int right, int com, int neededCenter) void GifPartitionByMedian(uint8_t * image, int left, int right, int com, int neededCenter) {
{ if (left < right - 1) {
if(left < right-1)
{
int pivotIndex = left + (right - left) / 2; int pivotIndex = left + (right - left) / 2;
pivotIndex = GifPartition(image, left, right, com, pivotIndex); pivotIndex = GifPartition(image, left, right, com, pivotIndex);
// Only "sort" the section of the array that contains the median // Only "sort" the section of the array that contains the median
if(pivotIndex > neededCenter) if (pivotIndex > neededCenter) GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
if(pivotIndex < neededCenter) if (pivotIndex < neededCenter) GifPartitionByMedian(image, pivotIndex + 1, right, com, neededCenter);
GifPartitionByMedian(image, pivotIndex+1, right, com, neededCenter);
} }
} }
// Builds a palette by creating a balanced k-d tree of all pixels in the image // Builds a palette by creating a balanced k-d tree of all pixels in the image
void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette* pal) void GifSplitPalette(uint8_t * image,
{ int numPixels,
if(lastElt <= firstElt || numPixels == 0) int firstElt,
return; int lastElt,
int splitElt,
int splitDist,
int treeNode,
bool buildForDither,
GifPalette * pal) {
if (lastElt <= firstElt || numPixels == 0) return;
// base case, bottom of the tree // base case, bottom of the tree
if(lastElt == firstElt+1) if (lastElt == firstElt + 1) {
{ if (buildForDither) {
if(buildForDither)
{
// Dithering needs at least one color as dark as anything // Dithering needs at least one color as dark as anything
// in the image and at least one brightest color - // in the image and at least one brightest color -
// otherwise it builds up error and produces strange artifacts // otherwise it builds up error and produces strange artifacts
if( firstElt == 1 ) if (firstElt == 1) {
{
// special case: the darkest color in the image // special case: the darkest color in the image
uint32_t r = 255, g = 255, b = 255; uint32_t r = 255, g = 255, b = 255;
for(int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{
r = (uint32_t)GifIMin((int32_t)r, image[ii * 4 + 0]); r = (uint32_t)GifIMin((int32_t)r, image[ii * 4 + 0]);
g = (uint32_t)GifIMin((int32_t)g, image[ii * 4 + 1]); g = (uint32_t)GifIMin((int32_t)g, image[ii * 4 + 1]);
b = (uint32_t)GifIMin((int32_t)b, image[ii * 4 + 2]); b = (uint32_t)GifIMin((int32_t)b, image[ii * 4 + 2]);
@@ -236,12 +227,10 @@ void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, i
return; return;
} }
if( firstElt == (1 << pal->bitDepth)-1 ) if (firstElt == (1 << pal->bitDepth) - 1) {
{
// special case: the lightest color in the image // special case: the lightest color in the image
uint32_t r = 0, g = 0, b = 0; uint32_t r = 0, g = 0, b = 0;
for(int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{
r = (uint32_t)GifIMax((int32_t)r, image[ii * 4 + 0]); r = (uint32_t)GifIMax((int32_t)r, image[ii * 4 + 0]);
g = (uint32_t)GifIMax((int32_t)g, image[ii * 4 + 1]); g = (uint32_t)GifIMax((int32_t)g, image[ii * 4 + 1]);
b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]); b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]);
@@ -257,8 +246,7 @@ void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, i
// otherwise, take the average of all colors in this subcube // otherwise, take the average of all colors in this subcube
uint64_t r = 0, g = 0, b = 0; uint64_t r = 0, g = 0, b = 0;
for(int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{
r += image[ii * 4 + 0]; r += image[ii * 4 + 0];
g += image[ii * 4 + 1]; g += image[ii * 4 + 1];
b += image[ii * 4 + 2]; b += image[ii * 4 + 2];
@@ -283,8 +271,7 @@ void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, i
int minR = 255, maxR = 0; int minR = 255, maxR = 0;
int minG = 255, maxG = 0; int minG = 255, maxG = 0;
int minB = 255, maxB = 0; int minB = 255, maxB = 0;
for(int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{
int r = image[ii * 4 + 0]; int r = image[ii * 4 + 0];
int g = image[ii * 4 + 1]; int g = image[ii * 4 + 1];
int b = image[ii * 4 + 2]; int b = image[ii * 4 + 2];
@@ -317,24 +304,27 @@ void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, i
pal->treeSplit[treeNode] = image[subPixelsA * 4 + splitCom]; pal->treeSplit[treeNode] = image[subPixelsA * 4 + splitCom];
GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt - splitDist, splitDist / 2, treeNode * 2, buildForDither, pal); GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt - splitDist, splitDist / 2, treeNode * 2, buildForDither, pal);
GifSplitPalette(image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2+1, buildForDither, pal); GifSplitPalette(image + subPixelsA * 4,
subPixelsB,
splitElt,
lastElt,
splitElt + splitDist,
splitDist / 2,
treeNode * 2 + 1,
buildForDither,
pal);
} }
// Finds all pixels that have changed from the previous image and // Finds all pixels that have changed from the previous image and
// moves them to the fromt of th buffer. // moves them to the fromt of th buffer.
// This allows us to build a palette optimized for the colors of the // This allows us to build a palette optimized for the colors of the
// changed pixels only. // changed pixels only.
int GifPickChangedPixels( const uint8_t* lastFrame, uint8_t* frame, int numPixels ) int GifPickChangedPixels(const uint8_t * lastFrame, uint8_t * frame, int numPixels) {
{
int numChanged = 0; int numChanged = 0;
uint8_t * writeIter = frame; uint8_t * writeIter = frame;
for (int ii=0; ii<numPixels; ++ii) for (int ii = 0; ii < numPixels; ++ii) {
{ if (lastFrame[0] != frame[0] || lastFrame[1] != frame[1] || lastFrame[2] != frame[2]) {
if(lastFrame[0] != frame[0] ||
lastFrame[1] != frame[1] ||
lastFrame[2] != frame[2])
{
writeIter[0] = frame[0]; writeIter[0] = frame[0];
writeIter[1] = frame[1]; writeIter[1] = frame[1];
writeIter[2] = frame[2]; writeIter[2] = frame[2];
@@ -350,8 +340,13 @@ int GifPickChangedPixels( const uint8_t* lastFrame, uint8_t* frame, int numPixel
// Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom. // Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom.
// This is known as the "modified median split" technique // This is known as the "modified median split" technique
void GifMakePalette( const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette* pPal ) void GifMakePalette(const uint8_t * lastFrame,
{ const uint8_t * nextFrame,
uint32_t width,
uint32_t height,
int bitDepth,
bool buildForDither,
GifPalette * pPal) {
pPal->bitDepth = bitDepth; pPal->bitDepth = bitDepth;
// SplitPalette is destructive (it sorts the pixels by color) so // SplitPalette is destructive (it sorts the pixels by color) so
@@ -361,8 +356,7 @@ void GifMakePalette( const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_
memcpy(destroyableImage, nextFrame, imageSize); memcpy(destroyableImage, nextFrame, imageSize);
int numPixels = (int)(width * height); int numPixels = (int)(width * height);
if(lastFrame) if (lastFrame) numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
const int lastElt = 1 << bitDepth; const int lastElt = 1 << bitDepth;
const int splitElt = lastElt / 2; const int splitElt = lastElt / 2;
@@ -380,8 +374,12 @@ void GifMakePalette( const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_
} }
// Implements Floyd-Steinberg dithering, writes palette value to alpha // Implements Floyd-Steinberg dithering, writes palette value to alpha
void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal ) void GifDitherImage(const uint8_t * lastFrame,
{ const uint8_t * nextFrame,
uint8_t * outFrame,
uint32_t width,
uint32_t height,
GifPalette * pPal) {
int numPixels = (int)(width * height); int numPixels = (int)(width * height);
// quantPixels initially holds color*256 for all pixels // quantPixels initially holds color*256 for all pixels
@@ -389,17 +387,14 @@ void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t
// to be propagated // to be propagated
int32_t * quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4); int32_t * quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4);
for( int ii=0; ii<numPixels*4; ++ii ) for (int ii = 0; ii < numPixels * 4; ++ii) {
{
uint8_t pix = nextFrame[ii]; uint8_t pix = nextFrame[ii];
int32_t pix16 = (int32_t)(pix)*256; int32_t pix16 = (int32_t)(pix)*256;
quantPixels[ii] = pix16; quantPixels[ii] = pix16;
} }
for( uint32_t yy=0; yy<height; ++yy ) for (uint32_t yy = 0; yy < height; ++yy) {
{ for (uint32_t xx = 0; xx < width; ++xx) {
for( uint32_t xx=0; xx<width; ++xx )
{
int32_t * nextPix = quantPixels + 4 * (yy * width + xx); int32_t * nextPix = quantPixels + 4 * (yy * width + xx);
const uint8_t * lastPix = lastFrame ? lastFrame + 4 * (yy * width + xx) : NULL; const uint8_t * lastPix = lastFrame ? lastFrame + 4 * (yy * width + xx) : NULL;
@@ -410,11 +405,7 @@ void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t
// if it happens that we want the color from last frame, then just write out // if it happens that we want the color from last frame, then just write out
// a transparent pixel // a transparent pixel
if( lastFrame && if (lastFrame && lastPix[0] == rr && lastPix[1] == gg && lastPix[2] == bb) {
lastPix[0] == rr &&
lastPix[1] == gg &&
lastPix[2] == bb )
{
nextPix[0] = rr; nextPix[0] = rr;
nextPix[1] = gg; nextPix[1] = gg;
nextPix[2] = bb; nextPix[2] = bb;
@@ -445,32 +436,28 @@ void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t
int quantloc_5 = (int)(yy * width + width + xx); int quantloc_5 = (int)(yy * width + width + xx);
int quantloc_1 = (int)(yy * width + width + xx + 1); int quantloc_1 = (int)(yy * width + width + xx + 1);
if(quantloc_7 < numPixels) if (quantloc_7 < numPixels) {
{
int32_t * pix7 = quantPixels + 4 * quantloc_7; int32_t * pix7 = quantPixels + 4 * quantloc_7;
pix7[0] += GifIMax(-pix7[0], r_err * 7 / 16); pix7[0] += GifIMax(-pix7[0], r_err * 7 / 16);
pix7[1] += GifIMax(-pix7[1], g_err * 7 / 16); pix7[1] += GifIMax(-pix7[1], g_err * 7 / 16);
pix7[2] += GifIMax(-pix7[2], b_err * 7 / 16); pix7[2] += GifIMax(-pix7[2], b_err * 7 / 16);
} }
if(quantloc_3 < numPixels) if (quantloc_3 < numPixels) {
{
int32_t * pix3 = quantPixels + 4 * quantloc_3; int32_t * pix3 = quantPixels + 4 * quantloc_3;
pix3[0] += GifIMax(-pix3[0], r_err * 3 / 16); pix3[0] += GifIMax(-pix3[0], r_err * 3 / 16);
pix3[1] += GifIMax(-pix3[1], g_err * 3 / 16); pix3[1] += GifIMax(-pix3[1], g_err * 3 / 16);
pix3[2] += GifIMax(-pix3[2], b_err * 3 / 16); pix3[2] += GifIMax(-pix3[2], b_err * 3 / 16);
} }
if(quantloc_5 < numPixels) if (quantloc_5 < numPixels) {
{
int32_t * pix5 = quantPixels + 4 * quantloc_5; int32_t * pix5 = quantPixels + 4 * quantloc_5;
pix5[0] += GifIMax(-pix5[0], r_err * 5 / 16); pix5[0] += GifIMax(-pix5[0], r_err * 5 / 16);
pix5[1] += GifIMax(-pix5[1], g_err * 5 / 16); pix5[1] += GifIMax(-pix5[1], g_err * 5 / 16);
pix5[2] += GifIMax(-pix5[2], b_err * 5 / 16); pix5[2] += GifIMax(-pix5[2], b_err * 5 / 16);
} }
if(quantloc_1 < numPixels) if (quantloc_1 < numPixels) {
{
int32_t * pix1 = quantPixels + 4 * quantloc_1; int32_t * pix1 = quantPixels + 4 * quantloc_1;
pix1[0] += GifIMax(-pix1[0], r_err / 16); pix1[0] += GifIMax(-pix1[0], r_err / 16);
pix1[1] += GifIMax(-pix1[1], g_err / 16); pix1[1] += GifIMax(-pix1[1], g_err / 16);
@@ -480,8 +467,7 @@ void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t
} }
// Copy the palettized result to the output buffer // Copy the palettized result to the output buffer
for( int ii=0; ii<numPixels*4; ++ii ) for (int ii = 0; ii < numPixels * 4; ++ii) {
{
outFrame[ii] = (uint8_t)quantPixels[ii]; outFrame[ii] = (uint8_t)quantPixels[ii];
} }
@@ -489,25 +475,22 @@ void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t
} }
// Picks palette colors for the image using simple thresholding, no dithering // Picks palette colors for the image using simple thresholding, no dithering
void GifThresholdImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal ) void GifThresholdImage(const uint8_t * lastFrame,
{ const uint8_t * nextFrame,
uint8_t * outFrame,
uint32_t width,
uint32_t height,
GifPalette * pPal) {
uint32_t numPixels = width * height; uint32_t numPixels = width * height;
for( uint32_t ii=0; ii<numPixels; ++ii ) for (uint32_t ii = 0; ii < numPixels; ++ii) {
{
// if a previous color is available, and it matches the current color, // if a previous color is available, and it matches the current color,
// set the pixel to transparent // set the pixel to transparent
if(lastFrame && if (lastFrame && lastFrame[0] == nextFrame[0] && lastFrame[1] == nextFrame[1] && lastFrame[2] == nextFrame[2]) {
lastFrame[0] == nextFrame[0] &&
lastFrame[1] == nextFrame[1] &&
lastFrame[2] == nextFrame[2])
{
outFrame[0] = lastFrame[0]; outFrame[0] = lastFrame[0];
outFrame[1] = lastFrame[1]; outFrame[1] = lastFrame[1];
outFrame[2] = lastFrame[2]; outFrame[2] = lastFrame[2];
outFrame[3] = kGifTransIndex; outFrame[3] = kGifTransIndex;
} } else {
else
{
// palettize the pixel // palettize the pixel
int32_t bestDiff = 1000000; int32_t bestDiff = 1000000;
int32_t bestInd = 1; int32_t bestInd = 1;
@@ -528,8 +511,7 @@ void GifThresholdImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint
// Simple structure to write out the LZW-compressed portion of the image // Simple structure to write out the LZW-compressed portion of the image
// one bit at a time // one bit at a time
typedef struct typedef struct {
{
uint8_t bitIndex; // how many bits in the partial byte written so far uint8_t bitIndex; // how many bits in the partial byte written so far
uint8_t byte; // current partial byte uint8_t byte; // current partial byte
@@ -538,15 +520,13 @@ typedef struct
} GifBitStatus; } GifBitStatus;
// insert a single bit // insert a single bit
void GifWriteBit( GifBitStatus* stat, uint32_t bit ) void GifWriteBit(GifBitStatus * stat, uint32_t bit) {
{
bit = bit & 1; bit = bit & 1;
bit = bit << stat->bitIndex; bit = bit << stat->bitIndex;
stat->byte |= bit; stat->byte |= bit;
++stat->bitIndex; ++stat->bitIndex;
if( stat->bitIndex > 7 ) if (stat->bitIndex > 7) {
{
// move the newly-finished byte to the chunk buffer // move the newly-finished byte to the chunk buffer
stat->chunk[stat->chunkIndex++] = stat->byte; stat->chunk[stat->chunkIndex++] = stat->byte;
// and start a new byte // and start a new byte
@@ -556,8 +536,7 @@ void GifWriteBit( GifBitStatus* stat, uint32_t bit )
} }
// write all bytes so far to the file // write all bytes so far to the file
void GifWriteChunk( FILE* f, GifBitStatus* stat ) void GifWriteChunk(FILE * f, GifBitStatus * stat) {
{
fputc((int)stat->chunkIndex, f); fputc((int)stat->chunkIndex, f);
fwrite(stat->chunk, 1, stat->chunkIndex, f); fwrite(stat->chunk, 1, stat->chunkIndex, f);
@@ -566,15 +545,12 @@ void GifWriteChunk( FILE* f, GifBitStatus* stat )
stat->chunkIndex = 0; stat->chunkIndex = 0;
} }
void GifWriteCode( FILE* f, GifBitStatus* stat, uint32_t code, uint32_t length ) void GifWriteCode(FILE * f, GifBitStatus * stat, uint32_t code, uint32_t length) {
{ for (uint32_t ii = 0; ii < length; ++ii) {
for( uint32_t ii=0; ii<length; ++ii )
{
GifWriteBit(stat, code); GifWriteBit(stat, code);
code = code >> 1; code = code >> 1;
if( stat->chunkIndex == 255 ) if (stat->chunkIndex == 255) {
{
GifWriteChunk(f, stat); GifWriteChunk(f, stat);
} }
} }
@@ -582,20 +558,17 @@ void GifWriteCode( FILE* f, GifBitStatus* stat, uint32_t code, uint32_t length )
// The LZW dictionary is a 256-ary tree constructed as the file is encoded, // The LZW dictionary is a 256-ary tree constructed as the file is encoded,
// this is one node // this is one node
typedef struct typedef struct {
{
uint16_t m_next[256]; uint16_t m_next[256];
} GifLzwNode; } GifLzwNode;
// write a 256-color (8-bit) image palette to the file // write a 256-color (8-bit) image palette to the file
void GifWritePalette( const GifPalette* pPal, FILE* f ) void GifWritePalette(const GifPalette * pPal, FILE * f) {
{
fputc(0, f); // first color: transparency fputc(0, f); // first color: transparency
fputc(0, f); fputc(0, f);
fputc(0, f); fputc(0, f);
for(int ii=1; ii<(1 << pPal->bitDepth); ++ii) for (int ii = 1; ii < (1 << pPal->bitDepth); ++ii) {
{
uint32_t r = pPal->r[ii]; uint32_t r = pPal->r[ii];
uint32_t g = pPal->g[ii]; uint32_t g = pPal->g[ii];
uint32_t b = pPal->b[ii]; uint32_t b = pPal->b[ii];
@@ -607,8 +580,14 @@ void GifWritePalette( const GifPalette* pPal, FILE* f )
} }
// write the image header, LZW-compress and write out the image // write the image header, LZW-compress and write out the image
void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette* pPal) void GifWriteLzwImage(FILE * f,
{ uint8_t * image,
uint32_t left,
uint32_t top,
uint32_t width,
uint32_t height,
uint32_t delay,
GifPalette * pPal) {
// graphics control extension // graphics control extension
fputc(0x21, f); fputc(0x21, f);
fputc(0xf9, f); fputc(0xf9, f);
@@ -656,10 +635,8 @@ void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uin
GifWriteCode(f, &stat, clearCode, codeSize); // start with a fresh LZW dictionary GifWriteCode(f, &stat, clearCode, codeSize); // start with a fresh LZW dictionary
for(uint32_t yy=0; yy<height; ++yy) for (uint32_t yy = 0; yy < height; ++yy) {
{ for (uint32_t xx = 0; xx < width; ++xx) {
for(uint32_t xx=0; xx<width; ++xx)
{
#ifdef GIF_FLIP_VERT #ifdef GIF_FLIP_VERT
// bottom-left origin image (such as an OpenGL capture) // bottom-left origin image (such as an OpenGL capture)
uint8_t nextValue = image[((height - 1 - yy) * width + xx) * 4 + 3]; uint8_t nextValue = image[((height - 1 - yy) * width + xx) * 4 + 3];
@@ -672,32 +649,25 @@ void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uin
// WriteCode( f, stat, nextValue, codeSize ); // WriteCode( f, stat, nextValue, codeSize );
// WriteCode( f, stat, 256, codeSize ); // WriteCode( f, stat, 256, codeSize );
if( curCode < 0 ) if (curCode < 0) {
{
// first value in a new run // first value in a new run
curCode = nextValue; curCode = nextValue;
} } else if (codetree[curCode].m_next[nextValue]) {
else if( codetree[curCode].m_next[nextValue] )
{
// current run already in the dictionary // current run already in the dictionary
curCode = codetree[curCode].m_next[nextValue]; curCode = codetree[curCode].m_next[nextValue];
} } else {
else
{
// finish the current run, write a code // finish the current run, write a code
GifWriteCode(f, &stat, (uint32_t)curCode, codeSize); GifWriteCode(f, &stat, (uint32_t)curCode, codeSize);
// insert the new run into the dictionary // insert the new run into the dictionary
codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode; codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode;
if( maxCode >= (1ul << codeSize) ) if (maxCode >= (1ul << codeSize)) {
{
// dictionary entry count has broken a size barrier, // dictionary entry count has broken a size barrier,
// we need more bits for codes // we need more bits for codes
codeSize++; codeSize++;
} }
if( maxCode == 4095 ) if (maxCode == 4095) {
{
// the dictionary is full, clear it out and begin anew // the dictionary is full, clear it out and begin anew
GifWriteCode(f, &stat, clearCode, codeSize); // clear tree GifWriteCode(f, &stat, clearCode, codeSize); // clear tree
@@ -717,7 +687,8 @@ void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uin
GifWriteCode(f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1); GifWriteCode(f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1);
// write out the last partial chunk // write out the last partial chunk
while( stat.bitIndex ) GifWriteBit(&stat, 0); while (stat.bitIndex)
GifWriteBit(&stat, 0);
if (stat.chunkIndex) GifWriteChunk(f, &stat); if (stat.chunkIndex) GifWriteChunk(f, &stat);
fputc(0, f); // image block terminator fputc(0, f); // image block terminator
@@ -725,8 +696,7 @@ void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uin
GIF_TEMP_FREE(codetree); GIF_TEMP_FREE(codetree);
} }
typedef struct typedef struct {
{
FILE * f; FILE * f;
uint8_t * oldImage; uint8_t * oldImage;
bool firstFrame; bool firstFrame;
@@ -735,9 +705,15 @@ typedef struct
// Creates a gif file. // Creates a gif file.
// The input GIFWriter is assumed to be uninitialized. // The input GIFWriter is assumed to be uninitialized.
// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value. // The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value.
bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth = 8, bool dither = false ) bool GifBegin(GifWriter * writer,
{ const char * filename,
(void)bitDepth; (void)dither; // Mute "Unused argument" warnings uint32_t width,
uint32_t height,
uint32_t delay,
int32_t bitDepth = 8,
bool dither = false) {
(void)bitDepth;
(void)dither; // Mute "Unused argument" warnings
#if defined(_MSC_VER) && (_MSC_VER >= 1400) #if defined(_MSC_VER) && (_MSC_VER >= 1400)
writer->f = 0; writer->f = 0;
fopen_s(&writer->f, filename, "wb"); fopen_s(&writer->f, filename, "wb");
@@ -773,8 +749,7 @@ bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t
fputc(0, writer->f); fputc(0, writer->f);
fputc(0, writer->f); fputc(0, writer->f);
if( delay != 0 ) if (delay != 0) {
{
// animation header // animation header
fputc(0x21, writer->f); // extension fputc(0x21, writer->f); // extension
fputc(0xff, writer->f); // application specific fputc(0xff, writer->f); // application specific
@@ -796,8 +771,13 @@ bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t
// The GIFWriter should have been created by GIFBegin. // The GIFWriter should have been created by GIFBegin.
// AFAIK, it is legal to use different bit depths for different frames of an image - // AFAIK, it is legal to use different bit depths for different frames of an image -
// this may be handy to save bits in animations that don't change much. // this may be handy to save bits in animations that don't change much.
bool GifWriteFrame( GifWriter* writer, const uint8_t* image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth = 8, bool dither = false ) bool GifWriteFrame(GifWriter * writer,
{ const uint8_t * image,
uint32_t width,
uint32_t height,
uint32_t delay,
int bitDepth = 8,
bool dither = false) {
if (!writer->f) return false; if (!writer->f) return false;
const uint8_t * oldImage = writer->firstFrame ? NULL : writer->oldImage; const uint8_t * oldImage = writer->firstFrame ? NULL : writer->oldImage;
@@ -819,8 +799,7 @@ bool GifWriteFrame( GifWriter* writer, const uint8_t* image, uint32_t width, uin
// Writes the EOF code, closes the file handle, and frees temp memory used by a GIF. // Writes the EOF code, closes the file handle, and frees temp memory used by a GIF.
// Many if not most viewers will still display a GIF properly if the EOF code is missing, // Many if not most viewers will still display a GIF properly if the EOF code is missing,
// but it's still a good idea to write it out. // but it's still a good idea to write it out.
bool GifEnd( GifWriter* writer ) bool GifEnd(GifWriter * writer) {
{
if (!writer->f) return false; if (!writer->f) return false;
fputc(0x3b, writer->f); // end of file fputc(0x3b, writer->f); // end of file

View File

@@ -1,19 +1,21 @@
#include "graphic.h" #include "graphic.h"
#include "gif.h"
#include "qad_types.h" #include "qad_types.h"
#include "uglwidget.h" #include "uglwidget.h"
#include "ui_graphic.h" #include "ui_graphic.h"
#include "ui_graphic_conf.h" #include "ui_graphic_conf.h"
#include <float.h>
#include <QMetaObject> #include <QActionGroup>
#include <QInputDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QTapAndHoldGesture> #include <QMetaObject>
#include <QPanGesture> #include <QPanGesture>
#include <QPinchGesture> #include <QPinchGesture>
#include <QActionGroup>
#include <QScrollArea> #include <QScrollArea>
#include <QTapAndHoldGesture>
#include <QTimer> #include <QTimer>
#include <QInputDialog> #include <float.h>
#include "gif.h"
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
# include <QRandomGenerator> # include <QRandomGenerator>
#endif #endif
@@ -61,6 +63,7 @@ public:
w->setAutoFillBackground(false); w->setAutoFillBackground(false);
} }
int minimum_hei; int minimum_hei;
protected: protected:
virtual QSize sizeHint() const { virtual QSize sizeHint() const {
QSize ret; QSize ret;
@@ -68,9 +71,7 @@ protected:
ret = widget()->sizeHint(); ret = widget()->sizeHint();
return ret; return ret;
} }
virtual QSize minimumSizeHint() const { virtual QSize minimumSizeHint() const { return QSize(1, minimum_hei); }
return QSize(1, minimum_hei);
}
}; };
@@ -95,8 +96,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
#ifdef NO_BUTTONS #ifdef NO_BUTTONS
ui->widgetLeft->hide(); ui->widgetLeft->hide();
ui->widgetRight->hide(); ui->widgetRight->hide();
QList<QToolButton*> btnlist = { QList<QToolButton *> btnlist = {ui->graphic_buttonAutofit,
ui->graphic_buttonAutofit,
ui->graphic_checkGrid, ui->graphic_checkGrid,
ui->graphic_checkGuides, ui->graphic_checkGuides,
ui->graphic_buttonFullscreen, ui->graphic_buttonFullscreen,
@@ -257,8 +257,7 @@ void Graphic::showEvent(QShowEvent *) {
void Graphic::timerEvent(QTimerEvent * e) { void Graphic::timerEvent(QTimerEvent * e) {
if (e->timerId() == timer_pause) { if (e->timerId() == timer_pause) {
pause_phase += 0.02; pause_phase += 0.02;
if (pause_phase > 1.) if (pause_phase > 1.) pause_phase -= 1.;
pause_phase -= 1.;
update(); update();
} }
if (e->timerId() == timer_record) { if (e->timerId() == timer_record) {
@@ -355,16 +354,19 @@ void Graphic::procGesture(QGesture * g) {
case Qt::TapAndHoldGesture: { case Qt::TapAndHoldGesture: {
QTapAndHoldGesture * pg = (QTapAndHoldGesture *)g; QTapAndHoldGesture * pg = (QTapAndHoldGesture *)g;
if (pg->state() == Qt::GestureStarted) if (pg->state() == Qt::GestureStarted)
QMetaObject::invokeMethod(this, [this](){showMenu();}, Qt::QueuedConnection); QMetaObject::invokeMethod(
this,
[this]() { showMenu(); },
Qt::QueuedConnection);
} break; } break;
default: default: break;
break;
} }
} }
void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km) { void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km) {
double scl, wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top(); double scl, wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(),
hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
double px = view_center.x() - gridborder.x() - margins_.left(), py = hei - view_center.y() + margins_.height(); double px = view_center.x() - gridborder.x() - margins_.left(), py = hei - view_center.y() + margins_.height();
px = px / wid * selrect.width() + selrect.x(); px = px / wid * selrect.width() + selrect.x();
py = py / hei * selrect.height() + selrect.y(); py = py / hei * selrect.height() + selrect.y();
@@ -372,12 +374,9 @@ void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers
if (km == Qt::NoModifier) if (km == Qt::NoModifier)
selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl); selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl);
else { else {
if (km == Qt::ControlModifier) if (km == Qt::ControlModifier) selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height());
selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height()); if (km == Qt::ShiftModifier) selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
if (km == Qt::ShiftModifier) if (km == Qt::AltModifier) selrect.translate((dzoom > 0. ? 1. : -1.) * selrect.width() / 2., 0.);
selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
if (km == Qt::AltModifier)
selrect.translate((dzoom > 0. ? 1. : -1.) * selrect.width() / 2., 0.);
} }
} }
@@ -395,8 +394,7 @@ void Graphic::canvasPaintEvent() {
int wid = canvas->width(), hei = canvas->height(); int wid = canvas->width(), hei = canvas->height();
if (canvas->isHidden() || wid <= 1 || hei <= 1) return; if (canvas->isHidden() || wid <= 1 || hei <= 1) return;
if (!buffer.isNull()) { if (!buffer.isNull()) {
if (lastw != wid || lasth != hei) if (lastw != wid || lasth != hei) buffer = QPixmap();
buffer = QPixmap();
} }
if (buffer.isNull()) { if (buffer.isNull()) {
#if QT_VERSION_MAJOR >= 5 #if QT_VERSION_MAJOR >= 5
@@ -452,13 +450,14 @@ void Graphic::canvasPaintEvent() {
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y())); painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
emit beforeGraphicPaintEvent(painter); emit beforeGraphicPaintEvent(painter);
painter->setClipping(false); painter->setClipping(false);
if (grid) if (grid) drawGrid();
drawGrid();
p.setRenderHint(QPainter::Antialiasing, aalias); p.setRenderHint(QPainter::Antialiasing, aalias);
#ifdef HAS_GL #ifdef HAS_GL
if (isOGL && !m_fakeGL) { if (isOGL && !m_fakeGL) {
if (aalias) glEnable(GL_MULTISAMPLE); if (aalias)
else glDisable(GL_MULTISAMPLE); glEnable(GL_MULTISAMPLE);
else
glDisable(GL_MULTISAMPLE);
} }
#endif #endif
fp_size.clear(); fp_size.clear();
@@ -491,34 +490,30 @@ void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
if (gestures) { if (gestures) {
if (!need_mouse_pan) return; if (!need_mouse_pan) return;
curaction = gaMove; curaction = gaMove;
} else } else if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton)
if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton) return; return;
switch (curaction) { switch (curaction) {
case gaZoomInRect: case gaZoomInRect:
ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " + ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " + pointCoords(curpos_r) + ", " + tr("Size") + ": " +
pointCoords(curpos_r) + ", " + tr("Size") + ": " + pointCoords(absPoint(curpos_r - startpos_r))); pointCoords(absPoint(curpos_r - startpos_r)));
repaintCanvas(true); repaintCanvas(true);
break; break;
case gaZoomRangeX: case gaZoomRangeX:
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) + ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) + " -> " + QString::number(curpos_r.x(), 'f', 3) +
" -> " + QString::number(curpos_r.x(), 'f', 3) + ", " + tr("Length") + ": " + ", " + tr("Length") + ": " + QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
repaintCanvas(true); repaintCanvas(true);
break; break;
case gaZoomRangeY: case gaZoomRangeY:
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) + ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) + " -> " + QString::number(curpos_r.y(), 'f', 3) +
" -> " + QString::number(curpos_r.y(), 'f', 3) + ", " + tr("Length") + ": " + ", " + tr("Length") + ": " + QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
repaintCanvas(true); repaintCanvas(true);
break; break;
case gaMove: case gaMove:
dp = e->pos() - prevpos; dp = e->pos() - prevpos;
dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw); dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw);
dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5); dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5);
if (e->modifiers() == Qt::ControlModifier) if (e->modifiers() == Qt::ControlModifier) dp.setY(0.);
dp.setY(0.); if (e->modifiers() == Qt::ShiftModifier) dp.setX(0.);
if (e->modifiers() == Qt::ShiftModifier)
dp.setX(0.);
selrect.translate(dp); selrect.translate(dp);
totalUpdate(); totalUpdate();
break; break;
@@ -553,15 +548,16 @@ void Graphic::canvasMousePressEvent(QMouseEvent * e) {
} }
} }
if (e->button() == Qt::LeftButton) { if (e->button() == Qt::LeftButton) {
if (e->modifiers() == Qt::ControlModifier) curaction = gaZoomRangeX; if (e->modifiers() == Qt::ControlModifier)
else if (e->modifiers() == Qt::ShiftModifier) curaction = gaZoomRangeY; curaction = gaZoomRangeX;
else curaction = gaZoomInRect; else if (e->modifiers() == Qt::ShiftModifier)
curaction = gaZoomRangeY;
else
curaction = gaZoomInRect;
switch (curaction) { switch (curaction) {
case gaZoomInRect: case gaZoomInRect:
case gaZoomRangeX: case gaZoomRangeX:
case gaZoomRangeY: case gaZoomRangeY: swapToBuffer(); break;
swapToBuffer();
break;
default: break; default: break;
} }
} }
@@ -641,11 +637,15 @@ void Graphic::canvasWheelEvent(QWheelEvent * e) {
void Graphic::zoom(float factor) { void Graphic::zoom(float factor) {
double wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top(); double wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(),
hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
double px = wid / 2, py = hei / 2; double px = wid / 2, py = hei / 2;
px = px / wid * selrect.width() + selrect.x(); px = px / wid * selrect.width() + selrect.x();
py = py / hei * selrect.height() + selrect.y(); py = py / hei * selrect.height() + selrect.y();
selrect.setRect(px - (px - selrect.x()) * factor, py - (py - selrect.y()) * factor, selrect.width() * factor, selrect.height() * factor); selrect.setRect(px - (px - selrect.x()) * factor,
py - (py - selrect.y()) * factor,
selrect.width() * factor,
selrect.height() * factor);
isFit = false; isFit = false;
update(true); update(true);
setRectToLines(); setRectToLines();
@@ -653,8 +653,10 @@ void Graphic::zoom(float factor) {
void Graphic::fullscreen() { void Graphic::fullscreen() {
if (fullscr) leaveFullscreen(); if (fullscr)
else enterFullscreen(); leaveFullscreen();
else
enterFullscreen();
} }
@@ -870,7 +872,8 @@ void Graphic::addPoints(const QPolygonF & pts, int graphic, bool update_) {
} }
} }
if (t.polyline.size() == 0) t.max_x = pts.at(0).x(); if (t.polyline.size() == 0) t.max_x = pts.at(0).x();
for(const QPointF & p : pts) if (t.max_x < p.x()) t.max_x = p.x(); for (const QPointF & p: pts)
if (t.max_x < p.x()) t.max_x = p.x();
t.polyline << pts; t.polyline << pts;
tick(graphic, true, update_); tick(graphic, true, update_);
} }
@@ -881,7 +884,8 @@ void Graphic::addPoints(const QVector<double> & pts, int graphic, bool update_)
ps.reserve(pts.size()); ps.reserve(pts.size());
double stx = 0; double stx = 0;
if (!graphics[curGraphic].polyline.isEmpty()) stx = graphics[curGraphic].max_x; if (!graphics[curGraphic].polyline.isEmpty()) stx = graphics[curGraphic].max_x;
for (int i=0; i<pts.size(); ++i) ps << QPointF(stx + i*inc_x, pts[i]); for (int i = 0; i < pts.size(); ++i)
ps << QPointF(stx + i * inc_x, pts[i]);
addPoints(ps, graphic, update_); addPoints(ps, graphic, update_);
} }
@@ -899,13 +903,17 @@ void Graphic::setGraphicData(const QVector<QPointF> & g, int graphic, bool updat
} }
t.max_x = t.polyline[0].x(); t.max_x = t.polyline[0].x();
for (int i = 1; i < t.polyline.size(); ++i) for (int i = 1; i < t.polyline.size(); ++i)
if (t.max_x < t.polyline[i].x()) if (t.max_x < t.polyline[i].x()) t.max_x = t.polyline[i].x();
t.max_x = t.polyline[i].x();
tick(graphic, false, update_); tick(graphic, false, update_);
} }
void Graphic::setGraphicProperties(int graphic, const QString & name, const QColor& color, Qt::PenStyle style, double width, bool visible) { void Graphic::setGraphicProperties(int graphic,
const QString & name,
const QColor & color,
Qt::PenStyle style,
double width,
bool visible) {
if (graphic < 0 || graphic >= graphics.size()) return; if (graphic < 0 || graphic >= graphics.size()) return;
graphics[graphic].name = name; graphics[graphic].name = name;
graphics[graphic].pen.setColor(color); graphics[graphic].pen.setColor(color);
@@ -991,8 +999,7 @@ void Graphic::exportGraphics(QString filename, QChar decimal_point) {
} }
++ind; ++ind;
line += "\n"; line += "\n";
if (has_data) if (has_data) ts << line;
ts << line;
} }
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
} }
@@ -1020,8 +1027,7 @@ void Graphic::setOpenGL(bool on) {
canvas = canvas_gl; canvas = canvas_gl;
} }
} else { } else {
if (canvas_gl) if (canvas_gl) canvas_gl->hide();
canvas_gl->hide();
ui->canvas_raster->show(); ui->canvas_raster->show();
canvas = ui->canvas_raster; canvas = ui->canvas_raster;
} }
@@ -1043,7 +1049,9 @@ void Graphic::setGraphicsCount(int arg, bool update) {
if (arg < 0) return; if (arg < 0) return;
while (graphics.size() < arg) { while (graphics.size() < arg) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115))); graphics.append(
GraphicType(tr("y(x)"),
QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115)));
#else #else
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115))); graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115)));
#endif #endif
@@ -1130,8 +1138,14 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
if (maxY < limit_.top()) maxY = limit_.top(); if (maxY < limit_.top()) maxY = limit_.top();
if (minX > maxX) qSwap<double>(minX, maxX); if (minX > maxX) qSwap<double>(minX, maxX);
if (minY > maxY) qSwap<double>(minY, maxY); if (minY > maxY) qSwap<double>(minY, maxY);
if (qAbs<double>(minX - maxX) < 1E-60) {minX -= defaultRect().width()/2; maxX += defaultRect().width()/2;} if (qAbs<double>(minX - maxX) < 1E-60) {
if (qAbs<double>(minY - maxY) < 1E-60) {minY -= defaultRect().height()/2; maxY += defaultRect().height()/2;} minX -= defaultRect().width() / 2;
maxX += defaultRect().width() / 2;
}
if (qAbs<double>(minY - maxY) < 1E-60) {
minY -= defaultRect().height() / 2;
maxY += defaultRect().height() / 2;
}
if (only_expand_x) { if (only_expand_x) {
if (minX > eminx) minX = eminx; if (minX > eminx) minX = eminx;
if (maxX < emaxx) maxX = emaxx; if (maxX < emaxx) maxX = emaxx;
@@ -1140,16 +1154,20 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
if (minY > eminy) minY = eminy; if (minY > eminy) minY = eminy;
if (maxY < emaxy) maxY = emaxy; if (maxY < emaxy) maxY = emaxy;
} }
eminx = minX; emaxx = maxX; eminx = minX;
eminy = minY; emaxy = maxY; emaxx = maxX;
if (isRangeX) selrect.setRect(start_x, minY, end_x - start_x, maxY - minY); eminy = minY;
else if (isRangeY) selrect.setRect(minX, start_y, maxX - minX, end_y - start_y); emaxy = maxY;
else grect.setRect(minX, minY, maxX - minX, maxY - minY); if (isRangeX)
selrect.setRect(start_x, minY, end_x - start_x, maxY - minY);
else if (isRangeY)
selrect.setRect(minX, start_y, maxX - minX, end_y - start_y);
else
grect.setRect(minX, minY, maxX - minX, maxY - minY);
grect = grect.normalized(); grect = grect.normalized();
if (isFit) { if (isFit) {
if (visible_time > 0.) { if (visible_time > 0.) {
if (grect.width() > visible_time) if (grect.width() > visible_time) grect.setLeft(grect.right() - visible_time);
grect.setLeft(grect.right() - visible_time);
} }
selrect = grect; selrect = grect;
} }
@@ -1158,7 +1176,8 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
void Graphic::drawAction() { void Graphic::drawAction() {
int wid = canvas->width(), hei = canvas->height() - gridborder.y(), sx = startpos.x(), sy = startpos.y(), cx = curpos.x(), cy = curpos.y(); int wid = canvas->width(), hei = canvas->height() - gridborder.y(), sx = startpos.x(), sy = startpos.y(), cx = curpos.x(),
cy = curpos.y();
painter->setPen(selpen); painter->setPen(selpen);
painter->setBrush(selbrush); painter->setBrush(selbrush);
switch (curaction) { switch (curaction) {
@@ -1192,8 +1211,10 @@ void Graphic::drawGrid() {
QPair<QString, QString> str; QPair<QString, QString> str;
range = selrect.bottom() - selrect.top(); range = selrect.bottom() - selrect.top();
if (grad_y == Graphic::Auto) step = splitRange(range, hei / gridy / font_sz.height() / 1.4); if (grad_y == Graphic::Auto)
else step = gridy; step = splitRange(range, hei / gridy / font_sz.height() / 1.4);
else
step = gridy;
start = roundTo(canvas2realY(-hei), step) - step; start = roundTo(canvas2realY(-hei), step) - step;
py = start + step; py = start + step;
cy = 0; cy = 0;
@@ -1257,8 +1278,10 @@ void Graphic::drawGrid() {
range = selrect.right() - selrect.left(); range = selrect.right() - selrect.left();
QString df; QString df;
if (axis_type_x == Graphic::Numeric) { if (axis_type_x == Graphic::Numeric) {
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4); if (grad_x == Graphic::Auto)
else step = gridx; step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
else
step = gridx;
start = roundTo(canvas2realX(right), step); start = roundTo(canvas2realX(right), step);
px = start + step; px = start + step;
if (step > 0.) { if (step > 0.) {
@@ -1300,10 +1323,12 @@ void Graphic::drawGrid() {
} else { } else {
int dt_add[DateComponentCount]; int dt_add[DateComponentCount];
int dt_add_lo[DateComponentCount]; int dt_add_lo[DateComponentCount];
for (int i = 0; i < DateComponentCount; ++i) dt_add_lo[i] = dt_add[i] = 0; for (int i = 0; i < DateComponentCount; ++i)
dt_add_lo[i] = dt_add[i] = 0;
DateFormats formats; DateFormats formats;
step = splitRangeDate(range, wid / gridx / font_sz.width() / 1.5, formats, dt_add); step = splitRangeDate(range, wid / gridx / font_sz.width() / 1.5, formats, dt_add);
for (int i = 0; i < DateComponentCount - 1; ++i) dt_add_lo[i + 1] = dt_add[i]; for (int i = 0; i < DateComponentCount - 1; ++i)
dt_add_lo[i + 1] = dt_add[i];
bool is_years = formats.center.isEmpty(); bool is_years = formats.center.isEmpty();
if (step > 0.) { if (step > 0.) {
int up_y = cy - font_sz.height() * 2; int up_y = cy - font_sz.height() * 2;
@@ -1372,10 +1397,8 @@ void Graphic::drawGrid() {
} }
} }
if (!is_years) { if (!is_years) {
if (area_start < right) if (area_start < right) areas_ce << Anchor{area_start, right, cdc};
areas_ce << Anchor{area_start, right, cdc}; if (area_start_lo < right) areas_lo << Anchor{area_start_lo, right, cdl};
if (area_start_lo < right)
areas_lo << Anchor{area_start_lo, right, cdl};
// qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date; // qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date;
painter->setPen(grid_pen); painter->setPen(grid_pen);
for (const auto & a: areas_ce) { for (const auto & a: areas_ce) {
@@ -1455,8 +1478,7 @@ void Graphic::fillDateFormats() {
void Graphic::drawGraphics() { void Graphic::drawGraphics() {
if (isHover) if (isHover) ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
QPointF srp = -selrect.topLeft(); QPointF srp = -selrect.topLeft();
double sclx, scly, wid = canvas->width(), hei = canvas->height(); double sclx, scly, wid = canvas->width(), hei = canvas->height();
int cwid = (wid - gridborder.x() - margins_.left() - margins_.width()); int cwid = (wid - gridborder.x() - margins_.left() - margins_.width());
@@ -1489,12 +1511,12 @@ void Graphic::drawGraphics() {
int ind_start = -1, ind_end = -1; int ind_start = -1, ind_end = -1;
if (m_LODOptimization) { if (m_LODOptimization) {
qreal xs = selrect.left(), xe = selrect.right(), _offset = 2. / cwid * selrect.width(); qreal xs = selrect.left(), xe = selrect.right(), _offset = 2. / cwid * selrect.width();
xs -= _offset; xe += _offset; xs -= _offset;
xe += _offset;
for (int i = 0; i < rpol.size(); ++i) { for (int i = 0; i < rpol.size(); ++i) {
qreal px = rpol[i].x(); qreal px = rpol[i].x();
if (px < xs) continue; if (px < xs) continue;
if (ind_start < 0) if (ind_start < 0) ind_start = qMax(0, i - 1);
ind_start = qMax(0, i - 1);
if (px > xe && ind_end < 0) { if (px > xe && ind_end < 0) {
ind_end = qMin(rpol.size(), i + 1); ind_end = qMin(rpol.size(), i + 1);
break; break;
@@ -1518,8 +1540,10 @@ void Graphic::drawGraphics() {
cpol = rpol; cpol = rpol;
} }
pen = t.pen; pen = t.pen;
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick); if (qRound(pen.widthF()) == pen.widthF())
else pen.setWidthF(pen.widthF()*thick); pen.setWidth(pen.width() * thick);
else
pen.setWidthF(pen.widthF() * thick);
pen.setCosmetic(true); pen.setCosmetic(true);
if (t.lines) { if (t.lines) {
painter->setPen(pen); painter->setPen(pen);
@@ -1530,8 +1554,10 @@ void Graphic::drawGraphics() {
painter->drawPolyline(mat.map(cpol)); painter->drawPolyline(mat.map(cpol));
} }
if (t.points) { if (t.points) {
if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick)); if (qRound(t.pointWidth) == t.pointWidth)
else pen.setWidthF(t.pointWidth*thick); pen.setWidth(qRound(t.pointWidth * thick));
else
pen.setWidthF(t.pointWidth * thick);
painter->setPen(pen); painter->setPen(pen);
painter->drawPoints(mat.map(cpol)); painter->drawPoints(mat.map(cpol));
} }
@@ -1642,19 +1668,12 @@ void Graphic::drawGuides() {
} }
}; };
switch (floating_axis_type) { switch (floating_axis_type) {
case TraceXY: case TraceXY: trace_free_func(rpos); break;
trace_free_func(rpos); case TraceX: trace_axis_func(true, rpos.x()); break;
break; case TraceY: trace_axis_func(false, rpos.y()); break;
case TraceX:
trace_axis_func(true, rpos.x());
break;
case TraceY:
trace_axis_func(false, rpos.y());
break;
default: break; default: break;
} }
if (was_trace && !trace_found) if (was_trace && !trace_found) emit graphicTraceEvent(-1, QPointF());
emit graphicTraceEvent(-1, QPointF());
was_trace = trace_found; was_trace = trace_found;
painter->drawLine(0, apos.y(), wid, apos.y()); painter->drawLine(0, apos.y(), wid, apos.y());
painter->drawLine(apos.x(), 0, apos.x(), hei); painter->drawLine(apos.x(), 0, apos.x(), hei);
@@ -1733,22 +1752,32 @@ double Graphic::splitRange(double range, int count) {
double Graphic::splitRangeDate(double range, int count, DateFormats & formats, int step[7]) { double Graphic::splitRangeDate(double range, int count, DateFormats & formats, int step[7]) {
static const qint64 static const qint64 to_sec = 1000LL, to_min = 1000LL * 60, to_hour = 1000LL * 60 * 60, to_day = 1000LL * 60 * 60 * 24,
to_sec = 1000LL, to_month = 1000LL * 60 * 60 * 24 * 30, to_year = 1000LL * 60 * 60 * 24 * 30 * 12;
to_min = 1000LL * 60,
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); double ret = splitRange(range, count);
int format_index = DateYears; int format_index = DateYears;
if (ret < to_sec / 1 ) {format_index = DateMSecs ; step[DateMSecs ] = qRound64(ret);} if (ret < to_sec / 1) {
else if (ret < to_min / 2 ) {format_index = DateSecs ; step[DateSecs ] = roundToNearest(ret / to_sec , {1, 2, 5, 10, 15, 20, 30});} format_index = DateMSecs;
else if (ret < to_hour ) {format_index = DateMinutes; step[DateMinutes] = roundToNearest(ret / to_min , {1, 2, 5, 10, 15, 20, 30});} step[DateMSecs] = qRound64(ret);
else if (ret < to_day ) {format_index = DateHours ; step[DateHours ] = roundToNearest(ret / to_hour , {1, 2, 3, 4, 6, 8, 12});} } else if (ret < to_min / 2) {
else if (ret < to_month / 1.6) {format_index = DateDays ; step[DateDays ] = roundToNearest(ret / to_day , {1, 2, 5, 10});} format_index = DateSecs;
else if (ret < to_year ) {format_index = DateMonths ; step[DateMonths ] = roundToNearest(ret / to_month, {1, 2, 3, 4, 6});} step[DateSecs] = roundToNearest(ret / to_sec, {1, 2, 5, 10, 15, 20, 30});
else {format_index = DateYears ; step[DateYears ] = qRound64(ret / to_year);} } else if (ret < to_hour) {
format_index = DateMinutes;
step[DateMinutes] = roundToNearest(ret / to_min, {1, 2, 5, 10, 15, 20, 30});
} else if (ret < to_day) {
format_index = DateHours;
step[DateHours] = roundToNearest(ret / to_hour, {1, 2, 3, 4, 6, 8, 12});
} else if (ret < to_month / 1.6) {
format_index = DateDays;
step[DateDays] = roundToNearest(ret / to_day, {1, 2, 5, 10});
} else if (ret < to_year) {
format_index = DateMonths;
step[DateMonths] = roundToNearest(ret / to_month, {1, 2, 3, 4, 6});
} else {
format_index = DateYears;
step[DateYears] = qRound64(ret / to_year);
}
formats = date_formats[format_index]; formats = date_formats[format_index];
return ret; return ret;
} }
@@ -1761,13 +1790,23 @@ double Graphic::roundTo(double value, double round_to) {
void Graphic::roundDateTime(QDateTime & dt, int * c) { void Graphic::roundDateTime(QDateTime & dt, int * c) {
QDate d(dt.date()); QTime t(dt.time()); QDate d(dt.date());
QTime t(dt.time());
if (c[DateMSecs] != 0) t.setHMS(t.hour(), t.minute(), t.second()); 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[DateSecs] != 0) t.setHMS(t.hour(), t.minute(), 0);
if (c[DateMinutes] != 0) t.setHMS(t.hour(), 0, 0); if (c[DateMinutes] != 0) t.setHMS(t.hour(), 0, 0);
if (c[DateHours ] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), d.day());} if (c[DateHours] != 0) {
if (c[DateDays ] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), 1);} t.setHMS(0, 0, 0);
if (c[DateMonths ] != 0 || c[DateYears] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), 1, 1);} d.setDate(d.year(), d.month(), d.day());
}
if (c[DateDays] != 0) {
t.setHMS(0, 0, 0);
d.setDate(d.year(), d.month(), 1);
}
if (c[DateMonths] != 0 || c[DateYears] != 0) {
t.setHMS(0, 0, 0);
d.setDate(d.year(), 1, 1);
}
dt = QDateTime(d, t); dt = QDateTime(d, t);
} }
@@ -1830,21 +1869,11 @@ QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
void Graphic::setCurrentAction(GraphicAction action) { void Graphic::setCurrentAction(GraphicAction action) {
curaction = action; curaction = action;
switch (action) { switch (action) {
case gaNone: case gaNone: setGuidesCursor(); break;
setGuidesCursor(); case gaZoomInRect: setCanvasCursor(Qt::CrossCursor); break;
break; case gaZoomRangeX: setCanvasCursor(Qt::SplitHCursor); break;
case gaZoomInRect: case gaZoomRangeY: setCanvasCursor(Qt::SplitVCursor); break;
setCanvasCursor(Qt::CrossCursor); case gaMove: setCanvasCursor(Qt::SizeAllCursor); break;
break;
case gaZoomRangeX:
setCanvasCursor(Qt::SplitHCursor);
break;
case gaZoomRangeY:
setCanvasCursor(Qt::SplitVCursor);
break;
case gaMove:
setCanvasCursor(Qt::SizeAllCursor);
break;
} }
} }
@@ -1852,8 +1881,7 @@ void Graphic::setCurrentAction(GraphicAction action) {
void Graphic::setCanvasCursor(QCursor cursor) { void Graphic::setCanvasCursor(QCursor cursor) {
ui->canvas_raster->setCursor(cursor); ui->canvas_raster->setCursor(cursor);
#ifdef HAS_GL #ifdef HAS_GL
if (canvas_gl) if (canvas_gl) canvas_gl->setCursor(cursor);
canvas_gl->setCursor(cursor);
#endif #endif
} }
@@ -1883,28 +1911,42 @@ void Graphic::swapToBuffer() {
void Graphic::setRectToLines() { void Graphic::setRectToLines() {
is_lines_update = true; is_lines_update = true;
if (line_x_min.isVisible() && line_x_max.isVisible() && line_y_min.isVisible() && line_y_max.isVisible()) { if (line_x_min.isVisible() && line_x_max.isVisible() && line_y_min.isVisible() && line_y_max.isVisible()) {
line_x_min.blockSignals(true); line_x_max.blockSignals(true); line_y_min.blockSignals(true); line_y_max.blockSignals(true); line_x_min.blockSignals(true);
line_x_max.blockSignals(true);
line_y_min.blockSignals(true);
line_y_max.blockSignals(true);
if (!line_x_min.hasFocus()) { if (!line_x_min.hasFocus()) {
if (isFit) line_x_min.setValue(grect.left()); if (isFit)
else line_x_min.setValue(selrect.left()); line_x_min.setValue(grect.left());
else
line_x_min.setValue(selrect.left());
} }
if (!line_x_max.hasFocus()) { if (!line_x_max.hasFocus()) {
if(isFit) line_x_max.setValue(grect.right()); if (isFit)
else line_x_max.setValue(selrect.right()); line_x_max.setValue(grect.right());
else
line_x_max.setValue(selrect.right());
} }
if (!line_y_min.hasFocus()) { if (!line_y_min.hasFocus()) {
if(isFit) line_y_min.setValue(grect.bottom()); if (isFit)
else line_y_min.setValue(selrect.bottom()); line_y_min.setValue(grect.bottom());
else
line_y_min.setValue(selrect.bottom());
} }
if (!line_y_max.hasFocus()) { if (!line_y_max.hasFocus()) {
if(isFit) line_y_max.setValue(grect.top()); if (isFit)
else line_y_max.setValue(selrect.top()); line_y_max.setValue(grect.top());
else
line_y_max.setValue(selrect.top());
} }
line_x_min.setDefaultText(QString::number(grect.left()).toUpper()); line_x_min.setDefaultText(QString::number(grect.left()).toUpper());
line_x_max.setDefaultText(QString::number(grect.right()).toUpper()); line_x_max.setDefaultText(QString::number(grect.right()).toUpper());
line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper()); line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper());
line_y_max.setDefaultText(QString::number(grect.top()).toUpper()); line_y_max.setDefaultText(QString::number(grect.top()).toUpper());
line_x_min.blockSignals(false); line_x_max.blockSignals(false); line_y_min.blockSignals(false); line_y_max.blockSignals(false); line_x_min.blockSignals(false);
line_x_max.blockSignals(false);
line_y_min.blockSignals(false);
line_y_max.blockSignals(false);
} }
is_lines_update = false; is_lines_update = false;
} }
@@ -1925,10 +1967,8 @@ void Graphic::tick(int index, bool slide, bool update_) {
/// TODO: [Graphic] fast autofit while addPoint(double y, ...) /// TODO: [Graphic] fast autofit while addPoint(double y, ...)
if (!t.cvrect.isNull()) { if (!t.cvrect.isNull()) {
QPointF fp(t.polyline.first()); QPointF fp(t.polyline.first());
if (qFuzzyCompare(t.cvrect.left(), fp.x()) || if (qFuzzyCompare(t.cvrect.left(), fp.x()) || qFuzzyCompare(t.cvrect.right(), fp.x()) ||
qFuzzyCompare(t.cvrect.right(), fp.x()) || qFuzzyCompare(t.cvrect.top(), fp.y()) || qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
qFuzzyCompare(t.cvrect.top(), fp.y()) ||
qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
t.cvrect = QRectF(); t.cvrect = QRectF();
} }
} }
@@ -1968,10 +2008,13 @@ void Graphic::calcLOD(int index) {
for (int i = 0; i < qcnt; ++i) { for (int i = 0; i < qcnt; ++i) {
int j = i * 4 + 1; int j = i * 4 + 1;
if (i == qcnt - 1) pc = pl.size() - j - 1; if (i == qcnt - 1) pc = pl.size() - j - 1;
mx[0] = mx[1] = my_x[0] = my_x[1] = pl[j].x(); my[0] = my[1] = pl[j].y(); mx[0] = mx[1] = my_x[0] = my_x[1] = pl[j].x();
my[0] = my[1] = pl[j].y();
for (int k = 1; k < pc; ++k) { for (int k = 1; k < pc; ++k) {
px = pl[j + k].x(); py = pl[j + k].y(); px = pl[j + k].x();
mx[0] = qMin(mx[0], px); mx[1] = qMax(mx[1], px); py = pl[j + k].y();
mx[0] = qMin(mx[0], px);
mx[1] = qMax(mx[1], px);
if (my[0] > py) { if (my[0] > py) {
my[0] = py; my[0] = py;
my_x[0] = px; my_x[0] = px;
@@ -2055,14 +2098,20 @@ void Graphic::on_graphic_buttonConfigure_clicked() {
setBorderInputsVisible(conf->ui->checkInputs->isChecked()); setBorderInputsVisible(conf->ui->checkInputs->isChecked());
setStatusVisible(conf->ui->checkStatus->isChecked()); setStatusVisible(conf->ui->checkStatus->isChecked());
setLegendVisible(conf->ui->checkLegend->isChecked()); setLegendVisible(conf->ui->checkLegend->isChecked());
setMargins(conf->ui->spinMarginL->value(), conf->ui->spinMarginR->value(), conf->ui->spinMarginT->value(), conf->ui->spinMarginB->value()); setMargins(conf->ui->spinMarginL->value(),
conf->ui->spinMarginR->value(),
conf->ui->spinMarginT->value(),
conf->ui->spinMarginB->value());
updateLegend(); updateLegend();
update(); update();
} }
void Graphic::on_graphic_buttonSave_clicked() { void Graphic::on_graphic_buttonSave_clicked() {
QString f = QFileDialog::getSaveFileName(this, tr("Save Image"), ppath, "PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)"); QString f = QFileDialog::getSaveFileName(this,
tr("Save Image"),
ppath,
"PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)");
if (f.isEmpty()) return; if (f.isEmpty()) return;
saveImage(f); saveImage(f);
} }
@@ -2072,7 +2121,8 @@ void Graphic::on_graphic_buttonExport_clicked() {
QString f = QFileDialog::getSaveFileName(this, tr("Export graphics"), ppath, "CSV(*.csv)"); QString f = QFileDialog::getSaveFileName(this, tr("Export graphics"), ppath, "CSV(*.csv)");
if (f.isEmpty()) return; if (f.isEmpty()) return;
QStringList items; QStringList items;
items << "." << ","; items << "."
<< ",";
bool ok; bool ok;
QString item = QInputDialog::getItem(this, tr("Select decimal point"), tr("Decimal point:"), items, 0, false, &ok); QString item = QInputDialog::getItem(this, tr("Select decimal point"), tr("Decimal point:"), items, 0, false, &ok);
if (ok && !item.isEmpty()) exportGraphics(f, item.front()); if (ok && !item.isEmpty()) exportGraphics(f, item.front());
@@ -2092,7 +2142,9 @@ void Graphic::on_graphic_buttonRecord_clicked(bool checked) {
qApp->setOverrideCursor(Qt::BusyCursor); qApp->setOverrideCursor(Qt::BusyCursor);
GifWriter gif_writer; GifWriter gif_writer;
int frame_delay = 10; int frame_delay = 10;
if (GifBegin(&gif_writer, f.toUtf8(), static_cast<uint32_t>(record_imgs.first().width()), if (GifBegin(&gif_writer,
f.toUtf8(),
static_cast<uint32_t>(record_imgs.first().width()),
static_cast<uint32_t>(record_imgs.first().height()), static_cast<uint32_t>(record_imgs.first().height()),
static_cast<uint32_t>(frame_delay))) { static_cast<uint32_t>(frame_delay))) {
for (const QImage & im: record_imgs) { for (const QImage & im: record_imgs) {
@@ -2127,8 +2179,10 @@ void Graphic::updateLegend(bool es) {
pix.fill(back_color); pix.fill(back_color);
QPainter p(&pix); QPainter p(&pix);
QPen pen = graphics[i].pen; QPen pen = graphics[i].pen;
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick); if (qRound(pen.widthF()) == pen.widthF())
else pen.setWidthF(pen.widthF()*thick); pen.setWidth(pen.width() * thick);
else
pen.setWidthF(pen.widthF() * thick);
p.setPen(pen); p.setPen(pen);
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2); p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
p.end(); p.end();
@@ -2188,7 +2242,10 @@ void Graphic::updateLegend(bool es) {
#endif*/ #endif*/
} }
col++; col++;
if (col > maxcol) {col = 0; row++;} if (col > maxcol) {
col = 0;
row++;
}
} }
ui->gridLayout->invalidate(); ui->gridLayout->invalidate();
ui->scrollLegend->setVisible(lv); ui->scrollLegend->setVisible(lv);
@@ -2215,8 +2272,11 @@ void Graphic::graphicVisibleChange(bool checked) {
QCheckBox * cb = qobject_cast<QCheckBox *>(sender()); QCheckBox * cb = qobject_cast<QCheckBox *>(sender());
int i = cb->property("graphic_num").toInt(); int i = cb->property("graphic_num").toInt();
graphics[i].visible = checked; graphics[i].visible = checked;
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit)
else {update();} on_graphic_buttonAutofit_clicked();
else {
update();
}
emit graphicSettingsChanged(); emit graphicSettingsChanged();
} }
@@ -2228,8 +2288,11 @@ void Graphic::graphicAllVisibleChange(bool checked) {
graphics[i].pb->setChecked(checked); graphics[i].pb->setChecked(checked);
} }
visible_update = false; visible_update = false;
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit)
else {update();} on_graphic_buttonAutofit_clicked();
else {
update();
}
emit graphicSettingsChanged(); emit graphicSettingsChanged();
} }
@@ -2332,8 +2395,7 @@ QByteArray Graphic::save() {
cs.add(9, gridPen()).add(10, graduationX()).add(11, graduationY()).add(12, graduationStepX()).add(13, graduationStepY()); cs.add(9, gridPen()).add(10, graduationX()).add(11, graduationY()).add(12, graduationStepX()).add(13, graduationStepY());
cs.add(14, graphics); cs.add(14, graphics);
cs.add(15, isFit).add(16, visualRect()); cs.add(15, isFit).add(16, visualRect());
if (backgroundColor() == palette().color(QPalette::Base) && if (backgroundColor() == palette().color(QPalette::Base) && textColor() == palette().color(QPalette::WindowText) &&
textColor() == palette().color(QPalette::WindowText) &&
gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText)) gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText))
cs.add(17, true); cs.add(17, true);
return cs.data().prepend('2'); return cs.data().prepend('2');
@@ -2356,10 +2418,16 @@ void Graphic::load(QByteArray ba) {
case 3: setBorderInputsVisible(cs.getData<bool>()); break; case 3: setBorderInputsVisible(cs.getData<bool>()); break;
case 4: setStatusVisible(cs.getData<bool>()); break; case 4: setStatusVisible(cs.getData<bool>()); break;
case 5: setLegendVisible(cs.getData<bool>()); break; case 5: setLegendVisible(cs.getData<bool>()); break;
case 6: if (!def_colors) setBackgroundColor(cs.getData<QColor>()); break; case 6:
case 7: if (!def_colors) setTextColor(cs.getData<QColor>()); break; if (!def_colors) setBackgroundColor(cs.getData<QColor>());
break;
case 7:
if (!def_colors) setTextColor(cs.getData<QColor>());
break;
case 8: setMargins(cs.getData<QRect>()); break; case 8: setMargins(cs.getData<QRect>()); break;
case 9: if (!def_colors) setGridPen(cs.getData<QPen>()); break; case 9:
if (!def_colors) setGridPen(cs.getData<QPen>());
break;
case 10: setGraduationX(cs.getData<Graduation>()); break; case 10: setGraduationX(cs.getData<Graduation>()); break;
case 11: setGraduationY(cs.getData<Graduation>()); break; case 11: setGraduationY(cs.getData<Graduation>()); break;
case 12: setGraduationStepX(cs.getData<double>()); break; case 12: setGraduationStepX(cs.getData<double>()); break;
@@ -2367,12 +2435,14 @@ void Graphic::load(QByteArray ba) {
case 14: graphics = cs.getData<QVector<GraphicType>>(); break; case 14: graphics = cs.getData<QVector<GraphicType>>(); break;
case 15: isFit = cs.getData<bool>(); break; case 15: isFit = cs.getData<bool>(); break;
case 16: vrect = cs.getData<QRectF>(); break; case 16: vrect = cs.getData<QRectF>(); break;
case 17: if(cs.getData<bool>()) { case 17:
if (cs.getData<bool>()) {
setTextColor(palette().color(QPalette::WindowText)); setTextColor(palette().color(QPalette::WindowText));
setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine)); setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine));
setBackgroundColor(palette().color(QPalette::Base)); setBackgroundColor(palette().color(QPalette::Base));
def_colors = true; def_colors = true;
} break; }
break;
default: break; default: break;
} }
} }
@@ -2381,10 +2451,14 @@ void Graphic::load(QByteArray ba) {
default: { // old version 0: default: { // old version 0:
QDataStream s(ba); QDataStream s(ba);
bool a; bool a;
s >> a; setOpenGL(a); s >> a;
s >> a; setAntialiasing(a); setOpenGL(a);
s >> a; setBorderInputsVisible(a); s >> a;
s >> a; setStatusVisible(a); setAntialiasing(a);
s >> a;
setBorderInputsVisible(a);
s >> a;
setStatusVisible(a);
s >> a; s >> a;
s >> graphics; s >> graphics;
setLegendVisible(a); setLegendVisible(a);
@@ -2403,7 +2477,8 @@ void Graphic::setCaption(const QString & str) {
void Graphic::setGraphicVisible(bool visible, int index) { void Graphic::setGraphicVisible(bool visible, int index) {
graphics[index].visible = visible; graphics[index].visible = visible;
updateLegendChecks(); updateLegendChecks();
if (isFit) on_graphic_buttonAutofit_clicked(); if (isFit)
on_graphic_buttonAutofit_clicked();
else if (aupdate) else if (aupdate)
update(); update();
} }

View File

@@ -20,23 +20,24 @@
#ifndef GRAPHIC_H #ifndef GRAPHIC_H
#define GRAPHIC_H #define GRAPHIC_H
#include <QWidget> #include "evalspinbox.h"
#include <QPainter> #include "graphic_conf.h"
#include <QPixmap> #include "qad_graphic_export.h"
#include <QMouseEvent>
#include <QComboBox> #include <QComboBox>
#include <QDebug> #include <QDebug>
#include <QGridLayout>
#include <QFileDialog>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QTranslator> #include <QFileDialog>
#include <QGestureEvent> #include <QGestureEvent>
#include <QGridLayout>
#include <QMenu> #include <QMenu>
#include <qmath.h> #include <QMouseEvent>
#include <QPainter>
#include <QPixmap>
#include <QTranslator>
#include <QWidget>
#include <float.h> #include <float.h>
#include "graphic_conf.h" #include <qmath.h>
#include "evalspinbox.h"
#include "qad_graphic_export.h"
namespace Ui { namespace Ui {
@@ -51,8 +52,7 @@ class GraphicPlugin;
Q_DECLARE_METATYPE(QVector<QPointF>) Q_DECLARE_METATYPE(QVector<QPointF>)
class QAD_GRAPHIC_EXPORT Graphic: public QFrame class QAD_GRAPHIC_EXPORT Graphic: public QFrame {
{
Q_OBJECT Q_OBJECT
Q_FLAGS(Buttons) Q_FLAGS(Buttons)
Q_ENUMS(Alignment Graduation AxisType FloatingAxisType) Q_ENUMS(Alignment Graduation AxisType FloatingAxisType)
@@ -128,8 +128,15 @@ public:
virtual ~Graphic(); virtual ~Graphic();
typedef QVector<QVector<QPointF>> GraphicsData; typedef QVector<QVector<QPointF>> GraphicsData;
enum GraphicAction {gaNone, gaZoomInRect, gaZoomRangeX, gaZoomRangeY, gaMove}; enum GraphicAction {
enum Button {NoButtons = 0x0, gaNone,
gaZoomInRect,
gaZoomRangeX,
gaZoomRangeY,
gaMove
};
enum Button {
NoButtons = 0x0,
AllButtons = 0xFFFFFFFF, AllButtons = 0xFFFFFFFF,
Autofit = 0x01, Autofit = 0x01,
Grid = 0x02, Grid = 0x02,
@@ -146,10 +153,24 @@ public:
Record = 0x4000, Record = 0x4000,
StandartButtons = 0x2BFF StandartButtons = 0x2BFF
}; };
enum Alignment {Left, Right}; enum Alignment {
enum Graduation {Auto, Fixed}; Left,
enum AxisType {Numeric, DateTime}; Right
enum FloatingAxisType {Free, TraceXY, TraceX, TraceY}; };
enum Graduation {
Auto,
Fixed
};
enum AxisType {
Numeric,
DateTime
};
enum FloatingAxisType {
Free,
TraceXY,
TraceX,
TraceY
};
Q_DECLARE_FLAGS(Buttons, Button) Q_DECLARE_FLAGS(Buttons, Button)
QString caption() const; QString caption() const;
@@ -229,9 +250,15 @@ public:
QByteArray save(); QByteArray save();
void load(QByteArray ba); void load(QByteArray ba);
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];} GraphicType graphic(int arg) {
if (arg < 0 || arg >= graphics.size()) return GraphicType();
return graphics[arg];
}
const QVector<GraphicType> & allGraphics() const { return graphics; } const QVector<GraphicType> & allGraphics() const { return graphics; }
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();} void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {
graphics = g;
if (update) updateLegend();
}
double canvas2realX(double px) const; double canvas2realX(double px) const;
double canvas2realY(double py) const; double canvas2realY(double py) const;
@@ -247,37 +274,108 @@ public:
public slots: public slots:
void setCaption(const QString & str); void setCaption(const QString & str);
void setLabelX(const QString & str) {label_x = str; hasLblX = (str.length() > 0); if (aupdate) update();} void setLabelX(const QString & str) {
void setLabelY(const QString & str) {label_y = str; hasLblY = (str.length() > 0); if (aupdate) update();} label_x = str;
void setGraphicName(const QString & str, int index) {graphics[index].name = str; updateLegend(); if (aupdate) update();} hasLblX = (str.length() > 0);
void setGraphicName(const QString & str) {graphics[curGraphic].name = str; updateLegend(); if (aupdate) update();} if (aupdate) update();
void setBackgroundColor(const QColor & color) {back_color = color; if (aupdate) update(); updateLegend();} }
void setTextColor(const QColor & color) {text_color = color; if (aupdate) update();} void setLabelY(const QString & str) {
void setGraphicColor(const QColor & color, int index) {graphics[index].pen.setColor(color); updateLegend(); if (aupdate) update();} label_y = str;
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 setGraphicColor(const QColor & color) { setGraphicColor(color, curGraphic); }
void setGridColor(const QColor & color) {grid_pen.setColor(color); if (aupdate) update();} void setGridColor(const QColor & color) {
grid_pen.setColor(color);
if (aupdate) update();
}
void setSelectionColor(const QColor & color) { selpen.setColor(color); } 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, int index) {
graphics[index].pen.setStyle(style);
updateLegend();
if (aupdate) update();
}
void setGraphicStyle(const Qt::PenStyle & style) { setGraphicStyle(style, curGraphic); } void setGraphicStyle(const Qt::PenStyle & style) { setGraphicStyle(style, curGraphic); }
void setGridStyle(const Qt::PenStyle & style) {grid_pen.setStyle(style); if (aupdate) update();} void setGridStyle(const Qt::PenStyle & style) {
grid_pen.setStyle(style);
if (aupdate) update();
}
void setSelectionStyle(const Qt::PenStyle & style) { selpen.setStyle(style); } void setSelectionStyle(const Qt::PenStyle & style) { selpen.setStyle(style); }
void setGraphicVisible(bool visible, int index); void setGraphicVisible(bool visible, int index);
void setGraphicVisible(bool visible) { setGraphicVisible(visible, curGraphic); } void setGraphicVisible(bool visible) { setGraphicVisible(visible, curGraphic); }
void setGraphicLineWidth(double w, int index) {if (qRound(w) == w) graphics[index].pen.setWidth(qRound(w)); else graphics[index].pen.setWidthF(w); updateLegend(); if (aupdate) update();} void setGraphicLineWidth(double w, int index) {
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 setGraphicLineWidth(double w) { setGraphicLineWidth(w, curGraphic); }
void setGraphicPointWidth(double w, int index) {graphics[index].pointWidth = w; updateLegend(); if (aupdate) update();} void setGraphicPointWidth(double w, int index) {
graphics[index].pointWidth = w;
updateLegend();
if (aupdate) update();
}
void setGraphicPointWidth(double w) { setGraphicPointWidth(w, curGraphic); } 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, int index) {
graphics[index].fill_color = w;
updateLegend();
if (aupdate) update();
}
void setGraphicFillColor(const QColor & w) { setGraphicFillColor(w, curGraphic); } 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, int index) {
graphics[index].lines = w;
updateLegend();
if (aupdate) update();
}
void setGraphicLinesEnabled(bool w) { setGraphicLinesEnabled(w, curGraphic); } 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, int index) {
graphics[index].points = w;
updateLegend();
if (aupdate) update();
}
void setGraphicPointsEnabled(bool w) { setGraphicPointsEnabled(w, curGraphic); } 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, int index) {
graphics[index].fill = w;
updateLegend();
if (aupdate) update();
}
void setGraphicFillEnabled(bool w) { setGraphicFillEnabled(w, curGraphic); } 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, int index) {
graphics[index].pen = pen;
updateLegend();
if (aupdate) update();
}
void setGraphicPen(const QPen & pen) { setGraphicPen(pen, curGraphic); } void setGraphicPen(const QPen & pen) { setGraphicPen(pen, curGraphic); }
void setGridPen(const QPen & pen) {grid_pen = pen; if (aupdate) update();} void setGridPen(const QPen & pen) {
grid_pen = pen;
if (aupdate) update();
}
void setSelectionPen(const QPen & pen) { selpen = pen; } void setSelectionPen(const QPen & pen) { selpen = pen; }
void setSelectionBrush(const QBrush & brush) { selbrush = brush; } void setSelectionBrush(const QBrush & brush) { selbrush = brush; }
void setNavigationEnabled(bool on) { navigation = on; } void setNavigationEnabled(bool on) { navigation = on; }
@@ -296,12 +394,27 @@ public slots:
void setMaxVisibleTime(double val); void setMaxVisibleTime(double val);
void setAutoXIncrement(double val) { inc_x = val; } void setAutoXIncrement(double val) { inc_x = val; }
void setLimit(const QRectF & val) { limit_ = val; } void setLimit(const QRectF & val) { limit_ = val; }
void setMargins(const QRect & val) {margins_ = val; update();} void setMargins(const QRect & val) {
margins_ = val;
update();
}
void setMargins(int left_, int right_, int top_, int bottom_) { setMargins(QRect(left_, bottom_, right_, top_)); } 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 setLeftMargin(int value) {
void setRightMargin(int value) {margins_.setWidth(value); setMargins(margins_);} margins_.moveLeft(value);
void setTopMargin(int value) {margins_.setHeight(value); setMargins(margins_);} setMargins(margins_);
void setBottomMargin(int value) {margins_.moveTop(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 setMinimumRepaintInterval(const int & val) { min_repaint_int = val; }
void setOnlyExpandY(bool yes); void setOnlyExpandY(bool yes);
void setOnlyExpandX(bool yes); void setOnlyExpandX(bool yes);
@@ -309,33 +422,92 @@ public slots:
void setGraphicsData(const GraphicsData & gd); void setGraphicsData(const GraphicsData & gd);
void setGraphicsDataRaw(const QByteArray & ba); void setGraphicsDataRaw(const QByteArray & ba);
void setGridNumbersMultiplierX(double value) {grid_numbers_x = value; updateGraphics();} void setGridNumbersMultiplierX(double value) {
void setGridNumbersMultiplierY(double value) {grid_numbers_y = value; updateGraphics();} grid_numbers_x = value;
void setGraduationX(Graduation value) {grad_x = value; if (aupdate) update();;} updateGraphics();
void setGraduationY(Graduation value) {grad_y = value; if (aupdate) update();;} }
void setGraduationStepX(double sx) {gridx = sx; if (aupdate) update();} void setGridNumbersMultiplierY(double value) {
void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();} grid_numbers_y = value;
void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();} updateGraphics();
void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();} }
void setFloatingAxisType(FloatingAxisType t) {floating_axis_type = t; setGuidesCursor(); if (aupdate) update();} void setGraduationX(Graduation value) {
grad_x = value;
if (aupdate) update();
;
}
void setGraduationY(Graduation value) {
grad_y = value;
if (aupdate) update();
;
}
void setGraduationStepX(double sx) {
gridx = sx;
if (aupdate) update();
}
void setGraduationStepY(double sy) {
gridy = sy;
if (aupdate) update();
}
void setGraduationSteps(double sx, double sy) {
gridx = sx;
gridy = sy;
if (aupdate) update();
}
void setAxisType(AxisType t) {
axis_type_x = t;
if (aupdate) update();
}
void setFloatingAxisType(FloatingAxisType t) {
floating_axis_type = t;
setGuidesCursor();
if (aupdate) update();
}
void setFloatingAxisEnabled(bool on); void setFloatingAxisEnabled(bool on);
void addPoint(const QPointF & p, int graphic, bool update_ = true); void addPoint(const QPointF & p, int graphic, bool update_ = true);
void addPoint(const QPointF & p, bool update = true) { addPoint(p, curGraphic, update); } void addPoint(const QPointF & p, bool update = true) { addPoint(p, curGraphic, update); }
void addPoint(double x, double y, int graphic, bool update = true) { addPoint(QPointF(x, y), graphic, update); } void addPoint(double x, double y, int graphic, bool update = true) { addPoint(QPointF(x, y), graphic, update); }
void addPoint(double x, double y, bool update = true) { addPoint(QPointF(x, y), update); } void addPoint(double x, double y, bool update = true) { addPoint(QPointF(x, y), update); }
void addPoint(double y, int graphic, bool update = true) {if (graphics[graphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), graphic, update); else addPoint(QPointF(graphics[graphic].max_x + inc_x, y), graphic, update);} void addPoint(double y, int graphic, bool update = true) {
void addPoint(double y, bool update = true) {if (graphics[curGraphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), update); else addPoint(QPointF(graphics[curGraphic].max_x + inc_x, y), update);} if (graphics[graphic].polyline.isEmpty())
addPoint(QPointF(0.0, y), graphic, update);
else
addPoint(QPointF(graphics[graphic].max_x + inc_x, y), graphic, update);
}
void addPoint(double y, bool update = true) {
if (graphics[curGraphic].polyline.isEmpty())
addPoint(QPointF(0.0, y), update);
else
addPoint(QPointF(graphics[curGraphic].max_x + inc_x, y), update);
}
void addPoints(const QPolygonF & pts, int graphic, bool update_ = true); void addPoints(const QPolygonF & pts, int graphic, bool update_ = true);
void addPoints(const QPolygonF & pts, bool update = true) { addPoints(pts, curGraphic, update); } void addPoints(const QPolygonF & pts, bool update = true) { addPoints(pts, curGraphic, update); }
void addPoints(const QVector<double> & pts, int graphic, bool update_ = true); void addPoints(const QVector<double> & pts, int graphic, bool update_ = true);
void addPoints(const QVector<double> & pts, bool update = true) { addPoints(pts, curGraphic, update); } void addPoints(const QVector<double> & pts, bool update = true) { addPoints(pts, curGraphic, update); }
void setGraphicData(const QVector<QPointF> & g, int graphic, bool update_ = true); void setGraphicData(const QVector<QPointF> & g, int graphic, bool update_ = true);
void setGraphicData(const QVector<QPointF> & g) { setGraphicData(g, curGraphic); } void setGraphicData(const QVector<QPointF> & g) { setGraphicData(g, curGraphic); }
void setGraphicProperties(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true) {setGraphicProperties(curGraphic, name, color, style, width, visible);} void setGraphicProperties(const QString & name,
void setGraphicProperties(int graphic, const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true); const QColor & color = Qt::darkRed,
void addGraphic(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true); Qt::PenStyle style = Qt::SolidLine,
void addGraphic(const GraphicType & gd, bool update = true) {graphics << gd; if (update) updateLegend();} double width = 0.,
bool visible = true) {
setGraphicProperties(curGraphic, name, color, style, width, visible);
}
void setGraphicProperties(int graphic,
const QString & name,
const QColor & color = Qt::darkRed,
Qt::PenStyle style = Qt::SolidLine,
double width = 0.,
bool visible = true);
void addGraphic(const QString & name,
const QColor & color = Qt::darkRed,
Qt::PenStyle style = Qt::SolidLine,
double width = 0.,
bool visible = true);
void addGraphic(const GraphicType & gd, bool update = true) {
graphics << gd;
if (update) updateLegend();
}
void setVisualRect(const QRectF & rect); void setVisualRect(const QRectF & rect);
void setDefaultRect(const QRectF & rect); void setDefaultRect(const QRectF & rect);
void autofit() { on_graphic_buttonAutofit_clicked(); } void autofit() { on_graphic_buttonAutofit_clicked(); }
@@ -344,9 +516,18 @@ public slots:
void clear(); void clear();
void update(bool force); void update(bool force);
void update() { update(false); } void update() { update(false); }
void updateGraphics() {findGraphicsRect(); update();} void updateGraphics() {
void setCurrentGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curGraphic = arg;} findGraphicsRect();
void setTraceGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curTrace = arg;} update();
}
void setCurrentGraphic(int arg) {
if (arg < 0 || arg >= graphics.size()) return;
curGraphic = arg;
}
void setTraceGraphic(int arg) {
if (arg < 0 || arg >= graphics.size()) return;
curTrace = arg;
}
void setGraphicsCount(int arg, bool update = true); void setGraphicsCount(int arg, bool update = true);
void removeGraphic(int arg, bool update = true); void removeGraphic(int arg, bool update = true);
void setCustomGridMarkFuncs(std::function<QString(double val)> fx, std::function<QString(double val)> fy); void setCustomGridMarkFuncs(std::function<QString(double val)> fx, std::function<QString(double val)> fy);
@@ -379,7 +560,11 @@ protected:
void findGraphicsRect(double start_x = 0., double end_x = 0., double start_y = 0., double end_y = 0.); void findGraphicsRect(double start_x = 0., double end_x = 0., double start_y = 0., double end_y = 0.);
void tick(int index, bool slide = true, bool update = true); void tick(int index, bool slide = true, bool update = true);
void calcLOD(int index); void calcLOD(int index);
void repaintCanvas(bool force = false) {if (tm.elapsed() < min_repaint_int && !force) return; tm.restart(); canvas->update();} void repaintCanvas(bool force = false) {
if (tm.elapsed() < min_repaint_int && !force) return;
tm.restart();
canvas->update();
}
void drawGraphics(); void drawGraphics();
void drawGrid(); void drawGrid();
void drawGuides(); void drawGuides();
@@ -438,8 +623,10 @@ protected:
double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle; double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle;
int lastw, lasth, min_repaint_int, thick; int lastw, lasth, min_repaint_int, thick;
int timer_pause, timer_record; int timer_pause, timer_record;
bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL, need_createGL; bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL,
bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan, was_trace; need_createGL;
bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan,
was_trace;
std::function<QString(double val)> func_gridMarkX, func_gridMarkY; std::function<QString(double val)> func_gridMarkX, func_gridMarkY;
QVector<DateFormats> date_formats; QVector<DateFormats> date_formats;
QList<QImage> record_imgs; QList<QImage> record_imgs;
@@ -455,19 +642,37 @@ protected slots:
void canvasKeyPressEvent(QKeyEvent *); void canvasKeyPressEvent(QKeyEvent *);
void graphicVisibleChange(bool checked); void graphicVisibleChange(bool checked);
void graphicAllVisibleChange(bool checked); void graphicAllVisibleChange(bool checked);
void lineXMinChanged(double value) {selrect.setLeft(value); checkLines();} void lineXMinChanged(double value) {
void lineXMaxChanged(double value) {selrect.setRight(value); checkLines();} selrect.setLeft(value);
void lineYMinChanged(double value) {selrect.setBottom(value); checkLines();} checkLines();
void lineYMaxChanged(double value) {selrect.setTop(value); checkLines();} }
void 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_buttonClose_clicked() { emit closeRequest(this); }
void on_graphic_buttonClear_clicked() {clear(); emit cleared();} void on_graphic_buttonClear_clicked() {
clear();
emit cleared();
}
void on_graphic_buttonAutofit_clicked(); void on_graphic_buttonAutofit_clicked();
void on_graphic_buttonConfigure_clicked(); void on_graphic_buttonConfigure_clicked();
void on_graphic_buttonFullscreen_clicked() { fullscreen(); } void on_graphic_buttonFullscreen_clicked() { fullscreen(); }
void on_graphic_buttonSave_clicked(); void on_graphic_buttonSave_clicked();
void on_graphic_buttonExport_clicked(); void on_graphic_buttonExport_clicked();
void on_graphic_buttonRecord_clicked(bool checked); void on_graphic_buttonRecord_clicked(bool checked);
void on_graphic_checkGrid_toggled(bool checked) {grid = checked; update();} void on_graphic_checkGrid_toggled(bool checked) {
grid = checked;
update();
}
void on_graphic_checkGuides_toggled(bool checked); void on_graphic_checkGuides_toggled(bool checked);
void on_graphic_actionExpandX_triggered(bool checked); void on_graphic_actionExpandX_triggered(bool checked);
void on_graphic_actionExpandY_triggered(bool checked); void on_graphic_actionExpandY_triggered(bool checked);
@@ -499,8 +704,14 @@ Q_DECLARE_METATYPE(Graphic::GraphicsData)
Q_DECLARE_OPERATORS_FOR_FLAGS(Graphic::Buttons) Q_DECLARE_OPERATORS_FOR_FLAGS(Graphic::Buttons)
inline QDataStream & operator <<(QDataStream & s, const Graphic::Graduation & v) {s << (int)v; return s;} inline QDataStream & operator<<(QDataStream & s, const Graphic::Graduation & v) {
inline QDataStream & operator >>(QDataStream & s, Graphic::Graduation & v) {s >> *((int*)(&v)); return s;} s << (int)v;
return s;
}
inline QDataStream & operator>>(QDataStream & s, Graphic::Graduation & v) {
s >> *((int *)(&v));
return s;
}
class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ { class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ {

View File

@@ -1,4 +1,5 @@
#include "graphic_conf.h" #include "graphic_conf.h"
#include "qad_types.h" #include "qad_types.h"
#include "ui_graphic_conf.h" #include "ui_graphic_conf.h"
@@ -10,8 +11,7 @@ GraphicConf::GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent): QD
int fh = qMax<int>(fontMetrics().size(0, "0").height(), 22); int fh = qMax<int>(fontMetrics().size(0, "0").height(), 22);
int thick = lineThickness(this); int thick = lineThickness(this);
QSize sz(fh * 2.5, fh); QSize sz(fh * 2.5, fh);
styles << tr("NoPen") << tr("Solid") << tr("Dash") styles << tr("NoPen") << tr("Solid") << tr("Dash") << tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
ui->comboStyleGrid->setIconSize(sz); ui->comboStyleGrid->setIconSize(sz);
ui->comboStyleGraphic->setIconSize(sz); ui->comboStyleGraphic->setIconSize(sz);
ui->cbGraphicNames->setIconSize(sz); ui->cbGraphicNames->setIconSize(sz);
@@ -72,8 +72,10 @@ void GraphicConf::on_comboStyleGraphic_currentIndexChanged(int index) {
void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) { void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) {
if (graphicItems.isEmpty()) return; if (graphicItems.isEmpty()) return;
if (qRound(value) == value) graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value)); if (qRound(value) == value)
else graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value); graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value));
else
graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value);
} }

View File

@@ -20,12 +20,13 @@
#ifndef GRAPHIC_CONF_H #ifndef GRAPHIC_CONF_H
#define GRAPHIC_CONF_H #define GRAPHIC_CONF_H
#include <QDialog>
#include <QCheckBox>
#include <QPen>
#include <QPainter>
#include "qad_graphic_export.h" #include "qad_graphic_export.h"
#include <QCheckBox>
#include <QDialog>
#include <QPainter>
#include <QPen>
namespace Ui { namespace Ui {
class GraphicConf; class GraphicConf;
@@ -33,15 +34,21 @@ namespace Ui {
struct QAD_GRAPHIC_EXPORT GraphicType { struct QAD_GRAPHIC_EXPORT GraphicType {
GraphicType(QString name_ = "y(x)", QColor color = Qt::red, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible_ = true) { GraphicType(QString name_ = "y(x)",
QColor color = Qt::red,
Qt::PenStyle style = Qt::SolidLine,
double width = 0.,
bool visible_ = true) {
pen.setColor(color); pen.setColor(color);
pen.setStyle(style); pen.setStyle(style);
lines = true; lines = true;
points = false; points = false;
fill = false; fill = false;
fill_color = Qt::yellow; fill_color = Qt::yellow;
if (qRound(width) == width) pen.setWidth(qRound(width)); if (qRound(width) == width)
else pen.setWidthF(width); pen.setWidth(qRound(width));
else
pen.setWidthF(width);
pen.setWidth(1); pen.setWidth(1);
pen.setCosmetic(true); pen.setCosmetic(true);
max_x = 0.; max_x = 0.;
@@ -72,14 +79,20 @@ struct QAD_GRAPHIC_EXPORT GraphicType {
}; };
inline QDataStream & operator <<(QDataStream & s, const GraphicType & v) {s << v.name << v.pen << v.fill_color << v.lines << v.points << v.fill << v.pointWidth << v.visible; return s;} inline QDataStream & operator<<(QDataStream & s, const GraphicType & v) {
inline QDataStream & operator >>(QDataStream & s, GraphicType & v) {s >> v.name >> v.pen >> v.fill_color >> v.lines >> v.points >> v.fill >> v.pointWidth >> v.visible; return s;} s << v.name << v.pen << v.fill_color << v.lines << v.points << v.fill << v.pointWidth << v.visible;
return s;
}
inline QDataStream & operator>>(QDataStream & s, GraphicType & v) {
s >> v.name >> v.pen >> v.fill_color >> v.lines >> v.points >> v.fill >> v.pointWidth >> v.visible;
return s;
}
class QAD_GRAPHIC_EXPORT GraphicConf: public QDialog class QAD_GRAPHIC_EXPORT GraphicConf: public QDialog {
{
Q_OBJECT Q_OBJECT
friend class Graphic; friend class Graphic;
public: public:
explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0); explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0);

View File

@@ -1,5 +1,7 @@
#include "graphic.h"
#include "graphicplugin.h" #include "graphicplugin.h"
#include "graphic.h"
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -10,8 +12,7 @@ GraphicPlugin::GraphicPlugin(QObject * parent): QObject(parent) {
void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
m_designer = true; m_designer = true;
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -26,8 +27,7 @@ bool GraphicPlugin::isInitialized() const {
QWidget * GraphicPlugin::createWidget(QWidget * parent) { QWidget * GraphicPlugin::createWidget(QWidget * parent) {
auto ret = new Graphic(parent); auto ret = new Graphic(parent);
if (m_designer) if (m_designer) ret->m_fakeGL = true;
ret->m_fakeGL = true;
return ret; return ret;
} }
@@ -70,4 +70,3 @@ QString GraphicPlugin::domXml() const {
QString GraphicPlugin::includeFile() const { QString GraphicPlugin::includeFile() const {
return QLatin1String("graphic.h"); return QLatin1String("graphic.h");
} }

View File

@@ -8,8 +8,9 @@
# include <QDesignerCustomWidgetInterface> # include <QDesignerCustomWidgetInterface>
#endif #endif
class GraphicPlugin: public QObject, public QDesignerCustomWidgetInterface class GraphicPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -30,7 +31,6 @@ public:
private: private:
bool m_initialized, m_designer; bool m_initialized, m_designer;
}; };
#endif #endif

View File

@@ -1,8 +1,8 @@
#include "qad_graphic.h" #include "qad_graphic.h"
#include "graphicplugin.h" #include "graphicplugin.h"
QADGraphic::QADGraphic(QObject * parent): QObject(parent) QADGraphic::QADGraphic(QObject * parent): QObject(parent) {
{
m_widgets.append(new GraphicPlugin(this)); m_widgets.append(new GraphicPlugin(this));
} }

View File

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

View File

@@ -1,8 +1,8 @@
#ifndef UGLWIDGET_H #ifndef UGLWIDGET_H
#define UGLWIDGET_H #define UGLWIDGET_H
#include <QWidget>
#include <QDebug> #include <QDebug>
#include <QWidget>
#if QT_VERSION >= 0x050400 #if QT_VERSION >= 0x050400
# include <QOpenGLWidget> # include <QOpenGLWidget>
typedef QOpenGLWidget __GLWidget__; typedef QOpenGLWidget __GLWidget__;
@@ -16,14 +16,19 @@ typedef QGLWidget __GLWidget__;
#include "qad_graphic_export.h" #include "qad_graphic_export.h"
class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__ class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__ {
{
Q_OBJECT Q_OBJECT
public: public:
#if QT_VERSION >= 0x050400 #if QT_VERSION >= 0x050400
UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {QSurfaceFormat sf = format(); sf.setSamples(8); setFormat(sf);} UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {
QSurfaceFormat sf = format();
sf.setSamples(8);
setFormat(sf);
}
#else #else
UGLWidget(QWidget * parent = 0): __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {} UGLWidget(QWidget * parent = 0)
: __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {}
#endif #endif
// UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {} // UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {}
@@ -63,7 +68,6 @@ signals:
void wheelEvent(QWheelEvent * e); void wheelEvent(QWheelEvent * e);
void resizeSignal(); void resizeSignal();
void paintSignal(); void paintSignal();
}; };
#endif #endif

View File

@@ -1,17 +1,18 @@
#ifndef UWIDGET_H #ifndef UWIDGET_H
#define UWIDGET_H #define UWIDGET_H
#include <QWidget> #include "qad_graphic_export.h"
#include <QEvent>
#include <QPainter> #include <QPainter>
#include <QStyle> #include <QStyle>
#include <QStyleOption> #include <QStyleOption>
#include <QEvent> #include <QWidget>
#include "qad_graphic_export.h"
class QAD_GRAPHIC_EXPORT UWidget: public QWidget class QAD_GRAPHIC_EXPORT UWidget: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
UWidget(QWidget * parent = 0): QWidget(parent) {} UWidget(QWidget * parent = 0): QWidget(parent) {}
@@ -51,7 +52,6 @@ signals:
void showEvent(QShowEvent * e); void showEvent(QShowEvent * e);
void wheelEvent(QWheelEvent * e); void wheelEvent(QWheelEvent * e);
void paintEvent(QPaintEvent * e); void paintEvent(QPaintEvent * e);
}; };
#endif #endif

View File

@@ -1,8 +1,10 @@
#include "piqt.h" #include "piqt.h"
#include "qvariantedit.h" #include "qvariantedit.h"
#ifdef PIQT_HAS_GEOPOSITION #ifdef PIQT_HAS_GEOPOSITION
# include <QGeoCoordinate>
# include "pigeoposition.h" # include "pigeoposition.h"
# include <QGeoCoordinate>
#endif #endif

View File

@@ -20,16 +20,16 @@
#ifndef PIQT_H #ifndef PIQT_H
#define PIQT_H #define PIQT_H
#include <QVector3D>
#include <QPolygonF>
#include <QDateTime>
#include <QColor>
#include <QImage>
#include "pimathmatrix.h" #include "pimathmatrix.h"
#include "pipropertystorage.h" #include "pipropertystorage.h"
#include "qad_types.h"
#include "piqt_macros.h" #include "piqt_macros.h"
#include "qad_types.h"
#include <QColor>
#include <QDateTime>
#include <QImage>
#include <QPolygonF>
#include <QVector3D>
#if QT_VERSION_MAJOR == 5 #if QT_VERSION_MAJOR == 5
# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
# define PIQT_HAS_GEOPOSITION # define PIQT_HAS_GEOPOSITION
@@ -51,39 +51,79 @@ QAD_PIQT_EXPORT const QVariant PI2QVariant(const PIVariant & v);
QAD_PIQT_EXPORT const PIVariant Q2PIVariant(const QVariant & v); QAD_PIQT_EXPORT const PIVariant Q2PIVariant(const QVariant & v);
// inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());} // inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());}
inline const QString PI2QString(const PIString & v) {return QString::fromUtf8(v.dataUTF8());} inline const QString PI2QString(const PIString & v) {
return QString::fromUtf8(v.dataUTF8());
}
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 38, 0) #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 PIConstChars & v) {
return QString::fromLatin1(v.data(), v.length());
}
#endif #endif
// inline const PIString Q2PIString(const QString & v) {return PIString(v.toLocal8Bit().data());} // inline const PIString Q2PIString(const QString & v) {return PIString(v.toLocal8Bit().data());}
inline const PIString Q2PIString(const QString & v) {return PIString::fromUTF8(v.toUtf8().data());} inline const PIString Q2PIString(const QString & v) {
return PIString::fromUTF8(v.toUtf8().data());
}
inline const QStringList PI2QStringList(const PIStringList & v) {QStringList ret; piForeachC (PIString & s, v) ret << PI2QString(s); return ret;} inline const QStringList PI2QStringList(const PIStringList & v) {
QStringList ret;
piForeachC(PIString & s, v)
ret << PI2QString(s);
return ret;
}
inline const PIStringList Q2PIStringList(const QStringList & v) {PIStringList ret; foreach (const QString & s, v) ret << Q2PIString(s); return ret;} inline const PIStringList Q2PIStringList(const QStringList & v) {
PIStringList ret;
foreach(const QString & s, v)
ret << Q2PIString(s);
return ret;
}
inline const QByteArray PI2QByteArray(const PIByteArray & v) {return QByteArray((const char *)(v.data()), v.size_s());} inline const QByteArray PI2QByteArray(const PIByteArray & v) {
return QByteArray((const char *)(v.data()), v.size_s());
}
inline const PIByteArray Q2PIByteArray(const QByteArray & v) {return PIByteArray(v.constData(), v.size());} inline const PIByteArray Q2PIByteArray(const QByteArray & v) {
return PIByteArray(v.constData(), v.size());
}
inline const QPointF PI2QVector2(const PIMathVectorT2d & v) {return QPointF(v[0], v[1]);} inline const QPointF PI2QVector2(const PIMathVectorT2d & v) {
inline const QVector3D PI2QVector3(const PIMathVectorT3d & v) {return QVector3D(v[0], v[1], v[2]);} return QPointF(v[0], v[1]);
}
inline const QVector3D PI2QVector3(const PIMathVectorT3d & v) {
return QVector3D(v[0], v[1], v[2]);
}
inline const PIMathVectorT2d Q2PIVector2(const QPointF & v) {return PIMathVectorT2d({double(v.x()), double(v.y())});} inline const PIMathVectorT2d Q2PIVector2(const QPointF & v) {
inline const PIMathVectorT3d Q2PIVector3(const QVector3D & v) {return PIMathVectorT3d({double(v.x()), double(v.y()), double(v.z())});} return PIMathVectorT2d({double(v.x()), double(v.y())});
}
inline const PIMathVectorT3d Q2PIVector3(const QVector3D & v) {
return PIMathVectorT3d({double(v.x()), double(v.y()), double(v.z())});
}
inline const QPointF PI2QPoint(const PIPointd & v) {return QPointF(v.x, v.y);} inline const QPointF PI2QPoint(const PIPointd & v) {
inline const PIPointd Q2PIPoint(const QPointF & v) {return PIPointd(v.x(), v.y());} return QPointF(v.x, v.y);
}
inline const PIPointd Q2PIPoint(const QPointF & v) {
return PIPointd(v.x(), v.y());
}
inline const QRectF PI2QRect(const PIRectd & v) {return QRectF(v.left(), v.bottom(), v.width(), v.height());} inline const QRectF PI2QRect(const PIRectd & v) {
inline const PIRectd Q2PIRect(const QRectF & v) {return PIRectd(v.left(), v.top(), v.width(), v.height());} return QRectF(v.left(), v.bottom(), v.width(), v.height());
}
inline const PIRectd Q2PIRect(const QRectF & v) {
return PIRectd(v.left(), v.top(), v.width(), v.height());
}
inline const QLineF PI2QLine(const PILined & v) {return QLineF(PI2QPoint(v.p0), PI2QPoint(v.p1));} inline const QLineF PI2QLine(const PILined & v) {
inline const PILined Q2PILine(const QLineF & v) {return PILined(Q2PIPoint(v.p1()), Q2PIPoint(v.p2()));} return QLineF(PI2QPoint(v.p0), PI2QPoint(v.p1));
}
inline const PILined Q2PILine(const QLineF & v) {
return PILined(Q2PIPoint(v.p1()), Q2PIPoint(v.p2()));
}
inline const QAD::MathVector PI2QMathVector(const PIMathVectord & v) { inline const QAD::MathVector PI2QMathVector(const PIMathVectord & v) {
QVector<double> q = QVector<double>(v.size()); QVector<double> q = QVector<double>(v.size());
@@ -115,37 +155,70 @@ inline const PIMathMatrixd Q2PIMathMatrix(const QAD::MathMatrix & v) {
} }
inline const QDate PI2QDate(const PIDate & v) {return QDate(v.year, v.month, v.day);} inline const QDate PI2QDate(const PIDate & v) {
inline const QTime PI2QTime(const PITime & v) {return QTime(v.hours, v.minutes, v.seconds, v.milliseconds);} return QDate(v.year, v.month, v.day);
inline const QDateTime PI2QDateTime(const PIDateTime & v) {return QDateTime(PI2QDate(v.date()), PI2QTime(v.time()));} }
inline const QTime PI2QTime(const PITime & v) {
return QTime(v.hours, v.minutes, v.seconds, v.milliseconds);
}
inline const QDateTime PI2QDateTime(const PIDateTime & v) {
return QDateTime(PI2QDate(v.date()), PI2QTime(v.time()));
}
inline const PIDate Q2PIDate(const QDate & v) {return PIDate(v.year(), v.month(), v.day());} inline const PIDate Q2PIDate(const QDate & v) {
inline const PITime Q2PITime(const QTime & v) {return PITime(v.hour(), v.minute(), v.second(), v.msec());} return PIDate(v.year(), v.month(), v.day());
inline const PIDateTime Q2PIDateTime(const QDateTime & v) {return PIDateTime(Q2PIDate(v.date()), Q2PITime(v.time()));} }
inline const PITime Q2PITime(const QTime & v) {
return PITime(v.hour(), v.minute(), v.second(), v.msec());
}
inline const PIDateTime Q2PIDateTime(const QDateTime & v) {
return PIDateTime(Q2PIDate(v.date()), Q2PITime(v.time()));
}
inline const QColor PI2QColor(const PIVariantTypes::Color & v) {return QColor::fromRgba(v.rgba);} inline const QColor PI2QColor(const PIVariantTypes::Color & v) {
inline const PIVariantTypes::Color Q2PIColor(const QColor & v) {return PIVariantTypes::Color(v.rgba());} return QColor::fromRgba(v.rgba);
}
inline const PIVariantTypes::Color Q2PIColor(const QColor & v) {
return PIVariantTypes::Color(v.rgba());
}
template<typename T> template<typename T>
inline const QVector<T> PI2QVector(const PIVector<T> & v) {QVector<T> ret; ret.reserve(v.size_s()); for (int i = 0; i < v.size_s(); ++i) ret << v[i]; return ret;} inline const QVector<T> PI2QVector(const PIVector<T> & v) {
QVector<T> ret;
ret.reserve(v.size_s());
for (int i = 0; i < v.size_s(); ++i)
ret << v[i];
return ret;
}
template<typename T> template<typename T>
inline const PIVector<T> Q2PIVector(const QVector<T> & v) {if (v.isEmpty()) return PIVector<T>(); return PIVector<T>(v.constData(), (size_t)v.size());} inline const PIVector<T> Q2PIVector(const QVector<T> & v) {
if (v.isEmpty()) return PIVector<T>();
return PIVector<T>(v.constData(), (size_t)v.size());
}
template<typename K, typename T> template<typename K, typename T>
inline QMap<K, T> PI2QMap(const PIMap<K, T> & v) { inline QMap<K, T> PI2QMap(const PIMap<K, T> & v) {
QMap<K, T> ret; QMap<K, T> ret;
auto it = v.makeIterator(); auto it = v.makeIterator();
while (it.hasNext()) {it.next(); ret[it.key()] = it.value();} while (it.hasNext()) {
return ret;} it.next();
ret[it.key()] = it.value();
}
return ret;
}
template<typename K, typename T> template<typename K, typename T>
inline PIMap<K, T> Q2PIMap(const QMap<K, T> & v) { inline PIMap<K, T> Q2PIMap(const QMap<K, T> & v) {
PIMap<K, T> ret; PIMap<K, T> ret;
ret.reserve((size_t)v.size()); ret.reserve((size_t)v.size());
QMapIterator<K, T> it(v); QMapIterator<K, T> it(v);
while (it.hasNext()) {it.next(); ret[it.key()] = it.value();} while (it.hasNext()) {
return ret;} it.next();
ret[it.key()] = it.value();
}
return ret;
}
inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) { inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) {
@@ -183,175 +256,440 @@ template <typename From>
class __PIQtConverter { class __PIQtConverter {
public: public:
__PIQtConverter(const From & v): val(v) {} __PIQtConverter(const From & v): val(v) {}
template <typename To> operator To() {return To();} template<typename To>
operator To() {
return To();
}
From val; From val;
}; };
template<typename From> inline __PIQtConverter<From> __PIQtConvert(const From & f) {return __PIQtConverter<From>(f);} template<typename From>
inline __PIQtConverter<From> __PIQtConvert(const From & f) {
return __PIQtConverter<From>(f);
}
#define _PIQt_CONVERT(ft, tt, ftc, tfc) \ #define _PIQt_CONVERT(ft, tt, ftc, tfc) \
template<> template<> inline __PIQtConverter<ft>::operator tt() {return ftc(val);} \ template<> \
template<> template<> inline __PIQtConverter<tt>::operator ft() {return tfc(val);} template<> \
inline __PIQtConverter<ft>::operator tt() { \
return ftc(val); \
} \
template<> \
template<> \
inline __PIQtConverter<tt>::operator ft() { \
return tfc(val); \
}
#define _PIQt_CONVERT_S(t) _PIQt_CONVERT(PI##t, Q##t, PI2Q##t, Q2PI##t) #define _PIQt_CONVERT_S(t) _PIQt_CONVERT(PI##t, Q##t, PI2Q##t, Q2PI##t)
_PIQt_CONVERT_S(String) _PIQt_CONVERT_S(String) _PIQt_CONVERT_S(ByteArray) _PIQt_CONVERT_S(Time) _PIQt_CONVERT_S(Date) _PIQt_CONVERT_S(DateTime)
_PIQt_CONVERT_S(ByteArray) _PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2) _PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3)
_PIQt_CONVERT_S(Time)
_PIQt_CONVERT_S(Date)
_PIQt_CONVERT_S(DateTime)
_PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2)
_PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3)
#define piqt __PIQtConvert #define piqt __PIQtConvert
#define qtpi __PIQtConvert #define qtpi __PIQtConvert
#ifndef PIP_BINARY_STREAM #ifndef PIP_BINARY_STREAM
inline PIByteArray & operator <<(PIByteArray & s, const QString & v) {s << Q2PIString(v); return s;} inline PIByteArray &
inline PIByteArray & operator >>(PIByteArray & s, QString & v) {PIString t; s >> t; v = PI2QString(t); return s;} operator<<(PIByteArray & s, const QString & v) {
inline PIByteArray & operator <<(PIByteArray & s, const QStringList & v) {s << Q2PIStringList(v); return s;} s << Q2PIString(v);
inline PIByteArray & operator >>(PIByteArray & s, QStringList & v) {PIStringList t; s >> t; v = PI2QStringList(t); return s;} return s;
template <typename T> inline PIByteArray & operator <<(PIByteArray & s, const QVector<T> & v) {s << PIVector<T>(v.constData(), (size_t)v.size()); return s;} }
template <typename T> inline PIByteArray & operator >>(PIByteArray & s, QVector<T> & v) { inline PIByteArray & operator>>(PIByteArray & s, QString & v) {
PIVector<T> t; s >> t; PIString t;
v.resize(t.size_s()); s >> t;
for (int i = 0; i < t.size_s(); ++i) v = PI2QString(t);
v[i] = t[i]; return s;
return s;} }
template <typename K, typename T> inline PIByteArray & operator <<(PIByteArray & s, const QMap<K, T> & v) { inline PIByteArray & operator<<(PIByteArray & s, const QStringList & v) {
PIMap<K, T> t; s << Q2PIStringList(v);
t.reserve(v.size()); return s;
QMapIterator<K, T> it(v); }
while (it.hasNext()) {it.next(); t[it.key()] = it.value();} inline PIByteArray & operator>>(PIByteArray & s, QStringList & v) {
s << t; PIStringList t;
return s;} s >> t;
template <typename K, typename T> inline PIByteArray & operator >>(PIByteArray & s, QMap<K, T> & v) { v = PI2QStringList(t);
v.clear(); return s;
PIMap<K, T> t; s >> t; }
auto it = t.makeIterator(); template<typename T>
while (it.hasNext()) {it.next(); v[it.key()] = it.value();} inline PIByteArray & operator<<(PIByteArray & s, const QVector<T> & v) {
return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QPolygonF & v) {s << (QVector<QPointF>)v; return s;}
inline PIByteArray & operator >>(PIByteArray & s, QPolygonF & v) {QVector<QPointF> t; s >> t; v = t; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QByteArray & v) {s << Q2PIByteArray(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QByteArray & v) {PIByteArray t; s >> t; v = PI2QByteArray(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QDate & v) {s << Q2PIDate(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QDate & v) {PIDate t; s >> t; v = PI2QDate(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QTime & v) {s << Q2PITime(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QTime & v) {PITime t; s >> t; v = PI2QTime(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QDateTime & v) {s << Q2PIDateTime(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QDateTime & v) {PIDateTime t; s >> t; v = PI2QDateTime(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QVariant & v) {s << Q2PIVariant(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QVariant & v) {PIVariant t; s >> t; v = PI2QVariant(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PropertyStorage & v) {s << Q2PIPropertyStorage(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, PropertyStorage & v) {PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QColor & v) {s << Q2PIColor(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QColor & v) {PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::Enum & v) {s << QAD2PIEnum(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::Enum & v) {PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::File & v) {s << QAD2PIFile(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::File & v) {PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::Dir & v) {s << QAD2PIDir(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::Dir & v) {PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QAD::IODevice & v) {s << QAD2PIIODevice(v); return s;}
inline PIByteArray & operator >>(PIByteArray & s, QAD::IODevice & v) {PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s;}
inline PIByteArray & operator <<(PIByteArray & s, const QImage & v) {
QByteArray ba; QBuffer buf(&ba);
v.save(&buf, "png");
s << Q2PIByteArray(ba);
return s;}
inline PIByteArray & operator >>(PIByteArray & s, QImage & v) {
PIByteArray pba; s >> pba;
QByteArray ba = PI2QByteArray(pba);
if (!v.loadFromData(ba, "png"))
v = QImage();
return s;}
#else
template<typename P, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const QVector<T> & v) {
s << PIVector<T>(v.constData(), (size_t)v.size()); s << PIVector<T>(v.constData(), (size_t)v.size());
return s; return s;
} }
template<typename P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, QVector<T> & v) { template<typename T>
PIVector<T> t; s >> t; inline PIByteArray & operator>>(PIByteArray & s, QVector<T> & v) {
PIVector<T> t;
s >> t;
v.resize(t.size_s());
for (int i = 0; i < t.size_s(); ++i)
v[i] = t[i];
return s;
}
template<typename K, typename T>
inline PIByteArray & operator<<(PIByteArray & s, const QMap<K, T> & v) {
PIMap<K, T> t;
t.reserve(v.size());
QMapIterator<K, T> it(v);
while (it.hasNext()) {
it.next();
t[it.key()] = it.value();
}
s << t;
return s;
}
template<typename K, typename T>
inline PIByteArray & operator>>(PIByteArray & s, QMap<K, T> & v) {
v.clear();
PIMap<K, T> t;
s >> t;
auto it = t.makeIterator();
while (it.hasNext()) {
it.next();
v[it.key()] = it.value();
}
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QPolygonF & v) {
s << (QVector<QPointF>)v;
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QPolygonF & v) {
QVector<QPointF> t;
s >> t;
v = t;
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QByteArray & v) {
s << Q2PIByteArray(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QByteArray & v) {
PIByteArray t;
s >> t;
v = PI2QByteArray(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QDate & v) {
s << Q2PIDate(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QDate & v) {
PIDate t;
s >> t;
v = PI2QDate(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QTime & v) {
s << Q2PITime(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QTime & v) {
PITime t;
s >> t;
v = PI2QTime(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QDateTime & v) {
s << Q2PIDateTime(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QDateTime & v) {
PIDateTime t;
s >> t;
v = PI2QDateTime(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QVariant & v) {
s << Q2PIVariant(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QVariant & v) {
PIVariant t;
s >> t;
v = PI2QVariant(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const PropertyStorage & v) {
s << Q2PIPropertyStorage(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, PropertyStorage & v) {
PIPropertyStorage t;
s >> t;
v = PI2QPropertyStorage(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QColor & v) {
s << Q2PIColor(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QColor & v) {
PIVariantTypes::Color t;
s >> t;
v = PI2QColor(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::Enum & v) {
s << QAD2PIEnum(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::Enum & v) {
PIVariantTypes::Enum t;
s >> t;
v = PI2QADEnum(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::File & v) {
s << QAD2PIFile(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::File & v) {
PIVariantTypes::File t;
s >> t;
v = PI2QADFile(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::Dir & v) {
s << QAD2PIDir(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::Dir & v) {
PIVariantTypes::Dir t;
s >> t;
v = PI2QADDir(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QAD::IODevice & v) {
s << QAD2PIIODevice(v);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QAD::IODevice & v) {
PIVariantTypes::IODevice t;
s >> t;
v = PI2QADIODevice(t);
return s;
}
inline PIByteArray & operator<<(PIByteArray & s, const QImage & v) {
QByteArray ba;
QBuffer buf(&ba);
v.save(&buf, "png");
s << Q2PIByteArray(ba);
return s;
}
inline PIByteArray & operator>>(PIByteArray & s, QImage & v) {
PIByteArray pba;
s >> pba;
QByteArray ba = PI2QByteArray(pba);
if (!v.loadFromData(ba, "png")) v = QImage();
return s;
}
#else
template<typename P, typename T>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const QVector<T> & v) {
s << PIVector<T>(v.constData(), (size_t)v.size());
return s;
}
template<typename P, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, QVector<T> & v) {
PIVector<T> t;
s >> t;
v.resize(t.size_s()); v.resize(t.size_s());
for (int i = 0; i < t.size_s(); ++i) for (int i = 0; i < t.size_s(); ++i)
v[i] = t[i]; v[i] = t[i];
return s; return s;
} }
template<typename P, typename K, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const QMap<K, T> & v) { template<typename P, typename K, typename T>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const QMap<K, T> & v) {
PIMap<K, T> t; PIMap<K, T> t;
t.reserve(v.size()); t.reserve(v.size());
QMapIterator<K, T> it(v); QMapIterator<K, T> it(v);
while (it.hasNext()) {it.next(); t[it.key()] = it.value();} while (it.hasNext()) {
it.next();
t[it.key()] = it.value();
}
s << t; s << t;
return s; return s;
} }
template<typename P, typename K, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, QMap<K, T> & v) { template<typename P, typename K, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, QMap<K, T> & v) {
v.clear(); v.clear();
PIMap<K, T> t; s >> t; PIMap<K, T> t;
s >> t;
auto it = t.makeIterator(); auto it = t.makeIterator();
while (it.hasNext()) {it.next(); v[it.key()] = it.value();} while (it.hasNext()) {
it.next();
v[it.key()] = it.value();
}
return s; return s;
} }
BINARY_STREAM_WRITE(QString) {s << Q2PIString(v); return s;} BINARY_STREAM_WRITE(QString) {
BINARY_STREAM_READ (QString) {PIString t; s >> t; v = PI2QString(t); return s;} s << Q2PIString(v);
return s;
}
BINARY_STREAM_READ(QString) {
PIString t;
s >> t;
v = PI2QString(t);
return s;
}
BINARY_STREAM_WRITE(QStringList) {s << Q2PIStringList(v); return s;} BINARY_STREAM_WRITE(QStringList) {
BINARY_STREAM_READ (QStringList) {PIStringList t; s >> t; v = PI2QStringList(t); return s;} s << Q2PIStringList(v);
return s;
}
BINARY_STREAM_READ(QStringList) {
PIStringList t;
s >> t;
v = PI2QStringList(t);
return s;
}
BINARY_STREAM_WRITE(QPolygonF) {s << (QVector<QPointF>)v; return s;} BINARY_STREAM_WRITE(QPolygonF) {
BINARY_STREAM_READ (QPolygonF) {QVector<QPointF> t; s >> t; v = t; return s;} s << (QVector<QPointF>)v;
return s;
}
BINARY_STREAM_READ(QPolygonF) {
QVector<QPointF> t;
s >> t;
v = t;
return s;
}
BINARY_STREAM_WRITE(QByteArray) {s << Q2PIByteArray(v); return s;} BINARY_STREAM_WRITE(QByteArray) {
BINARY_STREAM_READ (QByteArray) {PIByteArray t; s >> t; v = PI2QByteArray(t); return s;} s << Q2PIByteArray(v);
return s;
}
BINARY_STREAM_READ(QByteArray) {
PIByteArray t;
s >> t;
v = PI2QByteArray(t);
return s;
}
BINARY_STREAM_WRITE(QDate) {s << Q2PIDate(v); return s;} BINARY_STREAM_WRITE(QDate) {
BINARY_STREAM_READ (QDate) {PIDate t; s >> t; v = PI2QDate(t); return s;} s << Q2PIDate(v);
return s;
}
BINARY_STREAM_READ(QDate) {
PIDate t;
s >> t;
v = PI2QDate(t);
return s;
}
BINARY_STREAM_WRITE(QTime) {s << Q2PITime(v); return s;} BINARY_STREAM_WRITE(QTime) {
BINARY_STREAM_READ (QTime) {PITime t; s >> t; v = PI2QTime(t); return s;} s << Q2PITime(v);
return s;
}
BINARY_STREAM_READ(QTime) {
PITime t;
s >> t;
v = PI2QTime(t);
return s;
}
BINARY_STREAM_WRITE(QDateTime) {s << Q2PIDateTime(v); return s;} BINARY_STREAM_WRITE(QDateTime) {
BINARY_STREAM_READ (QDateTime) {PIDateTime t; s >> t; v = PI2QDateTime(t); return s;} s << Q2PIDateTime(v);
return s;
}
BINARY_STREAM_READ(QDateTime) {
PIDateTime t;
s >> t;
v = PI2QDateTime(t);
return s;
}
BINARY_STREAM_WRITE(QVariant) {s << Q2PIVariant(v); return s;} BINARY_STREAM_WRITE(QVariant) {
BINARY_STREAM_READ (QVariant) {PIVariant t; s >> t; v = PI2QVariant(t); return s;} s << Q2PIVariant(v);
return s;
}
BINARY_STREAM_READ(QVariant) {
PIVariant t;
s >> t;
v = PI2QVariant(t);
return s;
}
BINARY_STREAM_WRITE(PropertyStorage) {s << Q2PIPropertyStorage(v); return s;} BINARY_STREAM_WRITE(PropertyStorage) {
BINARY_STREAM_READ (PropertyStorage) {PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s;} s << Q2PIPropertyStorage(v);
return s;
}
BINARY_STREAM_READ(PropertyStorage) {
PIPropertyStorage t;
s >> t;
v = PI2QPropertyStorage(t);
return s;
}
BINARY_STREAM_WRITE(QColor) {s << Q2PIColor(v); return s;} BINARY_STREAM_WRITE(QColor) {
BINARY_STREAM_READ (QColor) {PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s;} s << Q2PIColor(v);
return s;
}
BINARY_STREAM_READ(QColor) {
PIVariantTypes::Color t;
s >> t;
v = PI2QColor(t);
return s;
}
BINARY_STREAM_WRITE(QAD::Enum) {s << QAD2PIEnum(v); return s;} BINARY_STREAM_WRITE(QAD::Enum) {
BINARY_STREAM_READ (QAD::Enum) {PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s;} s << QAD2PIEnum(v);
return s;
}
BINARY_STREAM_READ(QAD::Enum) {
PIVariantTypes::Enum t;
s >> t;
v = PI2QADEnum(t);
return s;
}
BINARY_STREAM_WRITE(QAD::File) {s << QAD2PIFile(v); return s;} BINARY_STREAM_WRITE(QAD::File) {
BINARY_STREAM_READ (QAD::File) {PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s;} s << QAD2PIFile(v);
return s;
}
BINARY_STREAM_READ(QAD::File) {
PIVariantTypes::File t;
s >> t;
v = PI2QADFile(t);
return s;
}
BINARY_STREAM_WRITE(QAD::Dir) {s << QAD2PIDir(v); return s;} BINARY_STREAM_WRITE(QAD::Dir) {
BINARY_STREAM_READ (QAD::Dir) {PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s;} s << QAD2PIDir(v);
return s;
}
BINARY_STREAM_READ(QAD::Dir) {
PIVariantTypes::Dir t;
s >> t;
v = PI2QADDir(t);
return s;
}
BINARY_STREAM_WRITE(QAD::IODevice) {s << QAD2PIIODevice(v); return s;} BINARY_STREAM_WRITE(QAD::IODevice) {
BINARY_STREAM_READ (QAD::IODevice) {PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s;} s << QAD2PIIODevice(v);
return s;
}
BINARY_STREAM_READ(QAD::IODevice) {
PIVariantTypes::IODevice t;
s >> t;
v = PI2QADIODevice(t);
return s;
}
BINARY_STREAM_WRITE(QImage) { BINARY_STREAM_WRITE(QImage) {
QByteArray ba; QBuffer buf(&ba); QByteArray ba;
QBuffer buf(&ba);
v.save(&buf, "png"); v.save(&buf, "png");
s << Q2PIByteArray(ba); s << Q2PIByteArray(ba);
return s; return s;
} }
BINARY_STREAM_READ(QImage) { BINARY_STREAM_READ(QImage) {
PIByteArray pba; s >> pba; PIByteArray pba;
s >> pba;
QByteArray ba = PI2QByteArray(pba); QByteArray ba = PI2QByteArray(pba);
if (!v.loadFromData(ba, "png")) if (!v.loadFromData(ba, "png")) v = QImage();
v = QImage();
return s; return s;
} }
@@ -360,7 +698,8 @@ BINARY_STREAM_READ (QImage) {
/// pure Qt /// pure Qt
template <typename T> QByteArray qSerialize(const T & value, int version = -1) { template<typename T>
QByteArray qSerialize(const T & value, int version = -1) {
QByteArray ret; QByteArray ret;
QDataStream s(&ret, QIODevice::ReadWrite); QDataStream s(&ret, QIODevice::ReadWrite);
if (version > 0) s.setVersion((QDataStream::Version)version); if (version > 0) s.setVersion((QDataStream::Version)version);
@@ -368,7 +707,8 @@ template <typename T> QByteArray qSerialize(const T & value, int version = -1) {
return ret; return ret;
} }
template <typename T> T qDeserialize(const QByteArray & data, int version = -1) { template<typename T>
T qDeserialize(const QByteArray & data, int version = -1) {
T ret; T ret;
if (!data.isEmpty()) { if (!data.isEmpty()) {
QDataStream s(data); QDataStream s(data);
@@ -382,13 +722,15 @@ template <typename T> T qDeserialize(const QByteArray & data, int version = -1)
/// PIP with QByteArray /// PIP with QByteArray
template <typename T> QByteArray piqSerialize(const T & value) { template<typename T>
QByteArray piqSerialize(const T & value) {
PIByteArray ret; PIByteArray ret;
ret << value; ret << value;
return PI2QByteArray(ret); return PI2QByteArray(ret);
} }
template <typename T> T piqDeserialize(const QByteArray & data) { template<typename T>
T piqDeserialize(const QByteArray & data) {
T ret; T ret;
if (!data.isEmpty()) { if (!data.isEmpty()) {
PIByteArray ba = Q2PIByteArray(data); PIByteArray ba = Q2PIByteArray(data);

View File

@@ -20,10 +20,11 @@
#ifndef PIQT_MACROS_H #ifndef PIQT_MACROS_H
#define PIQT_MACROS_H #define PIQT_MACROS_H
#include <piobject.h>
#include <QObject>
#include "qad_piqt_export.h" #include "qad_piqt_export.h"
#include <QObject>
#include <piobject.h>
/// connect PIP event "event" of object "src" directly to Qt slot "slot" of object "tgt" /// connect PIP event "event" of object "src" directly to Qt slot "slot" of object "tgt"
/// e.g. PIQCONNECT(&pip_obj, someEvent, &qt_obj, someSlot) /// e.g. PIQCONNECT(&pip_obj, someEvent, &qt_obj, someSlot)
@@ -33,8 +34,7 @@
/// connect PIP event "event" of object "src" to Qt slot "slot" of object "tgt" via Qt::QueuedConnection /// connect PIP event "event" of object "src" to Qt slot "slot" of object "tgt" via Qt::QueuedConnection
/// Note! All argument types must be registered in Qt meta-system! /// Note! All argument types must be registered in Qt meta-system!
/// e.g. PIQCONNECT_QUEUED(&pip_obj, someEvent, &qt_obj, someSlot) /// e.g. PIQCONNECT_QUEUED(&pip_obj, someEvent, &qt_obj, someSlot)
#define PIQCONNECT_QUEUED(src, event, tgt, slot) \ #define PIQCONNECT_QUEUED(src, event, tgt, slot) PIQt::piqConnectQ(src, #event, &(src)->__stat_eh_##event##__, tgt, #slot);
PIQt::piqConnectQ(src, #event, &(src)->__stat_eh_##event##__, tgt, #slot);
/// connect Qt signal "sig" of object "src" directly to PIP event handler "handler" of object "tgt" /// connect Qt signal "sig" of object "src" directly to PIP event handler "handler" of object "tgt"
@@ -46,26 +46,37 @@
namespace PIQt { namespace PIQt {
template<typename T> T removePtr(T*) {} template<typename T>
template<typename T> QArgument<T> qargument(const T & v) { T removePtr(T *) {}
template<typename T>
QArgument<T> qargument(const T & v) {
return QArgument<T>( return QArgument<T>(
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
QMetaType::typeName(qMetaTypeId<T>()) QMetaType::typeName(qMetaTypeId<T>())
#else #else
QMetaType::fromType<T>().name() QMetaType::fromType<T>().name()
#endif #endif
, v);} ,
v);
}
template<typename SR, typename O, typename... ARGS> template<typename SR, typename O, typename... ARGS>
void piqConnect(PIObject * source, const char * event, void (*func)(void *, ARGS...), O * target, SR (O::*slot)(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); PIObject::piConnectLS(source,
PIStringAscii(event),
PIObject::__newFunctor(func, [target, slot](ARGS... args) { (target->*slot)(args...); }),
LOCATION);
} }
template<typename... ARGS> template<typename... ARGS>
void piqConnectQ(PIObject * source, const char * event, void (*func)(void *, ARGS...), QObject * target, const char * slot) { 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){ PIObject::piConnectLS(source,
PIStringAscii(event),
PIObject::__newFunctor(func,
[target, slot](ARGS... args) {
QMetaObject::invokeMethod(target, slot, Qt::QueuedConnection, qargument(args)...); QMetaObject::invokeMethod(target, slot, Qt::QueuedConnection, qargument(args)...);
}), LOCATION); }),
LOCATION);
} }
template<typename SR, typename O, typename... ARGS> template<typename SR, typename O, typename... ARGS>
@@ -73,6 +84,6 @@ QMetaObject::Connection qpiConnect(O * source, SR(O::*signal)(ARGS...), PIObject
return QObject::connect(source, signal, source, [target, handler](ARGS... args) { handler(target, args...); }); return QObject::connect(source, signal, source, [target, handler](ARGS... args) { handler(target, args...); });
} }
} } // namespace PIQt
#endif // PIQT_MACROS_H #endif // PIQT_MACROS_H

View File

@@ -19,12 +19,18 @@ bool QPIConnection::loadFromCMFile(const QString & file) {
void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) { void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) {
// piCout << from << PICoutManipulators::Hex << data; // piCout << from << PICoutManipulators::Hex << data;
QMetaObject::invokeMethod(this, "qDataReceivedEvent", Qt::QueuedConnection, QMetaObject::invokeMethod(this,
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data))); "qDataReceivedEvent",
Qt::QueuedConnection,
Q_ARG(QString, PI2QString(from)),
Q_ARG(QByteArray, PI2QByteArray(data)));
} }
void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) { void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) {
QMetaObject::invokeMethod(this, "qPacketReceivedEvent", Qt::QueuedConnection, QMetaObject::invokeMethod(this,
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data))); "qPacketReceivedEvent",
Qt::QueuedConnection,
Q_ARG(QString, PI2QString(from)),
Q_ARG(QByteArray, PI2QByteArray(data)));
} }

View File

@@ -20,17 +20,21 @@
#ifndef QPICONNECTION_H #ifndef QPICONNECTION_H
#define QPICONNECTION_H #define QPICONNECTION_H
#include <QObject>
#include <QMetaObject>
#include "piconnection.h" #include "piconnection.h"
#include "qpiconfig.h"
#include "piqt.h" #include "piqt.h"
#include "qad_piqt_export.h" #include "qad_piqt_export.h"
#include "qpiconfig.h"
#include <QMetaObject>
#include <QObject>
class QAD_PIQT_EXPORT QPIConnection: public QObject, public PIConnection { class QAD_PIQT_EXPORT QPIConnection
: public QObject
, public PIConnection {
Q_OBJECT Q_OBJECT
PIOBJECT_SUBCLASS(QPIConnection, PIConnection); PIOBJECT_SUBCLASS(QPIConnection, PIConnection);
public: public:
QPIConnection(const QString & name = QString()); QPIConnection(const QString & name = QString());
@@ -50,7 +54,6 @@ public slots:
signals: signals:
void qDataReceivedEvent(QString from, QByteArray data); void qDataReceivedEvent(QString from, QByteArray data);
void qPacketReceivedEvent(QString from, QByteArray data); void qPacketReceivedEvent(QString from, QByteArray data);
}; };
#endif // QPICONNECTION_H #endif // QPICONNECTION_H

View File

@@ -1,9 +1,11 @@
#include "ui_piqt_connection_edit.h"
#include "piqt_connection_edit.h" #include "piqt_connection_edit.h"
#include "picodeinfo.h"
#include "piqt.h"
#include "piqt_connection_view.h" #include "piqt_connection_view.h"
#include "piqt_highlighter.h" #include "piqt_highlighter.h"
#include "piqt.h" #include "ui_piqt_connection_edit.h"
#include "picodeinfo.h"
#include <QCheckBox> #include <QCheckBox>
#include <QMessageBox> #include <QMessageBox>
@@ -20,7 +22,8 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
if (ei) { if (ei) {
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"),
QVariant::fromValue<int>(e.value));
#else #else
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
#endif #endif
@@ -43,7 +46,8 @@ ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
if (ei) { if (ei) {
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ui->comboSplit->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboSplit->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"),
QVariant::fromValue<int>(e.value));
#else #else
ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
#endif #endif
@@ -67,7 +71,9 @@ void ConnectionEdit::accept() {
foreach(BlockItem * j, bl) foreach(BlockItem * j, bl)
if (i != j) if (i != j)
if (((DeviceItem *)i)->name() == ((DeviceItem *)j)->name()) { if (((DeviceItem *)i)->name() == ((DeviceItem *)j)->name()) {
QMessageBox::critical(this, windowTitle() + " - " + tr("error") + "!", tr("Equal devices names: \"%1\"!").arg(((DeviceItem*)i)->name())); QMessageBox::critical(this,
windowTitle() + " - " + tr("error") + "!",
tr("Equal devices names: \"%1\"!").arg(((DeviceItem *)i)->name()));
return; return;
} }
QDialog::accept(); QDialog::accept();
@@ -97,9 +103,7 @@ QByteArray ConnectionEdit::model() const {
switch (type) { switch (type) {
case __CV_Device: case __CV_Device:
case __CV_Filter: case __CV_Filter:
case __CV_Sender: case __CV_Sender: s << b->save(); break;
s << b->save();
break;
} }
} }
return ret; return ret;
@@ -136,7 +140,9 @@ void ConnectionEdit::setModel(const QByteArray & m) {
s >> sz; s >> sz;
for (int i = 0; i < sz; ++i) { for (int i = 0; i < sz; ++i) {
BlockBusItem * b = new BlockBusItem(); BlockBusItem * b = new BlockBusItem();
QByteArray ba; s >> ba; b->load(ba); QByteArray ba;
s >> ba;
b->load(ba);
ui->blockView->addItem(b); ui->blockView->addItem(b);
} }
s >> sz; s >> sz;
@@ -148,26 +154,26 @@ void ConnectionEdit::setModel(const QByteArray & m) {
switch (type) { switch (type) {
case __CV_Device: case __CV_Device:
b = new DeviceItem(); b = new DeviceItem();
s >> ba; b->load(ba); s >> ba;
if (!b->isPropertyExists("bufferSize")) b->load(ba);
((DeviceItem*)b)->setBufferSize(4096); if (!b->isPropertyExists("bufferSize")) ((DeviceItem *)b)->setBufferSize(4096);
((DeviceItem *)b)->rename(); ((DeviceItem *)b)->rename();
break; break;
case __CV_Filter: case __CV_Filter:
b = new FilterItem(); b = new FilterItem();
s >> ba; b->load(ba); s >> ba;
if (!b->isPropertyExists("bufferSize")) b->load(ba);
((FilterItem*)b)->setBufferSize(65536); if (!b->isPropertyExists("bufferSize")) ((FilterItem *)b)->setBufferSize(65536);
((FilterItem *)b)->rename(); ((FilterItem *)b)->rename();
break; break;
case __CV_Sender: case __CV_Sender:
b = new SenderItem(); b = new SenderItem();
s >> ba; b->load(ba); s >> ba;
b->load(ba);
((SenderItem *)b)->rename(); ((SenderItem *)b)->rename();
break; break;
} }
if (b) if (b) ui->blockView->addItem(b);
ui->blockView->addItem(b);
} }
ui->blockView->reconnectAll(); ui->blockView->reconnectAll();
loading = false; loading = false;
@@ -225,7 +231,6 @@ void ConnectionEdit::selectionChanged() {
ui->lineData->setText(si->data()); ui->lineData->setText(si->data());
ui->spinFrequency->setValue(si->frequency()); ui->spinFrequency->setValue(si->frequency());
} }
} }
@@ -270,8 +275,7 @@ int ConnectionEdit::getOptions() const {
for (int i = 0; i < ui->layoutOptions->count(); ++i) { for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget()); QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue; if (!cb) continue;
if (cb->isChecked()) if (cb->isChecked()) ret |= cb->property("__value").toInt();
ret |= cb->property("__value").toInt();
} }
return ret; return ret;
} }
@@ -294,8 +298,10 @@ void ConnectionEdit::recreateConnection() {
ui->blockView->reconnectAll(); ui->blockView->reconnectAll();
if (conn) delete conn; if (conn) delete conn;
PIString cn = Q2PIString(ui->lineName->text()); PIString cn = Q2PIString(ui->lineName->text());
if (cn.isEmpty()) conn = new PIConnection(); if (cn.isEmpty())
else conn = new PIConnection(cn); conn = new PIConnection();
else
conn = new PIConnection(cn);
QList<BlockItem *> devs = ui->blockView->allDevices(); QList<BlockItem *> devs = ui->blockView->allDevices();
foreach(BlockItem * b, devs) { foreach(BlockItem * b, devs) {
DeviceItem * di = (DeviceItem *)b; DeviceItem * di = (DeviceItem *)b;
@@ -414,8 +420,7 @@ void ConnectionEdit::on_buttonFilterModify_clicked() {
QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return; if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem *>(si[0])) return; if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter) if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter) return;
return;
applyFilter(qgraphicsitem_cast<FilterItem *>(si[0])); applyFilter(qgraphicsitem_cast<FilterItem *>(si[0]));
} }
@@ -438,8 +443,7 @@ void ConnectionEdit::on_buttonDeviceModify_clicked() {
QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return; if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem *>(si[0])) return; if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Device) if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Device) return;
return;
applyDevice(qgraphicsitem_cast<DeviceItem *>(si[0])); applyDevice(qgraphicsitem_cast<DeviceItem *>(si[0]));
} }
@@ -454,8 +458,7 @@ void ConnectionEdit::on_buttonSenderModify_clicked() {
QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems(); QList<QGraphicsItem *> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return; if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem *>(si[0])) return; if (!qgraphicsitem_cast<BlockItem *>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender) if (qgraphicsitem_cast<BlockItem *>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender) return;
return;
applySender(qgraphicsitem_cast<SenderItem *>(si[0])); applySender(qgraphicsitem_cast<SenderItem *>(si[0]));
} }

View File

@@ -20,10 +20,11 @@
#ifndef CONNECTION_EDIT_H #ifndef CONNECTION_EDIT_H
#define CONNECTION_EDIT_H #define CONNECTION_EDIT_H
#include <QDialog>
#include "piconnection.h" #include "piconnection.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include <QDialog>
namespace Ui { namespace Ui {
class ConnectionEdit; class ConnectionEdit;
@@ -35,6 +36,7 @@ class SenderItem;
class QAD_PIQT_UTILS_EXPORT ConnectionEdit: public QDialog { class QAD_PIQT_UTILS_EXPORT ConnectionEdit: public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectionEdit(QWidget * parent = 0); explicit ConnectionEdit(QWidget * parent = 0);
~ConnectionEdit(); ~ConnectionEdit();
@@ -62,7 +64,9 @@ private:
int udevicenum; int udevicenum;
private slots: private slots:
void recreateRequest() {if (!loading) QMetaObject::invokeMethod(this, "recreateConnection", Qt::QueuedConnection);} void recreateRequest() {
if (!loading) QMetaObject::invokeMethod(this, "recreateConnection", Qt::QueuedConnection);
}
void on_buttonRemove_clicked(); void on_buttonRemove_clicked();
void on_buttonClear_clicked(); void on_buttonClear_clicked();
void on_buttonFilterAdd_clicked(); void on_buttonFilterAdd_clicked();
@@ -76,7 +80,6 @@ private slots:
public slots: public slots:
void recreateConnection(); void recreateConnection();
}; };
#endif // CONNECTION_EDIT_H #endif // CONNECTION_EDIT_H

View File

@@ -1,6 +1,8 @@
#include "piqt_connection_view.h" #include "piqt_connection_view.h"
#include "picodeinfo.h" #include "picodeinfo.h"
#include "piqt.h" #include "piqt.h"
#include <alignedtextitem.h> #include <alignedtextitem.h>
@@ -11,7 +13,8 @@ DeviceItem::DeviceItem(): BlockItem() {
setColor(QColor(192, 192, 255)); setColor(QColor(192, 192, 255));
text_name = new AlignedTextItem(); text_name = new AlignedTextItem();
text_path = new AlignedTextItem(); text_path = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true); QFont fnt(text_name->font());
fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt); text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.); text_name->setPos(0., -size().height() / 2.);
@@ -31,17 +34,27 @@ void DeviceItem::rename() {
QString ms; QString ms;
BlockItemPin *pr = pinByText("read"), *pw = pinByText("write"); BlockItemPin *pr = pinByText("read"), *pw = pinByText("write");
switch (mode()) { switch (mode()) {
case PIIODevice::ReadOnly: ms = "ro"; pr->show(); pw->hide(); break; case PIIODevice::ReadOnly:
case PIIODevice::WriteOnly: ms = "wo"; pr->hide(); pw->show(); break; ms = "ro";
case PIIODevice::ReadWrite: ms = "rw"; pr->show(); pw->show(); break; pr->show();
pw->hide();
break;
case PIIODevice::WriteOnly:
ms = "wo";
pr->hide();
pw->show();
break;
case PIIODevice::ReadWrite:
ms = "rw";
pr->show();
pw->show();
break;
} }
text_name->setText(name() + " (" + ms + ")"); text_name->setText(name() + " (" + ms + ")");
text_path->setText(path()); text_path->setText(path());
} }
FilterItem::FilterItem(): BlockItem() { FilterItem::FilterItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Filter)); addProperty(BlockItem::Property("__type", "", __CV_Filter));
addProperty(BlockItem::Property("bufferSize", "", 65536)); addProperty(BlockItem::Property("bufferSize", "", 65536));
@@ -50,7 +63,8 @@ FilterItem::FilterItem(): BlockItem() {
setColor(QColor(192, 255, 192)); setColor(QColor(192, 255, 192));
text_name = new AlignedTextItem(); text_name = new AlignedTextItem();
text_mode = new AlignedTextItem(); text_mode = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true); QFont fnt(text_name->font());
fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt); text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.); text_name->setPos(0., -size().height() / 2.);
@@ -82,12 +96,9 @@ void FilterItem::rename() {
} }
} }
text_mode->setText(ms); text_mode->setText(ms);
} }
SenderItem::SenderItem(): BlockItem() { SenderItem::SenderItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Sender)); addProperty(BlockItem::Property("__type", "", __CV_Sender));
setSize(140, 80); setSize(140, 80);
@@ -95,7 +106,8 @@ SenderItem::SenderItem(): BlockItem() {
setColor(QColor(255, 192, 192)); setColor(QColor(255, 192, 192));
text_name = new AlignedTextItem(); text_name = new AlignedTextItem();
text_frequency = new AlignedTextItem(); text_frequency = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true); QFont fnt(text_name->font());
fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt); text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.); text_name->setPos(0., -size().height() / 2.);
@@ -116,14 +128,10 @@ void SenderItem::rename() {
} }
ConnectionView::ConnectionView(QWidget * parent): BlockView(parent) {}
ConnectionView::ConnectionView(QWidget * parent): BlockView(parent) { ConnectionView::~ConnectionView() {}
}
ConnectionView::~ConnectionView() {
}
DeviceItem * ConnectionView::addDevice(const QString & name, const QString & path) { DeviceItem * ConnectionView::addDevice(const QString & name, const QString & path) {
@@ -168,8 +176,7 @@ SenderItem * ConnectionView::addSender(const QString & name) {
DeviceItem * ConnectionView::findDevice(const QString & name) const { DeviceItem * ConnectionView::findDevice(const QString & name) const {
QList<BlockItem *> blockl = blocks(); QList<BlockItem *> blockl = blocks();
foreach(BlockItem * b, blockl) foreach(BlockItem * b, blockl)
if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device)) if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device)) return (DeviceItem *)b;
return (DeviceItem*)b;
return 0; return 0;
} }
@@ -202,7 +209,6 @@ void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem * > coll) {
QList<BlockItem *> ConnectionView::allByType(int type_) const { QList<BlockItem *> ConnectionView::allByType(int type_) const {
QList<BlockItem *> blockl = blocks(), ret; QList<BlockItem *> blockl = blocks(), ret;
foreach(BlockItem * b, blockl) foreach(BlockItem * b, blockl)
if (b->propertyByName("__type").value.toInt() == type_) if (b->propertyByName("__type").value.toInt() == type_) ret << b;
ret << b;
return ret; return ret;
} }

View File

@@ -33,12 +33,30 @@ class QAD_PIQT_UTILS_EXPORT DeviceItem: public BlockItem {
public: public:
DeviceItem(); DeviceItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();} void setName(const QString & n) {
void setPath(const QString & p) {addProperty(BlockItem::Property("device", "", p)); rename();} addProperty(BlockItem::Property("name", "", n));
void setMode(PIIODevice::DeviceMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();} rename();
void setOptions(PIIODevice::DeviceOptions o) {addProperty(BlockItem::Property("options", "", int(o))); rename();} }
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();} void setPath(const QString & p) {
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();} addProperty(BlockItem::Property("device", "", p));
rename();
}
void setMode(PIIODevice::DeviceMode m) {
addProperty(BlockItem::Property("mode", "", int(m)));
rename();
}
void setOptions(PIIODevice::DeviceOptions o) {
addProperty(BlockItem::Property("options", "", int(o)));
rename();
}
void setDisconnectTimeout(double v) {
addProperty(BlockItem::Property("disconnectTimeout", "", v));
rename();
}
void setBufferSize(int v) {
addProperty(BlockItem::Property("bufferSize", "", v));
rename();
}
QString name() const { return propertyByName("name").value.toString(); } QString name() const { return propertyByName("name").value.toString(); }
QString path() const { return propertyByName("device").value.toString(); } QString path() const { return propertyByName("device").value.toString(); }
@@ -51,7 +69,6 @@ public:
protected: protected:
AlignedTextItem *text_name, *text_path; AlignedTextItem *text_name, *text_path;
}; };
@@ -59,14 +76,38 @@ class QAD_PIQT_UTILS_EXPORT FilterItem: public BlockItem {
public: public:
FilterItem(); FilterItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();} void setName(const QString & n) {
void setMode(PIPacketExtractor::SplitMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();} addProperty(BlockItem::Property("name", "", n));
void setHeader(const QString & v) {addProperty(BlockItem::Property("header", "", v)); rename();} rename();
void setFooter(const QString & v) {addProperty(BlockItem::Property("footer", "", v)); rename();} }
void setTimeout(double v) {addProperty(BlockItem::Property("timeout", "", v)); rename();} void setMode(PIPacketExtractor::SplitMode m) {
void setPacketSize(int v) {addProperty(BlockItem::Property("size", "", v)); rename();} addProperty(BlockItem::Property("mode", "", int(m)));
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();} rename();
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();} }
void setHeader(const QString & v) {
addProperty(BlockItem::Property("header", "", v));
rename();
}
void setFooter(const QString & v) {
addProperty(BlockItem::Property("footer", "", v));
rename();
}
void setTimeout(double v) {
addProperty(BlockItem::Property("timeout", "", v));
rename();
}
void setPacketSize(int v) {
addProperty(BlockItem::Property("size", "", v));
rename();
}
void setDisconnectTimeout(double v) {
addProperty(BlockItem::Property("disconnectTimeout", "", v));
rename();
}
void setBufferSize(int v) {
addProperty(BlockItem::Property("bufferSize", "", v));
rename();
}
QString name() const { return propertyByName("name").value.toString(); } QString name() const { return propertyByName("name").value.toString(); }
PIPacketExtractor::SplitMode mode() const { return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt()); } PIPacketExtractor::SplitMode mode() const { return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt()); }
@@ -81,7 +122,6 @@ public:
protected: protected:
AlignedTextItem *text_name, *text_mode; AlignedTextItem *text_name, *text_mode;
}; };
@@ -89,9 +129,18 @@ class QAD_PIQT_UTILS_EXPORT SenderItem: public BlockItem {
public: public:
SenderItem(); SenderItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();} void setName(const QString & n) {
void setData(const QString & p) {addProperty(BlockItem::Property("data", "", p)); rename();} addProperty(BlockItem::Property("name", "", n));
void setFrequency(double m) {addProperty(BlockItem::Property("frequency", "", m)); rename();} rename();
}
void setData(const QString & p) {
addProperty(BlockItem::Property("data", "", p));
rename();
}
void setFrequency(double m) {
addProperty(BlockItem::Property("frequency", "", m));
rename();
}
QString name() const { return propertyByName("name").value.toString(); } QString name() const { return propertyByName("name").value.toString(); }
QString data() const { return propertyByName("data").value.toString(); } QString data() const { return propertyByName("data").value.toString(); }
@@ -101,12 +150,12 @@ public:
protected: protected:
AlignedTextItem *text_name, *text_frequency; AlignedTextItem *text_name, *text_frequency;
}; };
class QAD_PIQT_UTILS_EXPORT ConnectionView: public BlockView { class QAD_PIQT_UTILS_EXPORT ConnectionView: public BlockView {
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectionView(QWidget * parent = 0); explicit ConnectionView(QWidget * parent = 0);
~ConnectionView(); ~ConnectionView();
@@ -127,7 +176,6 @@ private:
QList<BlockItem *> allByType(int type_) const; QList<BlockItem *> allByType(int type_) const;
private slots: private slots:
}; };
#endif // CONNECTION_VIEW_H #endif // CONNECTION_VIEW_H

View File

@@ -21,8 +21,8 @@
#define CONF_HIGHLIGHTER_H #define CONF_HIGHLIGHTER_H
#include <QSyntaxHighlighter> #include <QSyntaxHighlighter>
#include <QTextCursor>
#include <QTextCharFormat> #include <QTextCharFormat>
#include <QTextCursor>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QRegularExpression> # include <QRegularExpression>
#else #else
@@ -33,9 +33,9 @@
class QTextDocument; class QTextDocument;
class QAD_PIQT_UTILS_EXPORT ConfigHighlighter : public QSyntaxHighlighter class QAD_PIQT_UTILS_EXPORT ConfigHighlighter: public QSyntaxHighlighter {
{
Q_OBJECT Q_OBJECT
public: public:
ConfigHighlighter(QTextDocument * parent = 0); ConfigHighlighter(QTextDocument * parent = 0);

View File

@@ -1,11 +1,13 @@
#include "piqt_iodevice_edit.h" #include "piqt_iodevice_edit.h"
#include "piqt_iodevice_edit_dialog.h" #include "piqt_iodevice_edit_dialog.h"
#include "qvariantedit_custom.h" #include "qvariantedit_custom.h"
#include <QBoxLayout>
#include <QLineEdit> #include <QLineEdit>
#include <QToolButton> #include <QToolButton>
#include <QBoxLayout>
#include <piqt.h>
#include <piiodevice.h> #include <piiodevice.h>
#include <piqt.h>
IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) { IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) {
@@ -65,7 +67,6 @@ void IODeviceEdit::buttonDlg_clicked() {
} }
class Factory: public QVariantEditorFactoryBase { class Factory: public QVariantEditorFactoryBase {
public: public:
Factory() {} Factory() {}

View File

@@ -20,9 +20,10 @@
#ifndef PIQT_IODEVICE_EDIT_H #ifndef PIQT_IODEVICE_EDIT_H
#define PIQT_IODEVICE_EDIT_H #define PIQT_IODEVICE_EDIT_H
#include <QWidget>
#include "qad_types.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include "qad_types.h"
#include <QWidget>
class QLineEdit; class QLineEdit;
class QToolButton; class QToolButton;
@@ -33,6 +34,7 @@ class QAD_PIQT_UTILS_EXPORT IODeviceEdit: public QWidget {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
public: public:
explicit IODeviceEdit(QWidget * parent = 0); explicit IODeviceEdit(QWidget * parent = 0);
~IODeviceEdit(); ~IODeviceEdit();
@@ -57,7 +59,6 @@ private slots:
signals: signals:
void valueChanged(); void valueChanged();
}; };

View File

@@ -1,8 +1,10 @@
#include "ui_piqt_iodevice_edit_dialog.h"
#include "piqt_iodevice_edit_dialog.h" #include "piqt_iodevice_edit_dialog.h"
#include "piqt.h"
#include "picodeinfo.h" #include "picodeinfo.h"
#include "piiodevice.h" #include "piiodevice.h"
#include "piqt.h"
#include "ui_piqt_iodevice_edit_dialog.h"
#include <QCheckBox> #include <QCheckBox>
@@ -13,7 +15,8 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
if (ei) { if (ei) {
piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members)
#if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0) #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0)
ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name.toString() + " (" + PIString::fromNumber(e.value) + ")"),
QVariant::fromValue<int>(e.value));
#else #else
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value)); ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
#endif #endif
@@ -39,8 +42,7 @@ IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
} }
IODeviceEditDialog::~IODeviceEditDialog() { IODeviceEditDialog::~IODeviceEditDialog() {}
}
int IODeviceEditDialog::getOptions() const { int IODeviceEditDialog::getOptions() const {
@@ -48,8 +50,7 @@ int IODeviceEditDialog::getOptions() const {
for (int i = 0; i < ui->layoutOptions->count(); ++i) { for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget()); QCheckBox * cb = qobject_cast<QCheckBox *>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue; if (!cb) continue;
if (cb->isChecked()) if (cb->isChecked()) ret |= cb->property("__value").toInt();
ret |= cb->property("__value").toInt();
} }
return ret; return ret;
} }
@@ -78,8 +79,7 @@ void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) {
QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) { QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) {
setValue(d); setValue(d);
if (QDialog::exec() != QDialog::Accepted) if (QDialog::exec() != QDialog::Accepted) return QAD::IODevice();
return QAD::IODevice();
return value(); return value();
} }

View File

@@ -20,10 +20,11 @@
#ifndef PIQT_IODEVICE_EDIT_DIALOG_H #ifndef PIQT_IODEVICE_EDIT_DIALOG_H
#define PIQT_IODEVICE_EDIT_DIALOG_H #define PIQT_IODEVICE_EDIT_DIALOG_H
#include <QDialog>
#include "qad_types.h"
#include "propertystorage.h" #include "propertystorage.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include "qad_types.h"
#include <QDialog>
namespace Ui { namespace Ui {
class IODeviceEditDialog; class IODeviceEditDialog;
@@ -31,6 +32,7 @@ namespace Ui {
class QAD_PIQT_UTILS_EXPORT IODeviceEditDialog: public QDialog { class QAD_PIQT_UTILS_EXPORT IODeviceEditDialog: public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit IODeviceEditDialog(QWidget * parent = 0); explicit IODeviceEditDialog(QWidget * parent = 0);
~IODeviceEditDialog(); ~IODeviceEditDialog();
@@ -48,7 +50,6 @@ private:
private slots: private slots:
void on_comboType_currentIndexChanged(int index); void on_comboType_currentIndexChanged(int index);
}; };
#endif // PIQT_IODEVICE_EDIT_DIALOG_H #endif // PIQT_IODEVICE_EDIT_DIALOG_H

View File

@@ -42,8 +42,7 @@ void Camera::anglesFromPoints() {
void Camera::apply(const GLfloat & aspect) { void Camera::apply(const GLfloat & aspect) {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
if (aspect <= 1.f) if (aspect <= 1.f) glScalef(aspect, aspect, 1.f);
glScalef(aspect, aspect, 1.f);
QMatrix4x4 pm = glMatrixPerspective(fov_, aspect, depth_start, depth_end); QMatrix4x4 pm = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
// pm.perspective(fov_, aspect, depth_start, depth_end); // pm.perspective(fov_, aspect, depth_start, depth_end);
// qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end); // qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end);
@@ -287,4 +286,3 @@ void Camera::flyToDistance(const float & d) {
pos_ = aim_ - dv * d; pos_ = aim_ - dv * d;
buildTransform(); buildTransform();
} }

View File

@@ -26,19 +26,35 @@ class Camera;
// extern QMatrix4x4 globCameraMatrix; // extern QMatrix4x4 globCameraMatrix;
// extern Camera * currentCamera; // extern Camera * currentCamera;
class Camera: public GLObjectBase class Camera: public GLObjectBase {
{
friend class QGLView; friend class QGLView;
friend class GLParticlesSystem; friend class GLParticlesSystem;
friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p); friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p); friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
public: public:
Camera(); Camera();
void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();} void setPos(const QVector3D & p) {
void setAim(const QVector3D & p) {aim_ = p; anglesFromPoints(); buildTransform();} pos_ = p;
void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();} anglesFromPoints();
void move(const float & x, const float & y = 0., const float & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();} buildTransform();
}
void setAim(const QVector3D & p) {
aim_ = p;
anglesFromPoints();
buildTransform();
}
void move(const QVector3D & p) {
pos_ += p;
aim_ += p;
buildTransform();
}
void move(const float & x, const float & y = 0., const float & z = 0.) {
pos_ += QVector3D(x, y, z);
aim_ += QVector3D(x, y, z);
buildTransform();
}
void moveForward(const float & x, bool withZ = true); void moveForward(const float & x, bool withZ = true);
void moveBackward(const float & x, bool withZ = true) { moveForward(-x, withZ); } void moveBackward(const float & x, bool withZ = true) { moveForward(-x, withZ); }
void moveLeft(const float & x, bool withZ = true); void moveLeft(const float & x, bool withZ = true);
@@ -47,7 +63,10 @@ public:
void moveDown(const float & x, bool onlyZ = false) { moveUp(-x, onlyZ); } void moveDown(const float & x, bool onlyZ = false) { moveUp(-x, onlyZ); }
void rotateZ(const float & a); void rotateZ(const float & a);
void rotateXY(const float & a); void rotateXY(const float & a);
void rotateRoll(const float & a) {angles_.setX(angles_.x() + a); buildTransform();} void rotateRoll(const float & a) {
angles_.setX(angles_.x() + a);
buildTransform();
}
void orbitZ(const float & a); void orbitZ(const float & a);
void orbitXY(const float & a); void orbitXY(const float & a);
void panZ(const float & a); void panZ(const float & a);
@@ -56,10 +75,23 @@ public:
void setAngles(const QVector3D & a) { setRotation(a); } void setAngles(const QVector3D & a) { setRotation(a); }
void setAngleZ(const float & a); void setAngleZ(const float & a);
void setAngleXY(const float & a); void setAngleXY(const float & a);
void setAngleRoll(const float & a) {angles_.setX(a); buildTransform();} void setAngleRoll(const float & a) {
void setAngleLowerLimitXY(const float & a) {angle_limit_lower_xy = a; buildTransform();} angles_.setX(a);
void setAngleUpperLimitXY(const float & a) {angle_limit_upper_xy = a; buildTransform();} buildTransform();
void setAngleLimitsXY(const float & lower, const float & upper) {angle_limit_lower_xy = lower; angle_limit_upper_xy = upper; buildTransform();} }
void 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 setDepthStart(const float & d) { depth_start = d; }
void setDepthEnd(const float & d) { depth_end = d; } void setDepthEnd(const float & d) { depth_end = d; }
void setMirrorX(bool yes) { mirror_x = yes; } void setMirrorX(bool yes) { mirror_x = yes; }
@@ -71,7 +103,10 @@ public:
QVector3D aim() const { return aim_; } QVector3D aim() const { return aim_; }
QVector3D angles() const { return rotation(); } QVector3D angles() const { return rotation(); }
QVector3D direction() const { return (aim_ - pos_).normalized(); } QVector3D direction() const { return (aim_ - pos_).normalized(); }
QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();} QVector3D directionXY() const {
QVector3D tv = aim_ - pos_;
return QVector3D(tv.x(), tv.y(), 0.).normalized();
}
float FOV() const { return fov_; } float FOV() const { return fov_; }
float distance() const { return (pos_ - aim_).length(); } float distance() const { return (pos_ - aim_).length(); }
float angleZ() const { return angles_.z(); } float angleZ() const { return angles_.z(); }
@@ -100,7 +135,6 @@ private:
GLfloat angle_limit_upper_xy; GLfloat angle_limit_upper_xy;
bool mirror_x; bool mirror_x;
bool mirror_y; bool mirror_y;
}; };
#endif // GLCAMERA_H #endif // GLCAMERA_H

View File

@@ -19,12 +19,12 @@
#ifndef GLFRAMEBUFFER_H #ifndef GLFRAMEBUFFER_H
#define GLFRAMEBUFFER_H #define GLFRAMEBUFFER_H
#include <QOpenGLExtraFunctions>
#include "gltypes.h" #include "gltypes.h"
#include <QOpenGLExtraFunctions>
class GLFramebuffer : protected QOpenGLExtraFunctions
{ class GLFramebuffer: protected QOpenGLExtraFunctions {
public: public:
GLFramebuffer(int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum target = GL_TEXTURE_2D); GLFramebuffer(int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum target = GL_TEXTURE_2D);
virtual ~GLFramebuffer(); virtual ~GLFramebuffer();
@@ -45,22 +45,30 @@ public:
void setReadBuffer(int index) { glReadBuffer(GL_COLOR_ATTACHMENT0 + index); } void setReadBuffer(int index) { glReadBuffer(GL_COLOR_ATTACHMENT0 + index); }
void setWriteBuffer(int index); void setWriteBuffer(int index);
void setWriteBuffers(int * indeces, int count); void setWriteBuffers(int * indeces, int count);
void setColorFormat(GLenum format) {color_format = format; is_changed = true;} void setColorFormat(GLenum format) {
color_format = format;
is_changed = true;
}
void copyDepthFrom(GLuint tex) { ; } void copyDepthFrom(GLuint tex) { ; }
void bindColorTextures(); void bindColorTextures();
void bindDepthTexture(int channel); void bindDepthTexture(int channel);
private: private:
void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;} void deleteGLRenderbuffer(GLuint & drbo) {
void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;} if (drbo != 0) glDeleteRenderbuffers(1, &drbo);
drbo = 0;
}
void deleteGLFramebuffer(GLuint & fbo) {
if (fbo != 0) glDeleteFramebuffers(1, &fbo);
fbo = 0;
}
bool is_depth, is_changed; bool is_depth, is_changed;
QVector<GLuint> colors; QVector<GLuint> colors;
GLenum color_format, target_; GLenum color_format, target_;
GLuint fbo, drbo, tex_d; GLuint fbo, drbo, tex_d;
GLint prev_view[4], wid, hei; GLint prev_view[4], wid, hei;
}; };
#endif // GLFRAMEBUFFER_H #endif // GLFRAMEBUFFER_H

View File

@@ -59,28 +59,41 @@ void GLCubeTexture::load() {
void GLCubeTexture::loadFromDirectory(const QString & dir) { void GLCubeTexture::loadFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl; QDir d(dir);
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath()); QFileInfoList sl;
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath()); sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath()); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath()); sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath()); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath()); sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath());
} }
void GLCubeTexture::loadPathesFromDirectory(const QString & dir) { void GLCubeTexture::loadPathesFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl; QDir d(dir);
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath(); QFileInfoList sl;
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath(); sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath(); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath(); sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot);
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath(); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath(); sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot);
if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath();
} }
QString GLTextureManagerBase::findFile(const QString & path) { QString GLTextureManagerBase::findFile(const QString & path) {
return ::findFile(path, search_pathes); return ::findFile(path, search_pathes);
} }
@@ -162,9 +175,12 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
const uchar * sd = sim.constBits(); const uchar * sd = sim.constBits();
for (int i = 0; i < sim.height(); i++) { for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) { for (int j = 0; j < sim.width(); j++) {
sum[2] += sd[a] / 255.f - 0.5f; ++a; sum[2] += sd[a] / 255.f - 0.5f;
sum[1] += sd[a] / 255.f - 0.5f; ++a; ++a;
sum[0] += sd[a] / 255.f - 0.5f; ++a; sum[1] += sd[a] / 255.f - 0.5f;
++a;
sum[0] += sd[a] / 255.f - 0.5f;
++a;
++a; ++a;
} }
} }
@@ -199,10 +215,14 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
res.y = piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f); res.y = piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f);
res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f); res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
res.z = 1.; res.z = 1.;
dd[a] = res.z * 255; ++a; dd[a] = res.z * 255;
dd[a] = res.x * 255; ++a; ++a;
dd[a] = res.y * 255; ++a; dd[a] = res.x * 255;
dd[a] = 255; ++a; ++a;
dd[a] = res.y * 255;
++a;
dd[a] = 255;
++a;
} }
} }
im = dim; im = dim;
@@ -210,8 +230,6 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
} }
Material::Material(): map_reflection(512) { Material::Material(): map_reflection(512) {
color_diffuse = color_specular = Qt::white; color_diffuse = color_specular = Qt::white;
color_self_illumination = Qt::black; color_self_illumination = Qt::black;

View File

@@ -19,21 +19,37 @@
#ifndef GLMATERIAL_H #ifndef GLMATERIAL_H
#define GLMATERIAL_H #define GLMATERIAL_H
#include "gltypes.h"
#include "chunkstream.h" #include "chunkstream.h"
#include "gltypes.h"
class GLTexture { class GLTexture {
public: public:
GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {wid = _width; hei = _height; format_ = _format; target_ = _target; id_ = 0;} GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {
bool create() {destroy(); createGLTexture(id_, wid, hei, format_, target_); return id_ > 0;} wid = _width;
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;} hei = _height;
void bind() {if (id_ > 0) glBindTexture(target_, id_);} format_ = _format;
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); } void release() { glBindTexture(target_, 0); }
int width() const { return wid; } int width() const { return wid; }
int height() const { return hei; } int height() const { return hei; }
GLenum format() const { return format_; } GLenum format() const { return format_; }
GLenum target() const { return target_; } GLenum target() const { return target_; }
GLuint id() const { return id_; } GLuint id() const { return id_; }
private: private:
int wid, hei; int wid, hei;
GLenum format_, target_; GLenum format_, target_;
@@ -43,27 +59,95 @@ private:
class GLCubeTexture { class GLCubeTexture {
public: public:
GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);} GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {
size = _size;
format_ = _format;
id_ = 0;
changed_ = false;
pathes.resize(6);
}
bool create(); bool create();
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;} void destroy() {
void bind() {if (changed_) {changed_ = false; create();} if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);} if (id_ > 0) glDeleteTextures(1, &id_);
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 release() { glBindTexture(GL_TEXTURE_CUBE_MAP, 0); }
void resize(int _size) {size = _size; changed_ = true;} void resize(int _size) {
size = _size;
changed_ = true;
}
void loadFromDirectory(const QString & dir); void loadFromDirectory(const QString & dir);
void loadFront(const QString & path) {bind(); pathes[0] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_X);} void loadFront(const QString & path) {
void loadBack(const QString & path) {bind(); pathes[1] = path; createGLTexture(id_, rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);} bind();
void loadLeft(const QString & path) {bind(); pathes[2] = path; createGLTexture(id_, QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);} pathes[0] = path;
void loadRight(const QString & path) {bind(); pathes[3] = path; createGLTexture(id_, rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);} createGLTexture(id_,
void loadTop(const QString & path) {bind(); pathes[4] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);} rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
void loadBottom(const QString & path) {bind(); pathes[5] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);} format_,
GL_TEXTURE_CUBE_MAP_POSITIVE_X);
}
void loadBack(const QString & path) {
bind();
pathes[1] = path;
createGLTexture(id_,
rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
}
void loadLeft(const QString & path) {
bind();
pathes[2] = path;
createGLTexture(id_,
QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
}
void loadRight(const QString & path) {
bind();
pathes[3] = path;
createGLTexture(id_,
rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
}
void loadTop(const QString & path) {
bind();
pathes[4] = path;
createGLTexture(id_,
rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
}
void loadBottom(const QString & path) {
bind();
pathes[5] = path;
createGLTexture(id_,
rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
format_,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
}
void load(); void load();
bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;} bool isEmpty() const {
foreach(const QString & i, pathes)
if (!i.isEmpty()) return false;
return true;
}
GLenum format() const { return format_; } GLenum format() const { return format_; }
void setFormat(GLenum f) {format_ = f; changed_ = true;} void setFormat(GLenum f) {
format_ = f;
changed_ = true;
}
GLuint id() const { return id_; } GLuint id() const { return id_; }
const QString & path(int side) const { return pathes[side]; } const QString & path(int side) const { return pathes[side]; }
void setPath(int side, const QString & p) { pathes[side] = p; } void setPath(int side, const QString & p) { pathes[side] = p; }
void loadPathesFromDirectory(const QString & dir); void loadPathesFromDirectory(const QString & dir);
private: private:
bool changed_; bool changed_;
int size; int size;
@@ -94,12 +178,17 @@ protected:
static void convertToNormal(QImage & im); static void convertToNormal(QImage & im);
static QStringList search_pathes; static QStringList search_pathes;
QMap<QString, GLuint> tex_ids[2]; QMap<QString, GLuint> tex_ids[2];
}; };
class Map { class Map {
public: public:
Map() {bitmap_id = 0; color_amount = 1.f; color_offset = 0.f; animation_frame_rate = -1.f; bitmap_scale = QPointF(1., 1.);} Map() {
bitmap_id = 0;
color_amount = 1.f;
color_offset = 0.f;
animation_frame_rate = -1.f;
bitmap_scale = QPointF(1., 1.);
}
QString bitmap_path; QString bitmap_path;
GLuint bitmap_id; GLuint bitmap_id;
QPointF bitmap_offset; QPointF bitmap_offset;
@@ -139,8 +228,14 @@ public:
inline QDataStream & operator<<(QDataStream & s, const Map & m) { inline QDataStream & operator<<(QDataStream & s, const Map & m) {
ChunkStream cs; ChunkStream cs;
cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(4, m.animation).add(5, m.animation_frame_rate).add(6, m.bitmap_scale); cs.add(1, m.bitmap_path)
s << cs.data(); return s; .add(2, m.color_amount)
.add(3, m.color_offset)
.add(4, m.animation)
.add(5, m.animation_frame_rate)
.add(6, m.bitmap_scale);
s << cs.data();
return s;
} }
inline QDataStream & operator>>(QDataStream & s, Map & m) { inline QDataStream & operator>>(QDataStream & s, Map & m) {
ChunkStream cs(s); ChunkStream cs(s);
@@ -159,10 +254,21 @@ inline QDataStream & operator >>(QDataStream & s, Map & m) {
inline QDataStream & operator<<(QDataStream & s, const Material & m) { inline QDataStream & operator<<(QDataStream & s, const Material & m) {
ChunkStream cs; ChunkStream cs;
cs.add(1, m.name).add(2, m.color_diffuse).add(3, m.color_specular).add(4, m.color_self_illumination) cs.add(1, m.name)
.add(5, m.transparency).add(6, m.reflectivity).add(7, m.glass).add(8, m.map_diffuse).add(9, m.map_normal) .add(2, m.color_diffuse)
.add(10, m.map_relief).add(11, m.map_specular).add(12, m.map_specularity).add(13, m.map_self_illumination); .add(3, m.color_specular)
s << qCompress(cs.data()); return s; .add(4, m.color_self_illumination)
.add(5, m.transparency)
.add(6, m.reflectivity)
.add(7, m.glass)
.add(8, m.map_diffuse)
.add(9, m.map_normal)
.add(10, m.map_relief)
.add(11, m.map_specular)
.add(12, m.map_specularity)
.add(13, m.map_self_illumination);
s << qCompress(cs.data());
return s;
} }
inline QDataStream & operator>>(QDataStream & s, Material & m) { inline QDataStream & operator>>(QDataStream & s, Material & m) {
QByteArray ba; QByteArray ba;

View File

@@ -17,6 +17,7 @@
*/ */
#include "globject.h" #include "globject.h"
#include "glcamera.h" #include "glcamera.h"
#include "qglview.h" #include "qglview.h"
@@ -129,8 +130,7 @@ void GLObjectBase::setView(QGLView * v) {
void GLObjectBase::addChild(GLObjectBase * o) { void GLObjectBase::addChild(GLObjectBase * o) {
if (o == this) return; if (o == this) return;
if (o->parent_) if (o->parent_) o->parent_->children_.removeAll(o);
o->parent_->children_.removeAll(o);
children_ << o; children_ << o;
o->parent_ = this; o->parent_ = this;
o->setView((QGLView *)view_); o->setView((QGLView *)view_);
@@ -230,8 +230,10 @@ void GLObjectBase::rotateY(GLfloat a) {
void GLObjectBase::rotateZ(GLfloat a) { void GLObjectBase::rotateZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
angles_.setZ(angles_.z() + a); angles_.setZ(angles_.z() + a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); while (angles_.z() < -360.f)
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f); angles_.setZ(angles_.z() + 360.f);
while (angles_.z() > 360.f)
angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
@@ -253,8 +255,10 @@ void GLObjectBase::setRotationY(GLfloat a) {
void GLObjectBase::setRotationZ(GLfloat a) { void GLObjectBase::setRotationZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
angles_.setZ(a); angles_.setZ(a);
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); while (angles_.z() < -360.f)
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f); angles_.setZ(angles_.z() + 360.f);
while (angles_.z() > 360.f)
angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
@@ -284,7 +288,8 @@ void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * whe
void GLObjectBase::loadTextures(bool with_children) { void GLObjectBase::loadTextures(bool with_children) {
material_.loadTextures(view_->textureManager()); material_.loadTextures(view_->textureManager());
if (with_children) if (with_children)
foreach (GLObjectBase * i, children_) i->loadTextures(); foreach(GLObjectBase * i, children_)
i->loadTextures();
is_tex_loaded = true; is_tex_loaded = true;
checkPass(); checkPass();
} }
@@ -338,15 +343,15 @@ void GLObjectBase::setTransform(const QMatrix4x4 & t) {
void GLObjectBase::select() { void GLObjectBase::select() {
// qDebug() << "select" << name() << view_; // qDebug() << "select" << name() << view_;
selected_ = true; selected_ = true;
if (view_) if (view_) ((QGLView *)view_)->selectObject(this);
((QGLView*)view_)->selectObject(this);
} }
void GLObjectBase::setMaterial(const Material & m, bool with_children) { void GLObjectBase::setMaterial(const Material & m, bool with_children) {
material_ = m; material_ = m;
if (with_children) if (with_children)
foreach (GLObjectBase * i, children_) i->setMaterial(m, true); foreach(GLObjectBase * i, children_)
i->setMaterial(m, true);
checkPass(); checkPass();
is_tex_loaded = false; is_tex_loaded = false;
} }
@@ -355,8 +360,7 @@ void GLObjectBase::setMaterial(const Material & m, bool with_children) {
void GLObjectBase::buildTransform() { void GLObjectBase::buildTransform() {
itransform_.setToIdentity(); itransform_.setToIdentity();
GLObjectBase * p = parent_; GLObjectBase * p = parent_;
if (p) if (p) itransform_ = p->itransform_;
itransform_ = p->itransform_;
if (raw_matrix) { if (raw_matrix) {
itransform_.translate(pos_); itransform_.translate(pos_);
itransform_ *= mat_; itransform_ *= mat_;
@@ -372,7 +376,8 @@ void GLObjectBase::buildTransform() {
void GLObjectBase::initInternal() { void GLObjectBase::initInternal() {
init(); init();
loadTextures(); loadTextures();
foreach (GLObjectBase * i, children_) i->initInternal(); foreach(GLObjectBase * i, children_)
i->initInternal();
} }
@@ -386,8 +391,10 @@ void GLObjectBase::localTransform(QMatrix4x4 & m) {
void GLObjectBase::checkPass() { void GLObjectBase::checkPass() {
if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f) pass_ = Transparent; if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f)
else pass_ = Solid; pass_ = Transparent;
else
pass_ = Solid;
} }
@@ -424,8 +431,6 @@ void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_
} }
Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) { Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
@@ -486,8 +491,7 @@ void Light::draw(QOpenGLShaderProgram * prog, bool simplest) {
if (light_type != Omni) { if (light_type != Omni) {
glBegin(GL_LINES); glBegin(GL_LINES);
QVector4D dir = QVector4D(direction); QVector4D dir = QVector4D(direction);
if (raw_matrix) if (raw_matrix) dir = transform().inverted() * dir;
dir = transform().inverted() * dir;
glVertex3f(0., 0., 0.); glVertex3f(0., 0., 0.);
glVertex3f(dir.x() * s, dir.y() * s, dir.z() * s); glVertex3f(dir.x() * s, dir.y() * s, dir.z() * s);
glEnd(); glEnd();
@@ -516,8 +520,8 @@ QDataStream & operator <<(QDataStream & s, const GLObjectBase * p) {
// qDebug() << "place camera ..."; // qDebug() << "place camera ...";
const Camera * c = (const Camera *)p; const Camera * c = (const Camera *)p;
cs << cs.chunk(200, c->aim_) << cs.chunk(201, c->fov_) << cs.chunk(202, c->depth_start) << cs.chunk(203, c->depth_end) cs << cs.chunk(200, c->aim_) << cs.chunk(201, c->fov_) << cs.chunk(202, c->depth_start) << cs.chunk(203, c->depth_end)
<< cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy) << cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy) << cs.chunk(206, c->mirror_x)
<< cs.chunk(206, c->mirror_x) << cs.chunk(207, c->mirror_y); << cs.chunk(207, c->mirror_y);
} }
// qDebug() << "place" << p->name() << cs.data().size() << s.device()->size(); // qDebug() << "place" << p->name() << cs.data().size() << s.device()->size();
s << cs.data(); s << cs.data();
@@ -535,28 +539,52 @@ QDataStream & operator >>(QDataStream & s, GLObjectBase *& p) {
// qDebug() << "read obj ..."; // qDebug() << "read obj ...";
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1: case 1: {
{
GLObjectBase::Type type = (GLObjectBase::Type)cs.getData<int>(); GLObjectBase::Type type = (GLObjectBase::Type)cs.getData<int>();
switch (type) { switch (type) {
case GLObjectBase::glMesh: p = new GLObjectBase(); break; case GLObjectBase::glMesh: p = new GLObjectBase(); break;
case GLObjectBase::glLight: p = new Light(); l = (Light*)p; break; case GLObjectBase::glLight:
case GLObjectBase::glCamera: p = new Camera(); c = (Camera*)p; break; p = new Light();
l = (Light *)p;
break;
case GLObjectBase::glCamera:
p = new Camera();
c = (Camera *)p;
break;
default: break; default: break;
} }
if (p) p->type_ = type; if (p) p->type_ = type;
} } break;
case 2:
if (p) p->accept_light = cs.getData<bool>();
break;
case 3:
if (p) p->accept_fog = cs.getData<bool>();
break;
case 4:
if (p) p->visible_ = cs.getData<bool>();
break;
case 5:
if (p) p->cast_shadow = cs.getData<bool>();
break;
case 6:
if (p) p->rec_shadow = cs.getData<bool>();
break;
case 7:
if (p) p->raw_matrix = cs.getData<bool>();
break;
case 8:
if (p) p->line_width = cs.getData<float>();
break;
case 9:
if (p) p->render_mode = (GLObjectBase::RenderMode)cs.getData<int>();
break;
case 10:
if (p) p->material_ = cs.getData<Material>();
break;
case 11:
if (p) p->pos_ = cs.getData<QVector3D>();
break; break;
case 2: if (p) p->accept_light = cs.getData<bool>(); break;
case 3: if (p) p->accept_fog = cs.getData<bool>(); break;
case 4: if (p) p->visible_ = cs.getData<bool>(); break;
case 5: if (p) p->cast_shadow = cs.getData<bool>(); break;
case 6: if (p) p->rec_shadow = cs.getData<bool>(); break;
case 7: if (p) p->raw_matrix = cs.getData<bool>(); break;
case 8: if (p) p->line_width = cs.getData<float>(); break;
case 9: if (p) p->render_mode = (GLObjectBase::RenderMode)cs.getData<int>(); break;
case 10: if (p) p->material_ = cs.getData<Material>(); break;
case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break;
case 12: case 12:
if (p) p->angles_ = cs.getData<QVector3D>(); if (p) p->angles_ = cs.getData<QVector3D>();
if (c) { if (c) {
@@ -564,30 +592,78 @@ QDataStream & operator >>(QDataStream & s, GLObjectBase *& p) {
cam_angles = c->angles(); cam_angles = c->angles();
} }
break; break;
case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break; case 13:
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break; if (p) p->scale_ = cs.getData<QVector3D>();
case 15: if (p) p->vbo = cs.getData<GLVBO>(); break; break;
case 16: if (p) ccnt = cs.getData<int>(); break; case 14:
case 17: if (p) p->name_ = cs.getData<QString>(); break; if (p) p->mat_ = cs.getData<QMatrix4x4>();
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break; break;
case 100: if (l) l->direction = cs.getData<QVector3D>(); break; case 15:
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break; if (p) p->vbo = cs.getData<GLVBO>();
case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break; break;
case 103: if (l) l->intensity = cs.getData<GLfloat>(); break; case 16:
case 104: if (l) l->decay_const = cs.getData<GLfloat>(); break; if (p) ccnt = cs.getData<int>();
case 105: if (l) l->decay_linear = cs.getData<GLfloat>(); break; break;
case 106: if (l) l->decay_quadratic = cs.getData<GLfloat>(); break; case 17:
case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break; if (p) p->name_ = cs.getData<QString>();
case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break; break;
case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break; case 18:
case 200: if (c) c->setAim(cs.getData<QVector3D>()); break; if (p) p->meta = cs.getData<QVariantMap>();
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break; break;
case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break; case 100:
case 203: if (c) c->setDepthEnd(cs.getData<GLfloat>()); break; if (l) l->direction = cs.getData<QVector3D>();
case 204: if (c) c->setAngleLowerLimitXY(cs.getData<GLfloat>()); break; break;
case 205: if (c) c->setAngleUpperLimitXY(cs.getData<GLfloat>()); break; case 101:
case 206: if (c) c->mirror_x = cs.getData<bool>(); break; if (l) l->angle_start = cs.getData<GLfloat>();
case 207: if (c) c->mirror_y = cs.getData<bool>(); break; break;
case 102:
if (l) l->angle_end = cs.getData<GLfloat>();
break;
case 103:
if (l) l->intensity = cs.getData<GLfloat>();
break;
case 104:
if (l) l->decay_const = cs.getData<GLfloat>();
break;
case 105:
if (l) l->decay_linear = cs.getData<GLfloat>();
break;
case 106:
if (l) l->decay_quadratic = cs.getData<GLfloat>();
break;
case 107:
if (l) l->decay_start = cs.getData<GLfloat>();
break;
case 108:
if (l) l->decay_end = cs.getData<GLfloat>();
break;
case 109:
if (l) l->light_type = (Light::Type)cs.getData<int>();
break;
case 200:
if (c) c->setAim(cs.getData<QVector3D>());
break;
case 201:
if (c) c->setFOV(cs.getData<GLfloat>());
break;
case 202:
if (c) c->setDepthStart(cs.getData<GLfloat>());
break;
case 203:
if (c) c->setDepthEnd(cs.getData<GLfloat>());
break;
case 204:
if (c) c->setAngleLowerLimitXY(cs.getData<GLfloat>());
break;
case 205:
if (c) c->setAngleUpperLimitXY(cs.getData<GLfloat>());
break;
case 206:
if (c) c->mirror_x = cs.getData<bool>();
break;
case 207:
if (c) c->mirror_y = cs.getData<bool>();
break;
} }
} }
if (c) c->setAngles(cam_angles); if (c) c->setAngles(cam_angles);

View File

@@ -19,25 +19,43 @@
#ifndef GLOBJECT_H #ifndef GLOBJECT_H
#define GLOBJECT_H #define GLOBJECT_H
#include "glvbo.h"
#include "glframebuffer.h" #include "glframebuffer.h"
#include "glmaterial.h" #include "glmaterial.h"
#include "glvbo.h"
class Camera; class Camera;
class QGLView; class QGLView;
class GLObjectBase class GLObjectBase {
{
friend class QGLView; friend class QGLView;
friend class GLRendererBase; friend class GLRendererBase;
friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p); friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p); friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
friend GLObjectBase * loadFromQGLFile(const QString & filepath); friend GLObjectBase * loadFromQGLFile(const QString & filepath);
public: public:
enum Type {glMesh, glLight, glCamera, glParticlesSystem}; enum Type {
enum Pass {Solid, Transparent, Reflection, User}; glMesh,
enum GeomPrimitives {Triangles = GL_TRIANGLES, Quads = GL_QUADS}; glLight,
enum RenderMode {View = 0, Point = GL_POINT, Line = GL_LINE, Fill = GL_FILL}; glCamera,
glParticlesSystem
};
enum Pass {
Solid,
Transparent,
Reflection,
User
};
enum GeomPrimitives {
Triangles = GL_TRIANGLES,
Quads = GL_QUADS
};
enum RenderMode {
View = 0,
Point = GL_POINT,
Line = GL_LINE,
Fill = GL_FILL
};
explicit GLObjectBase(); explicit GLObjectBase();
virtual ~GLObjectBase(); virtual ~GLObjectBase();
@@ -89,19 +107,58 @@ public:
void setReceiveShadows(bool on) { rec_shadow = on; } void setReceiveShadows(bool on) { rec_shadow = on; }
void setCastShadows(bool on) { cast_shadow = on; } void setCastShadows(bool on) { cast_shadow = on; }
void move(const QVector3D & dv) {pos_ += dv; buildTransform();} void move(const QVector3D & dv) {
void moveTo(const QVector3D & dv) {pos_ = dv; buildTransform();} pos_ += dv;
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); buildTransform();} buildTransform();
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {moveTo(QVector3D(dx, dy, dz)); buildTransform();} }
void moveX(GLfloat o) {pos_.setX(pos_.x() + o); buildTransform();} void moveTo(const QVector3D & dv) {
void moveY(GLfloat o) {pos_.setY(pos_.y() + o); buildTransform();} pos_ = dv;
void moveZ(GLfloat o) {pos_.setZ(pos_.z() + o); buildTransform();} buildTransform();
void setPosX(GLfloat o) {pos_.setX(o); buildTransform();} }
void setPosY(GLfloat o) {pos_.setY(o); buildTransform();} void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
void setPosZ(GLfloat o) {pos_.setZ(o); buildTransform();} move(QVector3D(dx, dy, dz));
void setPos(GLfloat x, GLfloat y, GLfloat z) {pos_ = QVector3D(x, y, z); buildTransform();} buildTransform();
void setPos(const QVector3D & p) {pos_ = p; buildTransform();} }
void resetPos() {pos_ = QVector3D(0., 0., 0.); buildTransform();} void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
moveTo(QVector3D(dx, dy, dz));
buildTransform();
}
void moveX(GLfloat o) {
pos_.setX(pos_.x() + o);
buildTransform();
}
void moveY(GLfloat o) {
pos_.setY(pos_.y() + o);
buildTransform();
}
void moveZ(GLfloat o) {
pos_.setZ(pos_.z() + o);
buildTransform();
}
void setPosX(GLfloat o) {
pos_.setX(o);
buildTransform();
}
void setPosY(GLfloat o) {
pos_.setY(o);
buildTransform();
}
void setPosZ(GLfloat o) {
pos_.setZ(o);
buildTransform();
}
void setPos(GLfloat x, GLfloat y, GLfloat z) {
pos_ = QVector3D(x, y, z);
buildTransform();
}
void setPos(const QVector3D & p) {
pos_ = p;
buildTransform();
}
void resetPos() {
pos_ = QVector3D(0., 0., 0.);
buildTransform();
}
QVector3D pos() const { return pos_; } QVector3D pos() const { return pos_; }
float posX() const { return pos_.x(); } float posX() const { return pos_.x(); }
@@ -127,19 +184,71 @@ public:
float scaleX() { return scale_.x(); } float scaleX() { return scale_.x(); }
float scaleY() { return scale_.y(); } float scaleY() { return scale_.y(); }
float scaleZ() { return scale_.z(); } float scaleZ() { return scale_.z(); }
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();} void scale(const QVector3D & sv) {
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();} raw_matrix = false;
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();} scale_ *= sv;
void scale(GLfloat sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();} buildTransform();
void scaleX(GLfloat a) {raw_matrix = false; scale_.setX(scale_.x() + a); buildTransform();} }
void scaleY(GLfloat a) {raw_matrix = false; scale_.setY(scale_.y() + a); buildTransform();} void scale(GLfloat sx, GLfloat sy, GLfloat sz) {
void scaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(scale_.z() + a); buildTransform();} raw_matrix = false;
void setScale(const QVector3D & a) {raw_matrix = false; scale_ = a; buildTransform();} scale(QVector3D(sx, sy, sz));
void setScale(GLfloat a) {raw_matrix = false; scale_ = QVector3D(a, a, a); buildTransform();} buildTransform();
void setScaleX(GLfloat a) {raw_matrix = false; scale_.setX(a); buildTransform();} }
void setScaleY(GLfloat a) {raw_matrix = false; scale_.setY(a); buildTransform();} void scale(GLfloat sx, GLfloat sy) {
void setScaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(a); buildTransform();} raw_matrix = false;
void resetScale() {raw_matrix = false; scale_ = QVector3D(1., 1., 1.); buildTransform();} scale(QVector3D(sx, sy, sy));
buildTransform();
}
void scale(GLfloat sx) {
raw_matrix = false;
scale(QVector3D(sx, sx, sx));
buildTransform();
}
void scaleX(GLfloat a) {
raw_matrix = false;
scale_.setX(scale_.x() + a);
buildTransform();
}
void scaleY(GLfloat a) {
raw_matrix = false;
scale_.setY(scale_.y() + a);
buildTransform();
}
void scaleZ(GLfloat a) {
raw_matrix = false;
scale_.setZ(scale_.z() + a);
buildTransform();
}
void setScale(const QVector3D & a) {
raw_matrix = false;
scale_ = a;
buildTransform();
}
void setScale(GLfloat a) {
raw_matrix = false;
scale_ = QVector3D(a, a, a);
buildTransform();
}
void setScaleX(GLfloat a) {
raw_matrix = false;
scale_.setX(a);
buildTransform();
}
void setScaleY(GLfloat a) {
raw_matrix = false;
scale_.setY(a);
buildTransform();
}
void setScaleZ(GLfloat a) {
raw_matrix = false;
scale_.setZ(a);
buildTransform();
}
void resetScale() {
raw_matrix = false;
scale_ = QVector3D(1., 1., 1.);
buildTransform();
}
QMatrix4x4 transform() { return mat_; } QMatrix4x4 transform() { return mat_; }
void setTransform(const QMatrix4x4 & t); void setTransform(const QMatrix4x4 & t);
@@ -163,7 +272,10 @@ public:
void setWriteDepth(bool yes) {write_depth_ = yes;}*/ void setWriteDepth(bool yes) {write_depth_ = yes;}*/
QColor color() const { return material_.color_diffuse; } QColor color() const { return material_.color_diffuse; }
void setColor(const QColor & c) {material_.color_diffuse = c; checkPass();} void setColor(const QColor & c) {
material_.color_diffuse = c;
checkPass();
}
GLenum srcAlpha() const { return blend_src; } GLenum srcAlpha() const { return blend_src; }
GLenum destAlpha() const { return blend_dest; } GLenum destAlpha() const { return blend_dest; }
@@ -202,7 +314,8 @@ protected:
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const; QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
int pass_; // Pass int pass_; // Pass
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_,
raw_matrix;
bool is_root; bool is_root;
float line_width; float line_width;
Type type_; Type type_;
@@ -221,21 +334,30 @@ protected:
QGLViewBase * view_; QGLViewBase * view_;
GLVBO vbo; GLVBO vbo;
QVariantMap meta; QVariantMap meta;
}; };
inline bool operator <(const GLObjectBase & f, const GLObjectBase & s) {return f.pos_h.z() < s.pos_h.z();} inline bool operator<(const GLObjectBase & f, const GLObjectBase & s) {
return f.pos_h.z() < s.pos_h.z();
}
class Light: public GLObjectBase { class Light: public GLObjectBase {
friend class QGLView; friend class QGLView;
friend class GLRendererBase; friend class GLRendererBase;
public: public:
enum Type {Omni, Directional, Cone}; enum Type {
Omni,
Directional,
Cone
};
Light(); Light();
Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.); Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.);
virtual GLObjectBase * clone(bool withChildren = true); virtual GLObjectBase * clone(bool withChildren = true);
virtual void init() {shadow_map.resize(512, 512); is_init = true;} virtual void init() {
shadow_map.resize(512, 512);
is_init = true;
}
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
QVector3D direction, dir0, dir1; QVector3D direction, dir0, dir1;
@@ -252,14 +374,17 @@ public:
QMatrix4x4 shadow_matrix; QMatrix4x4 shadow_matrix;
protected: protected:
}; };
template<class T> template<class T>
inline T globject_cast(GLObjectBase * object) {return reinterpret_cast<T>(object);} inline T globject_cast(GLObjectBase * object) {
return reinterpret_cast<T>(object);
}
template<class T> template<class T>
inline T globject_cast(const GLObjectBase * object) {return reinterpret_cast<T>(object);} inline T globject_cast(const GLObjectBase * object) {
return reinterpret_cast<T>(object);
}
QDataStream & operator<<(QDataStream & s, const GLObjectBase * p); QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);

View File

@@ -17,8 +17,9 @@
*/ */
#include "globject_editor.h" #include "globject_editor.h"
#include "ui_globject_editor.h"
#include "glcamera.h" #include "glcamera.h"
#include "ui_globject_editor.h"
GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) { GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
@@ -37,11 +38,8 @@ GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
void GLObjectEditor::changeEvent(QEvent * e) { void GLObjectEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
@@ -135,7 +133,8 @@ void GLObjectEditor::objectChanged() {
l->decay_quadratic = ui->spinLightDecayQuadratic->value(); l->decay_quadratic = ui->spinLightDecayQuadratic->value();
l->angle_start = ui->spinLightAngleStart->value(); l->angle_start = ui->spinLightAngleStart->value();
l->angle_end = ui->spinLightAngleEnd->value(); l->angle_end = ui->spinLightAngleEnd->value();
l->direction = QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized(); l->direction =
QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
} }
if (object->type() == GLObjectBase::glCamera) { if (object->type() == GLObjectBase::glCamera) {
Camera * c = globject_cast<Camera *>(object); Camera * c = globject_cast<Camera *>(object);
@@ -150,14 +149,12 @@ void GLObjectEditor::objectChanged() {
void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) { void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
if (ui->spinLightAngleEnd->value() < v) if (ui->spinLightAngleEnd->value() < v) ui->spinLightAngleEnd->setValue(v);
ui->spinLightAngleEnd->setValue(v);
} }
void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) { void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
if (ui->spinLightAngleStart->value() > v) if (ui->spinLightAngleStart->value() > v) ui->spinLightAngleStart->setValue(v);
ui->spinLightAngleStart->setValue(v);
} }

View File

@@ -25,9 +25,9 @@ namespace Ui {
class GLObjectEditor; class GLObjectEditor;
}; };
class GLObjectEditor: public QWidget class GLObjectEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit GLObjectEditor(QWidget * parent = 0); explicit GLObjectEditor(QWidget * parent = 0);
@@ -50,7 +50,6 @@ private slots:
signals: signals:
void changed(); void changed();
}; };
#endif // GLOBJECT_EDITOR_H #endif // GLOBJECT_EDITOR_H

View File

@@ -58,16 +58,14 @@ void GLParticlesSystem::update() {
for (int i = 0; i < floor(need_birth); ++i) { for (int i = 0; i < floor(need_birth); ++i) {
cp.lifeDuration = lifeDuration_ + urand(lifeDurationJitter_); cp.lifeDuration = lifeDuration_ + urand(lifeDurationJitter_);
switch (emitterType_) { switch (emitterType_) {
case Omni: case Omni: cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_)); break;
cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_)); case Cone:
break; case Box:
case Cone: case Box:
cp.speed = emitterDirection_ * initialSpeed_ * (1.f + urand(speedJitter_)); cp.speed = emitterDirection_ * initialSpeed_ * (1.f + urand(speedJitter_));
cp.speed += orthToVector(cp.speed, speedDirectionJitter_); cp.speed += orthToVector(cp.speed, speedDirectionJitter_);
break; break;
} }
if (emitterType_ == Box) if (emitterType_ == Box) cp.pos = emitterRect_.randomPoint();
cp.pos = emitterRect_.randomPoint();
// qDebug() << "before" << cp.speed.length(); // qDebug() << "before" << cp.speed.length();
lengthenVector(cp.speed, additionalSpeed); lengthenVector(cp.speed, additionalSpeed);
// qDebug() << "after" << cp.speed.length(); // qDebug() << "after" << cp.speed.length();
@@ -80,9 +78,12 @@ void GLParticlesSystem::update() {
else else
cp.animationFrameRate = material_.diffuse.animation_frame_rate; cp.animationFrameRate = material_.diffuse.animation_frame_rate;
}*/ }*/
if (tex_scale.isEmpty()) cp.tex_rect.setSize(tex_rect.size()); if (tex_scale.isEmpty())
else cp.tex_rect.setSize(tex_rect.size() * tex_scale); cp.tex_rect.setSize(tex_rect.size());
cp.tex_rect.moveTopLeft(tex_rect.topLeft() + QPointF(uprand(tex_rect.width() - cp.tex_rect.width()), uprand(tex_rect.height() - cp.tex_rect.height()))); else
cp.tex_rect.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; // cp.tex_rect = tex_rect;
particles.push_back(cp); particles.push_back(cp);
} }
@@ -118,8 +119,7 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
// qDebug() << camera.angles(); // qDebug() << camera.angles();
// qDebug() << camera.angle_xy; // qDebug() << camera.angle_xy;
GLfloat cxyc, czs, czc; GLfloat cxyc, czs, czc;
GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(), GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(), tr_g = material_.color_diffuse.greenF(),
tr_g = material_.color_diffuse.greenF(),
tr_b = material_.color_diffuse.blueF(), tr_b = material_.color_diffuse.blueF(),
tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency); tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency);
// cxys = sin(camera.angle_xy * deg2rad); // cxys = sin(camera.angle_xy * deg2rad);
@@ -205,7 +205,6 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
} }
GLParticlesSystem::Particle::Particle(float life_dur) { GLParticlesSystem::Particle::Particle(float life_dur) {
size = 1.; size = 1.;
angle = lifeCurrent = 0.; angle = lifeCurrent = 0.;

View File

@@ -19,13 +19,16 @@
#ifndef GLPARTICLES_SYSTEM_H #ifndef GLPARTICLES_SYSTEM_H
#define GLPARTICLES_SYSTEM_H #define GLPARTICLES_SYSTEM_H
#include <QMutex>
#include "gltexture_manager.h"
#include "globject.h"
#include "glcamera.h" #include "glcamera.h"
#include "globject.h"
#include "gltexture_manager.h"
class GLParticlesSystem: public QObject, public GLObjectBase, protected QOpenGLFunctions #include <QMutex>
{
class GLParticlesSystem
: public QObject
, public GLObjectBase
, protected QOpenGLFunctions {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float birthRate READ birthRate WRITE setBirthRate) Q_PROPERTY(float birthRate READ birthRate WRITE setBirthRate)
Q_PROPERTY(float lifeDuration READ lifeDuration WRITE setLifeDuration) Q_PROPERTY(float lifeDuration READ lifeDuration WRITE setLifeDuration)
@@ -47,11 +50,16 @@ class GLParticlesSystem: public QObject, public GLObjectBase, protected QOpenGLF
Q_PROPERTY(bool active READ isActive WRITE setActive) Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(bool birthEnabled READ isBirthEnabled WRITE setBirthEnabled) Q_PROPERTY(bool birthEnabled READ isBirthEnabled WRITE setBirthEnabled)
Q_PROPERTY(float fadeTime READ fadeTime WRITE setFadeTime) Q_PROPERTY(float fadeTime READ fadeTime WRITE setFadeTime)
public: public:
GLParticlesSystem(const QVector3D & pos = QVector3D()); GLParticlesSystem(const QVector3D & pos = QVector3D());
~GLParticlesSystem() { ; } ~GLParticlesSystem() { ; }
enum Type {Cone, Omni, Box}; enum Type {
Cone,
Omni,
Box
};
struct Particle { struct Particle {
Particle(float life_dur = 40.); Particle(float life_dur = 40.);
@@ -95,7 +103,10 @@ public:
float fadeTime() const { return fade_time; } float fadeTime() const { return fade_time; }
bool isAddVerticalFaceEnabled() const { return add_vert_face; } bool isAddVerticalFaceEnabled() const { return add_vert_face; }
void setBirthRate(const float & arg) {birthRate_ = arg; tick_birth = birthRate_ / freq;} void setBirthRate(const float & arg) {
birthRate_ = arg;
tick_birth = birthRate_ / freq;
}
void setLifeDuration(const float & arg) { lifeDuration_ = arg; } void setLifeDuration(const float & arg) { lifeDuration_ = arg; }
void setSize(const float & arg) { size_ = arg; } void setSize(const float & arg) { size_ = arg; }
void setEnlargeSpeed(const float & arg) { enlargeSpeed_ = arg; } void setEnlargeSpeed(const float & arg) { enlargeSpeed_ = arg; }
@@ -145,9 +156,10 @@ private:
float lifeDurationJitter_, speedJitter_, speedDirectionJitter_, sizeJitter_, angleJitter_, initialAngle_; float lifeDurationJitter_, speedJitter_, speedDirectionJitter_, sizeJitter_, angleJitter_, initialAngle_;
float enlargeSpeed_, enlargeSpeedJitter_, baseAngle_; float enlargeSpeed_, enlargeSpeedJitter_, baseAngle_;
bool active_, birthEnabled_, is_diffuse_anim, add_vert_face; bool active_, birthEnabled_, is_diffuse_anim, add_vert_face;
}; };
inline bool operator <(const GLParticlesSystem::Particle & f, const GLParticlesSystem::Particle & s) {return f.pos_h.z() > s.pos_h.z();} inline bool operator<(const GLParticlesSystem::Particle & f, const GLParticlesSystem::Particle & s) {
return f.pos_h.z() > s.pos_h.z();
}
#endif // GLPARTICLES_SYSTEM_H #endif // GLPARTICLES_SYSTEM_H

View File

@@ -28,7 +28,6 @@ void GLPrimitivePoint::draw(QOpenGLShaderProgram * prog, bool simplest) {
} }
void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) { void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) {
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF()); glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
glBegin(GL_LINES); glBegin(GL_LINES);
@@ -38,7 +37,6 @@ void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) {
} }
GLPrimitiveCube::GLPrimitiveCube(float width, float length, float height, QVector3D pos): GLObjectBase() { GLPrimitiveCube::GLPrimitiveCube(float width, float length, float height, QVector3D pos): GLObjectBase() {
geom_prim = Quads; geom_prim = Quads;
w = width; w = width;
@@ -53,7 +51,8 @@ void GLPrimitiveCube::init() {
float hw = w / 2.f, hl = l / 2.f, hh = h / 2.f; float hw = w / 2.f, hl = l / 2.f, hh = h / 2.f;
// list = glGenLists(1); // list = glGenLists(1);
// glNewList(list, GL_COMPILE); // glNewList(list, GL_COMPILE);
//glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(), material_.color_diffuse.alphaF()); // glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(),
// material_.color_diffuse.alphaF());
vbo.init(); vbo.init();
QVector<GLfloat> &d_vertices(vbo.vertices()), &d_normals(vbo.normals()), &d_uvs(vbo.texcoords()); QVector<GLfloat> &d_vertices(vbo.vertices()), &d_normals(vbo.normals()), &d_uvs(vbo.texcoords());
d_vertices.clear(); d_vertices.clear();
@@ -125,9 +124,12 @@ void GLPrimitiveEllipsoid::putTriangle(const QVector3D & v0, const QVector3D & v
vbo.normals() << n.x() << n.y() << n.z(); vbo.normals() << n.x() << n.y() << n.z();
return; return;
QVector3D s(w, l, h); QVector3D s(w, l, h);
n = (v0 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z(); n = (v0 * s).normalized();
n = (v1 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z(); vbo.normals() << n.x() << n.y() << n.z();
n = (v2 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z(); n = (v1 * s).normalized();
vbo.normals() << n.x() << n.y() << n.z();
n = (v2 * s).normalized();
vbo.normals() << n.x() << n.y() << n.z();
} }
@@ -161,7 +163,8 @@ void GLPrimitiveEllipsoid::init() {
} }
} }
} }
if (i == 1) putTriangle(points[0], points[ret - wlseg * 2 + 1], points[ret]); if (i == 1)
putTriangle(points[0], points[ret - wlseg * 2 + 1], points[ret]);
else { else {
putTriangle(points[ret - wlseg * 2 + 1], points[ret], points[ret - wlseg * 2]); putTriangle(points[ret - wlseg * 2 + 1], points[ret], points[ret - wlseg * 2]);
putTriangle(points[ret - wlseg * 2 + 1], points[ret - wlseg * 2], points[ret - wlseg * 4 + 1]); putTriangle(points[ret - wlseg * 2 + 1], points[ret - wlseg * 2], points[ret - wlseg * 4 + 1]);

View File

@@ -22,51 +22,53 @@
#include "globject.h" #include "globject.h"
class GLPrimitivePoint: public GLObjectBase class GLPrimitivePoint: public GLObjectBase {
{
public: public:
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) { sz = 8.; } GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) { sz = 8.; }
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
private: private:
double sz; double sz;
}; };
class GLPrimitiveLine: public GLObjectBase {
class GLPrimitiveLine: public GLObjectBase
{
public: public:
GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {p0 = p0_; p1 = p1_;} GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {
p0 = p0_;
p1 = p1_;
}
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
QVector3D point0() const { return p0; } QVector3D point0() const { return p0; }
QVector3D point1() const { return p1; } QVector3D point1() const { return p1; }
void setPoint0(const QVector3D & p) { p0 = p; } void setPoint0(const QVector3D & p) { p0 = p; }
void setPoint1(const QVector3D & p) { p1 = p; } void setPoint1(const QVector3D & p) { p1 = p; }
private: private:
QVector3D p0, p1; QVector3D p0, p1;
}; };
class GLPrimitiveCube: public GLObjectBase {
class GLPrimitiveCube: public GLObjectBase
{
public: public:
GLPrimitiveCube(float width = 1., float length = 1., float height = 1., QVector3D pos = QVector3D()); GLPrimitiveCube(float width = 1., float length = 1., float height = 1., QVector3D pos = QVector3D());
virtual void init(); virtual void init();
private: private:
float w, l, h; float w, l, h;
}; };
class GLPrimitiveEllipsoid: public GLObjectBase {
class GLPrimitiveEllipsoid: public GLObjectBase
{
public: public:
GLPrimitiveEllipsoid(float width = 1., float length = 1., float height = 1., int seg_wl = 10, int seg_h = 10, QVector3D pos = QVector3D()); GLPrimitiveEllipsoid(float width = 1.,
float length = 1.,
float height = 1.,
int seg_wl = 10,
int seg_h = 10,
QVector3D pos = QVector3D());
virtual void init(); virtual void init();
private: private:
void putTriangle(const QVector3D & v0, const QVector3D & v1, const QVector3D & v2); void putTriangle(const QVector3D & v0, const QVector3D & v1, const QVector3D & v2);
float w, l, h; float w, l, h;
@@ -74,8 +76,7 @@ private:
}; };
class GLPrimitiveAxis: public GLObjectBase class GLPrimitiveAxis: public GLObjectBase {
{
public: public:
GLPrimitiveAxis() { accept_fog = accept_light = cast_shadow = rec_shadow = select_ = false; } GLPrimitiveAxis() { accept_fog = accept_light = cast_shadow = rec_shadow = select_ = false; }
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false); virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);

View File

@@ -17,6 +17,7 @@
*/ */
#include "glrendererbase.h" #include "glrendererbase.h"
#include "globject.h" #include "globject.h"
#include "qglview.h" #include "qglview.h"
@@ -57,11 +58,12 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
if (l.light_type == Light::Cone) { if (l.light_type == Light::Cone) {
glLightfv(gl_index, GL_SPOT_DIRECTION, dir); glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_end / 2.f); glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_end / 2.f);
glLightf(gl_index, GL_SPOT_EXPONENT, (1.f - piClamp<float>((l.angle_end - l.angle_start) / (l.angle_end + 0.001f), 0., 1.f)) * 128.f); glLightf(gl_index,
GL_SPOT_EXPONENT,
(1.f - piClamp<float>((l.angle_end - l.angle_start) / (l.angle_end + 0.001f), 0., 1.f)) * 128.f);
} else { } else {
glLightf(gl_index, GL_SPOT_CUTOFF, 180.); glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
} }
} }
@@ -86,10 +88,13 @@ void GLRendererBase::setupShadersLights(int lights_count) {
} }
#define BIND_TEXTURE(ch, map) if (rp.prev_tex[ch] != mat.map.bitmap_id) { \ #define BIND_TEXTURE(ch, map) \
if (rp.prev_tex[ch] != mat.map.bitmap_id) { \
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); \ glActiveTexture(GL_TEXTURE0 + ch); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.feature(QGLView::qglAnisotropicLevel).toInt());} glBindTexture(GL_TEXTURE_2D, mat.map.bitmap_id); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.feature(QGLView::qglAnisotropicLevel).toInt()); \
}
void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) { void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) {
if (first_object) { if (first_object) {
@@ -99,12 +104,30 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
setupShadersTextures(o, rp); setupShadersTextures(o, rp);
Material & mat(o.material_); Material & mat(o.material_);
if (rp.light) { if (rp.light) {
if (o.accept_light) {if (!rp.prev_light) {glSetLightEnabled(true); rp.prev_light = true;}} if (o.accept_light) {
else {if (rp.prev_light) {glSetLightEnabled(false); rp.prev_light = false;}} if (!rp.prev_light) {
glSetLightEnabled(true);
rp.prev_light = true;
}
} else {
if (rp.prev_light) {
glSetLightEnabled(false);
rp.prev_light = false;
}
}
} }
if (rp.fog) { if (rp.fog) {
if (o.accept_fog) {if (!rp.prev_fog) {glSetFogEnabled(true); rp.prev_fog = true;}} if (o.accept_fog) {
else {if (rp.prev_fog) {glSetFogEnabled(false); rp.prev_fog = false;}} if (!rp.prev_fog) {
glSetFogEnabled(true);
rp.prev_fog = true;
}
} else {
if (rp.prev_fog) {
glSetFogEnabled(false);
rp.prev_fog = false;
}
}
} }
if (rp.textures) { if (rp.textures) {
BIND_TEXTURE(0, map_diffuse) BIND_TEXTURE(0, map_diffuse)
@@ -166,7 +189,8 @@ void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, boo
rpl.prev_proj_matrix = rp.prev_proj_matrix; rpl.prev_proj_matrix = rp.prev_proj_matrix;
rpl.cam_offset_matrix = view.camera()->offsetMatrix(); rpl.cam_offset_matrix = view.camera()->offsetMatrix();
// qDebug() << "view:" << rp.view_matrix; // qDebug() << "view:" << rp.view_matrix;
for (int i = 0; i < 32; ++i) rpl.prev_tex[i] = 0; for (int i = 0; i < 32; ++i)
rpl.prev_tex[i] = 0;
setupTextures(view.objects_, rpl, true); setupTextures(view.objects_, rpl, true);
glSetLightEnabled(rpl.prev_light); glSetLightEnabled(rpl.prev_light);
glSetFogEnabled(rpl.prev_fog); glSetFogEnabled(rpl.prev_fog);
@@ -181,14 +205,13 @@ void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, boo
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) { void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) {
if (!o.isInit()) if (!o.isInit()) o.init();
o.init(); if (!o.isTexturesLoaded()) o.loadTextures();
if (!o.isTexturesLoaded())
o.loadTextures();
if (!o.visible_) return; if (!o.visible_) return;
if (rpl.pass == o.pass_) { if (rpl.pass == o.pass_) {
Material & mat(o.material_); Material & mat(o.material_);
QMatrix4x4 curview = rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_, prevview = rpl.prev_view_matrix * rpl.cam_offset_matrix * o.itransform_; QMatrix4x4 curview = rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_,
prevview = rpl.prev_view_matrix * rpl.cam_offset_matrix * o.itransform_;
setupTextures(o, rpl, false); setupTextures(o, rpl, false);
mat.apply((QOpenGLShaderProgram *)rpl.shaders); mat.apply((QOpenGLShaderProgram *)rpl.shaders);
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL)); glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
@@ -199,9 +222,12 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
glActiveTexture(GL_TEXTURE0 + 3); glActiveTexture(GL_TEXTURE0 + 3);
if (mat.reflectivity > 0.f) { if (mat.reflectivity > 0.f) {
glEnable(GL_TEXTURE_CUBE_MAP); glEnable(GL_TEXTURE_CUBE_MAP);
if (!mat.map_reflection.isEmpty()) mat.map_reflection.bind(); if (!mat.map_reflection.isEmpty())
else glDisable(GL_TEXTURE_CUBE_MAP); mat.map_reflection.bind();
} else glDisable(GL_TEXTURE_CUBE_MAP); else
glDisable(GL_TEXTURE_CUBE_MAP);
} else
glDisable(GL_TEXTURE_CUBE_MAP);
if (rpl.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP); if (rpl.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity}; GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -265,8 +291,7 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri
void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters & rpl) { void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters & rpl) {
if (!o.isInit()) if (!o.isInit()) o.init();
o.init();
if (!o.visible_) return; if (!o.visible_) return;
if (rpl.shaders) { if (rpl.shaders) {
// qDebug() << o.name() << curview << curview.determinant(); // qDebug() << o.name() << curview << curview.determinant();
@@ -275,7 +300,8 @@ void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters &
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
setGLMatrix(rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_); setGLMatrix(rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
} }
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL)); glPolygonMode(GL_FRONT_AND_BACK,
o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_); glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_);
glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_); glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_);
o.draw((QOpenGLShaderProgram *)rpl.shaders, true); o.draw((QOpenGLShaderProgram *)rpl.shaders, true);
@@ -284,8 +310,6 @@ void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters &
} }
GLRendererBase::RenderingParameters::RenderingParameters() { GLRendererBase::RenderingParameters::RenderingParameters() {
shaders = nullptr; shaders = nullptr;
cur_shader = nullptr; cur_shader = nullptr;

View File

@@ -22,10 +22,12 @@
#include "glcamera.h" #include "glcamera.h"
#include "glshaders.h" #include "glshaders.h"
class GLRendererBase: public QObject , protected QOpenGLExtraFunctions class GLRendererBase
{ : public QObject
, protected QOpenGLExtraFunctions {
friend class QGLView; friend class QGLView;
Q_OBJECT Q_OBJECT
public: public:
GLRendererBase(QGLView * view_); GLRendererBase(QGLView * view_);
virtual void prepareScene() { ; } virtual void prepareScene() { ; }
@@ -74,7 +76,6 @@ protected:
QGLView & view; QGLView & view;
QImage white_image, violent_image; QImage white_image, violent_image;
GLuint white_image_id, violent_image_id; GLuint white_image_id, violent_image_id;
}; };
#endif // GLRENDERERBASE_H #endif // GLRENDERERBASE_H

View File

@@ -32,13 +32,11 @@ const char qgl_vertex_head[] =
"in vec3 qgl_Vertex;\n" "in vec3 qgl_Vertex;\n"
"vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * vec4(qgl_Vertex, 1);}\n"; "vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * vec4(qgl_Vertex, 1);}\n";
const char qgl_fragment_head[] = const char qgl_fragment_head[] = "in vec2 qgl_FragTexture;\n"
"in vec2 qgl_FragTexture;\n"
"in vec4 qgl_FragColor;\n" "in vec4 qgl_FragColor;\n"
"out vec4 qgl_FragData[gl_MaxDrawBuffers];\n"; "out vec4 qgl_FragData[gl_MaxDrawBuffers];\n";
const char qgl_uniform[] = const char qgl_uniform[] = "uniform mat4 qgl_ModelViewMatrix;\n"
"uniform mat4 qgl_ModelViewMatrix;\n"
"uniform mat4 qgl_ProjectionMatrix;\n" "uniform mat4 qgl_ProjectionMatrix;\n"
"uniform mat4 qgl_ModelViewProjectionMatrix;\n" "uniform mat4 qgl_ModelViewProjectionMatrix;\n"
"uniform mat3 qgl_NormalMatrix;\n" "uniform mat3 qgl_NormalMatrix;\n"
@@ -52,8 +50,7 @@ const char qgl_uniform[] =
"uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n" "uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n"
"uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n"; "uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n";
const char qgl_structs[] = const char qgl_structs[] = "const int qgl_MaxLights = 8;\n"
"const int qgl_MaxLights = 8;\n"
"struct QGLLight {\n" "struct QGLLight {\n"
" vec4 color;\n" " vec4 color;\n"
" vec4 position;\n" " vec4 position;\n"
@@ -203,7 +200,6 @@ void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat) {
setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3, 6); setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3, 6);
setUniformMap(prog, "map_specularity", mat.map_specularity, 4, 6); setUniformMap(prog, "map_specularity", mat.map_specularity, 4, 6);
setUniformMap(prog, "map_specular", mat.map_specular, 5, 6); setUniformMap(prog, "map_specular", mat.map_specular, 5, 6);
} }
@@ -232,8 +228,7 @@ void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn
pos = m * pos; pos = m * pos;
dir = ((m * dir) - pos).normalized(); dir = ((m * dir) - pos).normalized();
float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f; float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f;
if (light->light_type == Light::Omni) if (light->light_type == Light::Omni) ang_start = ang_end = 180.;
ang_start = ang_end = 180.;
// qDebug() << "light" << light->name() << ulightn << pos; // qDebug() << "light" << light->name() << ulightn << pos;
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos); prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir); prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir);

View File

@@ -27,7 +27,11 @@ class Light;
QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file); QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file);
bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QString & dir = QString()); bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QString & dir = QString());
void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj = QMatrix4x4(), QMatrix4x4 prevview = QMatrix4x4()); void setUniformMatrices(QOpenGLShaderProgram * prog,
QMatrix4x4 proj,
QMatrix4x4 view,
QMatrix4x4 prevproj = QMatrix4x4(),
QMatrix4x4 prevview = QMatrix4x4());
void setUniformMap(QOpenGLShaderProgram * prog, const Map & map, int channel, int def_channel); void setUniformMap(QOpenGLShaderProgram * prog, const Map & map, int channel, int def_channel);
void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat); void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat);
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light *> & lights, const QMatrix4x4 & mat, int shadow_start); void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light *> & lights, const QMatrix4x4 & mat, int shadow_start);

View File

@@ -20,11 +20,11 @@
#define GLTEXTUREMANAGER_H #define GLTEXTUREMANAGER_H
#include "glmaterial.h" #include "glmaterial.h"
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
class GLTextureManager: public GLTextureManagerBase class GLTextureManager: public GLTextureManagerBase {
{
public: public:
GLTextureManager() { ; } GLTextureManager() { ; }
~GLTextureManager() { deleteTextures(); } ~GLTextureManager() { deleteTextures(); }
@@ -32,7 +32,10 @@ public:
struct Animation { struct Animation {
QString path; QString path;
QVector<GLuint> bitmaps; QVector<GLuint> bitmaps;
GLuint bitmapID(const int frame) {if (frame < 0 || frame >= bitmaps.size()) return 0; return bitmaps[frame];} GLuint bitmapID(const int frame) {
if (frame < 0 || frame >= bitmaps.size()) return 0;
return bitmaps[frame];
}
}; };
void addTexture(const QString & path) { tex_pathes << path; } void addTexture(const QString & path) { tex_pathes << path; }
@@ -40,14 +43,17 @@ public:
bool loadTextures(); bool loadTextures();
void deleteTextures(); void deleteTextures();
void deleteTexture(const QString & name); void deleteTexture(const QString & name);
Animation * findAnimation(const QString & name) {for (int i = 0; i < anim_ids.size(); ++i) if (anim_ids[i].first == name) return &(anim_ids[i].second); return 0;} Animation * findAnimation(const QString & name) {
for (int i = 0; i < anim_ids.size(); ++i)
if (anim_ids[i].first == name) return &(anim_ids[i].second);
return 0;
}
QVector<QPair<QString, Animation>> anim_ids; QVector<QPair<QString, Animation>> anim_ids;
private: private:
QStringList tex_pathes; QStringList tex_pathes;
QList<QPair<QString, QString>> anim_pathes; QList<QPair<QString, QString>> anim_pathes;
}; };
#endif // GLTEXTUREMANAGER_H #endif // GLTEXTUREMANAGER_H

View File

@@ -46,8 +46,7 @@ QString findFile(const QString & file, const QStringList & pathes) {
foreach(QString p, pathes) { foreach(QString p, pathes) {
QFileInfoList fil = QDir(p).entryInfoList(QStringList(fn), QDir::Files | QDir::NoDotAndDotDot); QFileInfoList fil = QDir(p).entryInfoList(QStringList(fn), QDir::Files | QDir::NoDotAndDotDot);
// qDebug() << "findFile" << fn << "in" << p << "->" << fil.size(); // qDebug() << "findFile" << fn << "in" << p << "->" << fil.size();
if (!fil.isEmpty()) if (!fil.isEmpty()) return fil[0].absoluteFilePath();
return fil[0].absoluteFilePath();
} }
return QString(); return QString();
} }
@@ -58,10 +57,8 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
glSetPolygonMode(GL_FILL); glSetPolygonMode(GL_FILL);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
int loc = prog ? prog->attributeLocation("qgl_Color") : -1, int loc = prog ? prog->attributeLocation("qgl_Color") : -1, locv = prog ? prog->attributeLocation("qgl_Vertex") : -1,
locv = prog ? prog->attributeLocation("qgl_Vertex") : -1, loct = prog ? prog->attributeLocation("qgl_Texture") : -1, locc = prog ? prog->attributeLocation("view_corner") : -1;
loct = prog ? prog->attributeLocation("qgl_Texture") : -1,
locc = prog ? prog->attributeLocation("view_corner") : -1;
// if (prog) {qDebug() << locv << loct << locc;} // if (prog) {qDebug() << locv << loct << locc;}
QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions();
if (prog) { if (prog) {
@@ -70,10 +67,18 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
static const GLfloat texs[] = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f}; static const GLfloat texs[] = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f};
GLfloat vcs[] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; GLfloat vcs[] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
if (corner_dirs) { if (corner_dirs) {
vcs[0] = corner_dirs[0].x(); vcs[1] = corner_dirs[0].y(); vcs[2] = corner_dirs[0].z(); vcs[0] = corner_dirs[0].x();
vcs[3] = corner_dirs[1].x(); vcs[4] = corner_dirs[1].y(); vcs[5] = corner_dirs[1].z(); vcs[1] = corner_dirs[0].y();
vcs[6] = corner_dirs[2].x(); vcs[7] = corner_dirs[2].y(); vcs[8] = corner_dirs[2].z(); vcs[2] = corner_dirs[0].z();
vcs[9] = corner_dirs[3].x(); vcs[10] = corner_dirs[3].y(); vcs[11] = corner_dirs[3].z(); vcs[3] = corner_dirs[1].x();
vcs[4] = corner_dirs[1].y();
vcs[5] = corner_dirs[1].z();
vcs[6] = corner_dirs[2].x();
vcs[7] = corner_dirs[2].y();
vcs[8] = corner_dirs[2].z();
vcs[9] = corner_dirs[3].x();
vcs[10] = corner_dirs[3].y();
vcs[11] = corner_dirs[3].z();
} }
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
@@ -96,10 +101,14 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
} else { } else {
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glTexCoord2f(0.f, 0.f); glVertex2f(x, y); glTexCoord2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex2f(x+w, y); glVertex2f(x, y);
glTexCoord2f(0.f, 1.f); glVertex2f(x, y+h); glTexCoord2f(1.f, 0.f);
glTexCoord2f(1.f, 1.f); glVertex2f(x+w, y+h); glVertex2f(x + w, y);
glTexCoord2f(0.f, 1.f);
glVertex2f(x, y + h);
glTexCoord2f(1.f, 1.f);
glVertex2f(x + w, y + h);
glEnd(); glEnd();
} }
} }
@@ -147,10 +156,8 @@ void createGLTexture(GLuint & tex, int width, int height, const GLenum & format,
else { else {
int t = GL_UNSIGNED_BYTE; int t = GL_UNSIGNED_BYTE;
int f = GL_RGBA; int f = GL_RGBA;
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F) if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F) t = GL_FLOAT;
t = GL_FLOAT; if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB) f = GL_RGB;
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB)
f = GL_RGB;
glTexImage2D(target, 0, format, width, height, 0, f, t, nullptr); glTexImage2D(target, 0, format, width, height, 0, f, t, nullptr);
// glGenerateMipmap(target); // glGenerateMipmap(target);
// qDebug() << "glTexImage2D" << width << height << QString::number(t, 16); // qDebug() << "glTexImage2D" << width << height << QString::number(t, 16);
@@ -214,14 +221,15 @@ QImage rotateQImageRight(const QImage & im) {
} }
QColor colorFromString(const QString & str) { QColor colorFromString(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
int i = s.indexOf("\t"); int i = s.indexOf("\t");
float r, g, b; float r, g, b;
r = s.left(i).toFloat(); s = s.right(s.length() - i - 1); i = s.indexOf("\t"); r = s.left(i).toFloat();
g = s.left(i).toFloat(); s = s.right(s.length() - i - 1); s = s.right(s.length() - i - 1);
i = s.indexOf("\t");
g = s.left(i).toFloat();
s = s.right(s.length() - i - 1);
b = s.toFloat(); b = s.toFloat();
return QColor(r * 255.f, g * 255.f, b * 255.f); return QColor(r * 255.f, g * 255.f, b * 255.f);
} }
@@ -230,9 +238,12 @@ QColor colorFromString(const QString & str) {
QVector3D orthToVector(const QVector3D & v, const float & scale) { QVector3D orthToVector(const QVector3D & v, const float & scale) {
if (v.isNull()) return QVector3D(); if (v.isNull()) return QVector3D();
QVector3D rv, fn, sn; QVector3D rv, fn, sn;
if (v.x() != 0.f) rv.setZ(1.); if (v.x() != 0.f)
else if (v.y() != 0.f) rv.setX(1.); rv.setZ(1.);
else rv.setY(1.); else if (v.y() != 0.f)
rv.setX(1.);
else
rv.setY(1.);
fn = QVector3D::crossProduct(v, rv).normalized(); fn = QVector3D::crossProduct(v, rv).normalized();
sn = QVector3D::crossProduct(v, fn).normalized(); sn = QVector3D::crossProduct(v, fn).normalized();
return fn * urand(scale) + sn * urand(scale); return fn * urand(scale) + sn * urand(scale);
@@ -267,8 +278,11 @@ void lengthenVector(QVector3D & v, const float & l) {
Vector3d::Vector3d(const QString & str) { Vector3d::Vector3d(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
int i = s.indexOf("\t"); int i = s.indexOf("\t");
x = s.left(i).toFloat(); s = s.right(s.length() - i - 1); i = s.indexOf("\t"); x = s.left(i).toFloat();
y = s.left(i).toFloat(); s = s.right(s.length() - i - 1); s = s.right(s.length() - i - 1);
i = s.indexOf("\t");
y = s.left(i).toFloat();
s = s.right(s.length() - i - 1);
z = s.toFloat(); z = s.toFloat();
} }
@@ -276,8 +290,11 @@ Vector3d::Vector3d(const QString & str) {
Vector3i::Vector3i(const QString & str) { Vector3i::Vector3i(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
int i = s.indexOf("\t"); int i = s.indexOf("\t");
p0 = s.left(i).toInt(); s = s.right(s.length() - i - 1); i = s.indexOf("\t"); p0 = s.left(i).toInt();
p1 = s.left(i).toInt(); s = s.right(s.length() - i - 1); s = s.right(s.length() - i - 1);
i = s.indexOf("\t");
p1 = s.left(i).toInt();
s = s.right(s.length() - i - 1);
p2 = s.toInt(); p2 = s.toInt();
} }
@@ -306,8 +323,6 @@ void glClearFramebuffer(const QColor & color, bool depth) {
} }
QGLViewBase::QGLViewBase() { QGLViewBase::QGLViewBase() {
camera_ = new Camera(); camera_ = new Camera();
textures_manager = new GLTextureManager(); textures_manager = new GLTextureManager();
@@ -347,9 +362,12 @@ Box3D::Box3D(const QVector<QVector3D> & points) {
iy = ay = points[0].y(); iy = ay = points[0].y();
iz = az = points[0].z(); iz = az = points[0].z();
for (int i = 1; i < points.size(); ++i) { for (int i = 1; i < points.size(); ++i) {
ix = qMin<float>(ix, points[i].x()); ax = qMax<float>(ax, points[i].x()); ix = qMin<float>(ix, points[i].x());
iy = qMin<float>(iy, points[i].y()); ay = qMax<float>(ay, points[i].y()); ax = qMax<float>(ax, points[i].x());
iz = qMin<float>(iz, points[i].z()); az = qMax<float>(az, points[i].z()); iy = qMin<float>(iy, points[i].y());
ay = qMax<float>(ay, points[i].y());
iz = qMin<float>(iz, points[i].z());
az = qMax<float>(az, points[i].z());
} }
x = ix; x = ix;
y = iy; y = iy;
@@ -363,20 +381,27 @@ Box3D::Box3D(const QVector<QVector3D> & points) {
QVector<QVector3D> Box3D::corners() const { QVector<QVector3D> Box3D::corners() const {
QVector<QVector3D> ret; QVector<QVector3D> ret;
ret << QVector3D(x, y, z) << QVector3D(x, y + width, z) << QVector3D(x, y, z + height) << QVector3D(x, y + width, z + height) ret << QVector3D(x, y, z) << QVector3D(x, y + width, z) << QVector3D(x, y, z + height) << QVector3D(x, y + width, z + height)
<< QVector3D(x + length, y, z) << QVector3D(x + length, y + width, z) << QVector3D(x + length, y, z) << QVector3D(x + length, y + width, z) << QVector3D(x + length, y, z + height)
<< QVector3D(x + length, y, z + height) << QVector3D(x + length, y + width, z + height); << QVector3D(x + length, y + width, z + height);
return ret; return ret;
} }
Box3D & Box3D::operator|=(const Box3D & o) { Box3D & Box3D::operator|=(const Box3D & o) {
if (isEmpty()) *this = o; if (isEmpty())
*this = o;
else { else {
GLfloat mx = x + length, my = y + width, mz = z + height; GLfloat mx = x + length, my = y + width, mz = z + height;
GLfloat omx = o.x + o.length, omy = o.y + o.width, omz = o.z + o.height; GLfloat omx = o.x + o.length, omy = o.y + o.width, omz = o.z + o.height;
x = qMin(x, o.x); y = qMin(y, o.y); z = qMin(z, o.z); x = qMin(x, o.x);
mx = qMax(mx, omx); my = qMax(my, omy); mz = qMax(mz, omz); y = qMin(y, o.y);
length = mx - x; width = my - y; height = mz - z; z = qMin(z, o.z);
mx = qMax(mx, omx);
my = qMax(my, omy);
mz = qMax(mz, omz);
length = mx - x;
width = my - y;
height = mz - z;
} }
return *this; return *this;
} }

View File

@@ -45,37 +45,37 @@
#include <QObject> #include <QObject>
#ifndef WINDOWS #ifndef WINDOWS
# ifdef MAC # ifdef MAC
# include <GLUT/glut.h>
# include <OpenGL/gl.h> # include <OpenGL/gl.h>
# include <OpenGL/glu.h> # include <OpenGL/glu.h>
# include <GLUT/glut.h>
# else # else
# include <GL/gl.h> # include <GL/gl.h>
# include <GL/glext.h> # include <GL/glext.h>
# include <GL/glu.h> # include <GL/glu.h>
# endif # endif
#endif #endif
#include <QColor>
#include <QDataStream>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QImage>
#include <QMatrix4x4>
#include <QMutex>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLWidget>
#include <QOpenGLShader> #include <QOpenGLShader>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <cmath> #include <QOpenGLWidget>
#include <float.h>
#include <QMatrix4x4>
#include <QDebug>
#include <QDataStream>
#include <QColor>
#include <QVector2D> #include <QVector2D>
#include <QVector3D> #include <QVector3D>
#include <QImage> #include <cmath>
#include <QMutex> #include <float.h>
#include <QFile>
#include <QDir>
#ifndef QNX #ifndef QNX
# include <cmath> # include <cmath>
# include <complex> # include <complex>
#else #else
# include <math.h>
# include <complex.h> # include <complex.h>
# include <math.h>
#endif #endif
#include <iostream> #include <iostream>
@@ -114,73 +114,164 @@ const float deg2rad = atanf(1.f) / 45.f;
const float rad2deg = 45.f / atanf(1.f); const float rad2deg = 45.f / atanf(1.f);
# ifdef WINDOWS # ifdef WINDOWS
inline int random() {return rand();} inline int random() {
return rand();
}
# endif # endif
#else #else
# define random randomi # define random randomi
#endif #endif
#ifdef CC_VC #ifdef CC_VC
inline float round(const float & v) {return floor(v + 0.5);} inline float round(const float & v) {
return floor(v + 0.5);
}
#endif #endif
inline float randomu() {return float(random()) / RAND_MAX;} inline float randomu() {
return float(random()) / RAND_MAX;
}
inline const QSizeF operator *(const QSizeF & f, const QSizeF & s) {return QSizeF(f.width() * s.width(), f.height() * s.height());} inline const QSizeF operator*(const QSizeF & f, const QSizeF & s) {
return QSizeF(f.width() * s.width(), f.height() * s.height());
}
#ifndef PIP_VERSION #ifndef PIP_VERSION
template<typename T> inline void piSwap(T & f, T & s) {T t(f); f = s; s = t;} template<typename T>
template<typename Type> inline Type piMin(const Type & f, const Type & s) {return (f > s) ? s : f;} inline void piSwap(T & f, T & s) {
template<typename Type> inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);} T t(f);
template<typename Type> inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;} f = s;
template<typename Type> inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);} s = t;
template<typename Type> inline Type piClamp(const Type & v, const Type & min, const Type & max) {return (v > max ? max : (v < min ? min : v));} }
inline ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);} template<typename Type>
inline Type piMin(const Type & f, const Type & s) {
return (f > s) ? s : f;
}
template<typename Type>
inline Type piMin(const Type & f, const Type & s, const Type & t) {
return (f < s && f < t) ? f : ((s < t) ? s : t);
}
template<typename Type>
inline Type piMax(const Type & f, const Type & s) {
return (f < s) ? s : f;
}
template<typename Type>
inline Type piMax(const Type & f, const Type & s, const Type & t) {
return (f > s && f > t) ? f : ((s > t) ? s : t);
}
template<typename Type>
inline Type piClamp(const Type & v, const Type & min, const Type & max) {
return (v > max ? max : (v < min ? min : v));
}
inline ushort letobe_s(ushort v) {
return (v << 8) | (v >> 8);
}
#endif #endif
// return [-1, 1] // return [-1, 1]
inline float urand(const float & scale = 1.) {return ((float)rand() / RAND_MAX - .5f) * (scale + scale);} inline float urand(const float & scale = 1.) {
return ((float)rand() / RAND_MAX - .5f) * (scale + scale);
}
// return [0, 1] // return [0, 1]
inline float uprand(const float & scale = 1.) {return ((float)rand() / RAND_MAX) * scale;} inline float uprand(const float & scale = 1.) {
return ((float)rand() / RAND_MAX) * scale;
}
QString readCharsUntilNull(QDataStream & s); QString readCharsUntilNull(QDataStream & s);
QString findFile(const QString & file, const QStringList & pathes); QString findFile(const QString & file, const QStringList & pathes);
inline QColor operator *(const QColor & c, float v) {return QColor(piClamp<int>(c.red() * v, 0, 255), piClamp<int>(c.green() * v, 0, 255), piClamp<int>(c.blue() * v, 0, 255), piClamp<int>(c.alpha() * v, 0, 255));} inline QColor operator*(const QColor & c, float v) {
inline QColor operator /(const QColor & c, float v) {return QColor(piClamp<int>(c.red() / v, 0, 255), piClamp<int>(c.green() / v, 0, 255), piClamp<int>(c.blue() / v, 0, 255), piClamp<int>(c.alpha() / v, 0, 255));} return QColor(piClamp<int>(c.red() * v, 0, 255),
piClamp<int>(c.green() * v, 0, 255),
piClamp<int>(c.blue() * v, 0, 255),
piClamp<int>(c.alpha() * v, 0, 255));
}
inline QColor operator/(const QColor & c, float v) {
return QColor(piClamp<int>(c.red() / v, 0, 255),
piClamp<int>(c.green() / v, 0, 255),
piClamp<int>(c.blue() / v, 0, 255),
piClamp<int>(c.alpha() / v, 0, 255));
}
// extern __GLWidget__ * currentQGLView; // extern __GLWidget__ * currentQGLView;
inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());} inline void qglColor(const QColor & c) {
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
}
void qglMultMatrix(const QMatrix4x4 & m); void qglMultMatrix(const QMatrix4x4 & m);
void glEnableDepth(); void glEnableDepth();
void glDisableDepth(); void glDisableDepth();
inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();} inline void glResetAllTransforms() {
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();} glMatrixMode(GL_TEXTURE);
inline void glClearAccumulation(const QColor & color = Qt::black) {glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_ACCUM_BUFFER_BIT);} glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
inline void glClearError() {
int c = 100;
while (glGetError() != GL_NO_ERROR && --c > 0)
glGetError();
}
inline void glClearAccumulation(const QColor & color = Qt::black) {
glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF());
glClear(GL_ACCUM_BUFFER_BIT);
}
void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true); void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true);
inline void glSetCapEnabled(GLenum cap, bool on = true) {if (on) glEnable(cap); else glDisable(cap);} inline void glSetCapEnabled(GLenum cap, bool on = true) {
inline void glSetLightEnabled(bool on) {if (on) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);} if (on)
inline void glSetFogEnabled(bool on) {if (on) glEnable(GL_FOG); else glDisable(GL_FOG);} glEnable(cap);
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);} else
void glDrawQuad(QOpenGLShaderProgram * prog = 0, QVector4D * corner_dirs = 0, GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f); glDisable(cap);
}
inline void glSetLightEnabled(bool on) {
if (on)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
inline void glSetFogEnabled(bool on) {
if (on)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
}
inline void glSetPolygonMode(GLenum mode) {
glPolygonMode(GL_FRONT_AND_BACK, mode);
}
void glDrawQuad(QOpenGLShaderProgram * prog = 0,
QVector4D * corner_dirs = 0,
GLfloat x = -1.f,
GLfloat y = -1.f,
GLfloat w = 2.f,
GLfloat h = 2.f);
QMatrix4x4 getGLMatrix(GLenum matrix); QMatrix4x4 getGLMatrix(GLenum matrix);
void setGLMatrix(QMatrix4x4 matrix); void setGLMatrix(QMatrix4x4 matrix);
inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;} inline void deleteGLTexture(GLuint & tex) {
if (tex != 0) glDeleteTextures(1, &tex);
tex = 0;
}
// # define QGLCI if (!QOpenGLContext::currentContext()) return; QOpenGLFunctions gf(QOpenGLContext::currentContext()); // # define QGLCI if (!QOpenGLContext::currentContext()) return; QOpenGLFunctions gf(QOpenGLContext::currentContext());
// # define QGLC gf. // # define QGLC gf.
// inline void glActiveTextureChannel(int channel) {QGLCI gf.glActiveTexture(GL_TEXTURE0 + channel);} // inline void glActiveTextureChannel(int channel) {QGLCI gf.glActiveTexture(GL_TEXTURE0 + channel);}
//inline void glDisableTextures(int channels = 8) {QGLCI for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}} // inline void glDisableTextures(int channels = 8) {QGLCI for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i);
//inline void glReleaseTextures(int channels = 8) {QGLCI for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}} // glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}} inline void glReleaseTextures(int channels = 8) {QGLCI for (int i = channels
//inline void glReleaseFramebuffer() {QGLCI gf.glBindFramebuffer(GL_FRAMEBUFFER, 0);} // - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}} inline void
//inline void glReleaseShaders() {QGLCI gf.glUseProgram(0);} // glReleaseFramebuffer() {QGLCI gf.glBindFramebuffer(GL_FRAMEBUFFER, 0);} inline void glReleaseShaders() {QGLCI gf.glUseProgram(0);} inline
//inline void deleteGLFramebuffer(GLuint & fbo) {QGLCI if (fbo != 0) gf.glDeleteFramebuffers(1, &fbo); fbo = 0;} // void deleteGLFramebuffer(GLuint & fbo) {QGLCI if (fbo != 0) gf.glDeleteFramebuffers(1, &fbo); fbo = 0;} inline void
//inline void deleteGLRenderbuffer(GLuint & drbo) {QGLCI if (drbo != 0) gf.glDeleteRenderbuffers(1, &drbo); drbo = 0;} // deleteGLRenderbuffer(GLuint & drbo) {QGLCI if (drbo != 0) gf.glDeleteRenderbuffers(1, &drbo); drbo = 0;} inline void
//inline void deleteGLBuffer(GLuint & bo) {QGLCI if (bo != 0) gf.glDeleteBuffers(1, &bo); bo = 0;} // deleteGLBuffer(GLuint & bo) {QGLCI if (bo != 0) gf.glDeleteBuffers(1, &bo); bo = 0;} inline void deleteGLVertexArray(GLuint & va) {QGLCI
//inline void deleteGLVertexArray(GLuint & va) {QGLCI if (va != 0) gf.glDeleteVertexArrays(1, &va); va = 0;} // if (va != 0) gf.glDeleteVertexArrays(1, &va); va = 0;}
void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D); void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D); void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
inline void qglTranslate(const QVector3D & v) {glTranslatef(v.x(), v.y(), v.z());} inline void qglTranslate(const QVector3D & v) {
inline void qglScale(const QVector3D & v) {glScalef(v.x(), v.y(), v.z());} glTranslatef(v.x(), v.y(), v.z());
}
inline void qglScale(const QVector3D & v) {
glScalef(v.x(), v.y(), v.z());
}
QMatrix4x4 glMatrixPerspective(float angle, float aspect, float near_, float far_); QMatrix4x4 glMatrixPerspective(float angle, float aspect, float near_, float far_);
QImage rotateQImageLeft(const QImage & im); QImage rotateQImageLeft(const QImage & im);
QImage rotateQImageRight(const QImage & im); QImage rotateQImageRight(const QImage & im);
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);} inline QImage rotateQImage180(const QImage & im) {
return im.mirrored(true, true);
}
// const double deg2rad = atan(1.) / 45.; // const double deg2rad = atan(1.) / 45.;
// const double rad2deg = 45. / atan(1.); // const double rad2deg = 45. / atan(1.);
@@ -195,7 +286,15 @@ struct Box3D {
GLfloat angle_xy; GLfloat angle_xy;
GLfloat angle_roll; GLfloat angle_roll;
Box3D() { x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f; } Box3D() { x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f; }
Box3D(const QVector3D & center, GLfloat hwid, GLfloat hlen, GLfloat hhei) {x = center.x() - hwid; y = center.y() - hlen; z = center.z() - hhei; width = 2 * hwid; length = 2 * hlen; height = 2 * hhei; angle_z = angle_xy = angle_roll = 0.f;} Box3D(const QVector3D & center, GLfloat hwid, GLfloat hlen, GLfloat hhei) {
x = center.x() - hwid;
y = center.y() - hlen;
z = center.z() - hhei;
width = 2 * hwid;
length = 2 * hlen;
height = 2 * hhei;
angle_z = angle_xy = angle_roll = 0.f;
}
Box3D(const QVector<QVector3D> & points); Box3D(const QVector<QVector3D> & points);
bool isEmpty() const { return (qAbs(width) < 1E-6f) || (qAbs(length) < 1E-6f) || (qAbs(height) < 1E-6f); } bool isEmpty() const { return (qAbs(width) < 1E-6f) || (qAbs(length) < 1E-6f) || (qAbs(height) < 1E-6f); }
QVector3D randomPoint() const { return QVector3D(uprand(length) + x, uprand(width) + y, uprand(height) + z); } QVector3D randomPoint() const { return QVector3D(uprand(length) + x, uprand(width) + y, uprand(height) + z); }
@@ -204,17 +303,54 @@ struct Box3D {
QVector3D center() const { return QVector3D(length / 2.f + x, width / 2.f + y, height / 2.f + z); } QVector3D center() const { return QVector3D(length / 2.f + x, width / 2.f + y, height / 2.f + z); }
QVector3D angles() const { return QVector3D(angle_xy, angle_roll, angle_z); } QVector3D angles() const { return QVector3D(angle_xy, angle_roll, angle_z); }
QVector<QVector3D> corners() const; QVector<QVector3D> corners() const;
void setPos(const QVector3D & p) {x = p.x(); y = p.y(); z = p.z();} void setPos(const QVector3D & p) {
void setAngles(const QVector3D & a) {angle_xy = a.x(); angle_roll = a.y(); angle_z = a.z();} x = p.x();
void setSize(const QVector3D & s) {length = s.x(); width = s.y(); height = s.z();} y = p.y();
Box3D & moveTo(const QVector3D & v) {x = v.x(); y = v.y(); z = v.z(); return *this;} z = p.z();
Box3D & move(const QVector3D & v) {x += v.x(); y += v.y(); z += v.z(); return *this;} }
Box3D movedTo(const QVector3D & v) const {Box3D t(*this); t.x = v.x(); t.y = v.y(); t.z = v.z(); return t;} void setAngles(const QVector3D & a) {
Box3D moved(const QVector3D & v) const {Box3D t(*this); t.x += v.x(); t.y += v.y(); t.z += v.z(); return t;} angle_xy = a.x();
angle_roll = a.y();
angle_z = a.z();
}
void setSize(const QVector3D & s) {
length = s.x();
width = s.y();
height = s.z();
}
Box3D & moveTo(const QVector3D & v) {
x = v.x();
y = v.y();
z = v.z();
return *this;
}
Box3D & move(const QVector3D & v) {
x += v.x();
y += v.y();
z += v.z();
return *this;
}
Box3D movedTo(const QVector3D & v) const {
Box3D t(*this);
t.x = v.x();
t.y = v.y();
t.z = v.z();
return t;
}
Box3D moved(const QVector3D & v) const {
Box3D t(*this);
t.x += v.x();
t.y += v.y();
t.z += v.z();
return t;
}
Box3D & operator|=(const Box3D & o); Box3D & operator|=(const Box3D & o);
}; };
inline QDebug operator <<(QDebug d, const Box3D & v) {d << "Box3D {start (" << v.x << "," << v.y << "," << v.z << "), size (" << v.length << "," << v.width << "," << v.height << ")}"; return d;} inline QDebug operator<<(QDebug d, const Box3D & v) {
d << "Box3D {start (" << v.x << "," << v.y << "," << v.z << "), size (" << v.length << "," << v.width << "," << v.height << ")}";
return d;
}
struct Vector3d; struct Vector3d;
@@ -224,8 +360,16 @@ struct Vector3d {
GLfloat x; GLfloat x;
GLfloat y; GLfloat y;
GLfloat z; GLfloat z;
Vector3d(GLfloat x_ = 0., GLfloat y_ = 0., GLfloat z_ = 0.) {x = x_; y = y_; z = z_;} Vector3d(GLfloat x_ = 0., GLfloat y_ = 0., GLfloat z_ = 0.) {
Vector3d(const QVector3D & v) {x = v.x(); y = v.y(); z = v.z();} x = x_;
y = y_;
z = z_;
}
Vector3d(const QVector3D & v) {
x = v.x();
y = v.y();
z = v.z();
}
Vector3d(const QString & str); Vector3d(const QString & str);
inline void clear() { x = y = z = 0.; } inline void clear() { x = y = z = 0.; }
inline GLfloat length() const { return sqrtf(x * x + y * y + z * z); } inline GLfloat length() const { return sqrtf(x * x + y * y + z * z); }
@@ -233,11 +377,16 @@ struct Vector3d {
Vector3d & normalize() { Vector3d & normalize() {
GLfloat l = length(); GLfloat l = length();
if (l == 0.f) return *this; if (l == 0.f) return *this;
x /= l; y /= l; z /= l; x /= l;
y /= l;
z /= l;
return *this; return *this;
} }
Vector3d normalized() { return Vector3d(*this).normalize(); } Vector3d normalized() { return Vector3d(*this).normalize(); }
Vector3d projectTo(Vector3d dir) {dir.normalize(); return dir * dot(dir, *this);} Vector3d projectTo(Vector3d dir) {
dir.normalize();
return dir * dot(dir, *this);
}
Vector3d operator*(const GLfloat v) { return Vector3d(x * v, y * v, z * v); } Vector3d operator*(const GLfloat v) { return Vector3d(x * v, y * v, z * v); }
Vector3d operator/(const GLfloat v) { return Vector3d(x / v, y / v, z / v); } Vector3d operator/(const GLfloat v) { return Vector3d(x / v, y / v, z / v); }
Vector3d operator+(const GLfloat v) { return Vector3d(x + v, y + v, z + v); } Vector3d operator+(const GLfloat v) { return Vector3d(x + v, y + v, z + v); }
@@ -245,12 +394,42 @@ struct Vector3d {
Vector3d operator+(const Vector3d & v) { return Vector3d(x + v.x, y + v.y, z + v.z); } Vector3d operator+(const Vector3d & v) { return Vector3d(x + v.x, y + v.y, z + v.z); }
Vector3d operator-(const Vector3d & v) { return Vector3d(x - v.x, y - v.y, z - v.z); } Vector3d operator-(const Vector3d & v) { return Vector3d(x - v.x, y - v.y, z - v.z); }
Vector3d operator-() { return Vector3d(-x, -y, -z); } Vector3d operator-() { return Vector3d(-x, -y, -z); }
Vector3d & operator *=(const GLfloat & v) {x *= v; y *= v; z *= v; return *this;} Vector3d & operator*=(const GLfloat & v) {
Vector3d & operator /=(const GLfloat & v) {x /= v; y /= v; z /= v; return *this;} x *= v;
Vector3d & operator +=(const GLfloat & v) {x += v; y += v; z += v; return *this;} y *= v;
Vector3d & operator -=(const GLfloat & v) {x -= v; y -= v; z -= v; return *this;} z *= v;
Vector3d & operator +=(const Vector3d & v) {x += v.x; y += v.y; z += v.z; return *this;} return *this;
Vector3d & operator -=(const Vector3d & v) {x -= v.x; y -= v.y; z -= v.z; return *this;} }
Vector3d & operator/=(const GLfloat & v) {
x /= v;
y /= v;
z /= v;
return *this;
}
Vector3d & operator+=(const GLfloat & v) {
x += v;
y += v;
z += v;
return *this;
}
Vector3d & operator-=(const GLfloat & v) {
x -= v;
y -= v;
z -= v;
return *this;
}
Vector3d & operator+=(const Vector3d & v) {
x += v.x;
y += v.y;
z += v.z;
return *this;
}
Vector3d & operator-=(const Vector3d & v) {
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}
bool operator==(const Vector3d & v) { return x == v.x && y == v.y && z == v.z; } bool operator==(const Vector3d & v) { return x == v.x && y == v.y && z == v.z; }
QVector3D toQVector3D() const { return QVector3D(x, y, z); } QVector3D toQVector3D() const { return QVector3D(x, y, z); }
}; };
@@ -258,13 +437,21 @@ struct Vector3d {
inline Vector3d operator*(const Vector3d & v0, const Vector3d & v1) { inline Vector3d operator*(const Vector3d & v0, const Vector3d & v1) {
return Vector3d(v0.y * v1.z - v1.y * v0.z, v1.x * v0.z - v0.x * v1.z, v0.x * v1.y - v1.x * v0.y); return Vector3d(v0.y * v1.z - v1.y * v0.z, v1.x * v0.z - v0.x * v1.z, v0.x * v1.y - v1.x * v0.y);
} }
inline GLfloat dot(const Vector3d & v0, const Vector3d & v1) {return v0.x*v1.x + v0.y*v1.y + v0.z*v1.z;} inline GLfloat dot(const Vector3d & v0, const Vector3d & v1) {
return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
}
struct Vector2d { struct Vector2d {
GLfloat x; GLfloat x;
GLfloat y; GLfloat y;
Vector2d(GLfloat x_ = 0., GLfloat y_ = 0.) {x = x_; y = y_;} Vector2d(GLfloat x_ = 0., GLfloat y_ = 0.) {
Vector2d(const Vector3d & v3) {x = v3.x; y = v3.y;} x = x_;
y = y_;
}
Vector2d(const Vector3d & v3) {
x = v3.x;
y = v3.y;
}
Vector2d operator*(const GLfloat v) { return Vector2d(x * v, y * v); } Vector2d operator*(const GLfloat v) { return Vector2d(x * v, y * v); }
Vector2d operator/(const GLfloat v) { return Vector2d(x / v, y / v); } Vector2d operator/(const GLfloat v) { return Vector2d(x / v, y / v); }
Vector2d operator+(const GLfloat v) { return Vector2d(x + v, y + v); } Vector2d operator+(const GLfloat v) { return Vector2d(x + v, y + v); }
@@ -273,16 +460,46 @@ struct Vector2d {
Vector2d operator-(const Vector3d & v) { return Vector3d(x - v.x, y - v.y); } Vector2d operator-(const Vector3d & v) { return Vector3d(x - v.x, y - v.y); }
Vector2d operator+(const Vector2d & v) { return Vector2d(x + v.x, y + v.y); } Vector2d operator+(const Vector2d & v) { return Vector2d(x + v.x, y + v.y); }
Vector2d operator-(const Vector2d & v) { return Vector2d(x - v.x, y - v.y); } Vector2d operator-(const Vector2d & v) { return Vector2d(x - v.x, y - v.y); }
Vector2d & operator *=(const GLfloat & v) {x *= v; y *= v; return *this;} Vector2d & operator*=(const GLfloat & v) {
Vector2d & operator /=(const GLfloat & v) {x /= v; y /= v; return *this;} x *= v;
Vector2d & operator +=(const GLfloat & v) {x += v; y += v; return *this;} y *= v;
Vector2d & operator -=(const GLfloat & v) {x -= v; y -= v; return *this;} return *this;
Vector2d & operator +=(const Vector3d & v) {x += v.x; y += v.y;; return *this;} }
Vector2d & operator -=(const Vector3d & v) {x -= v.x; y -= v.y;; return *this;} Vector2d & operator/=(const GLfloat & v) {
x /= v;
y /= v;
return *this;
}
Vector2d & operator+=(const GLfloat & v) {
x += v;
y += v;
return *this;
}
Vector2d & operator-=(const GLfloat & v) {
x -= v;
y -= v;
return *this;
}
Vector2d & operator+=(const Vector3d & v) {
x += v.x;
y += v.y;
;
return *this;
}
Vector2d & operator-=(const Vector3d & v) {
x -= v.x;
y -= v.y;
;
return *this;
}
}; };
struct Vector3i { struct Vector3i {
Vector3i(int p0_ = 0, int p1_ = 0, int p2_ = 0) {p0 = p0_; p1 = p1_; p2 = p2_;} Vector3i(int p0_ = 0, int p1_ = 0, int p2_ = 0) {
p0 = p0_;
p1 = p1_;
p2 = p2_;
}
Vector3i(const QString & str); Vector3i(const QString & str);
Vector3i movedX(const int & o) { return Vector3i(p0 + o, p1, p2); } Vector3i movedX(const int & o) { return Vector3i(p0 + o, p1, p2); }
Vector3i movedY(const int & o) { return Vector3i(p0, p1 + o, p2); } Vector3i movedY(const int & o) { return Vector3i(p0, p1 + o, p2); }
@@ -296,17 +513,43 @@ struct Vector3i {
QVector3D toQVector3D() const { return QVector3D(p0, p1, p2); } QVector3D toQVector3D() const { return QVector3D(p0, p1, p2); }
}; };
inline Vector3i operator +(const Vector3i & f, const Vector3i & s) {return Vector3i(f.p0 + s.p0, f.p1 + s.p1, f.p2 + s.p2);} inline Vector3i operator+(const Vector3i & f, const Vector3i & s) {
inline Vector3i operator -(const Vector3i & f, const Vector3i & s) {return Vector3i(f.p0 - s.p0, f.p1 - s.p1, f.p2 - s.p2);} return Vector3i(f.p0 + s.p0, f.p1 + s.p1, f.p2 + s.p2);
inline Vector3i operator /(const Vector3i & f, const int & s) {return Vector3i(f.p0 / s, f.p1 / s, f.p2 / s);} }
inline uint qHash(const Vector3i & v) {return v.p0 + v.p1 * 1024 + v.p2 * 1024 * 1024;} inline Vector3i operator-(const Vector3i & f, const Vector3i & s) {
inline QDebug operator <<(QDebug d, const Vector3d& v) {d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}"; return d.space();} return Vector3i(f.p0 - s.p0, f.p1 - s.p1, f.p2 - s.p2);
inline QDebug operator <<(QDebug d, const Vector3i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}"; return d.space();} }
inline Vector3i operator/(const Vector3i & f, const int & s) {
return Vector3i(f.p0 / s, f.p1 / s, f.p2 / s);
}
inline uint qHash(const Vector3i & v) {
return v.p0 + v.p1 * 1024 + v.p2 * 1024 * 1024;
}
inline QDebug operator<<(QDebug d, const Vector3d & v) {
d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}";
return d.space();
}
inline QDebug operator<<(QDebug d, const Vector3i & v) {
d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}";
return d.space();
}
inline QDataStream & operator <<(QDataStream & s, const Vector3d & v) {s << v.x << v.y << v.z; return s;} inline QDataStream & operator<<(QDataStream & s, const Vector3d & v) {
inline QDataStream & operator >>(QDataStream & s, Vector3d & v) {s >> v.x >> v.y >> v.z; return s;} s << v.x << v.y << v.z;
inline QDataStream & operator <<(QDataStream & s, const Vector3i & v) {s << v.p0 << v.p1 << v.p2; return s;} return s;
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;} }
inline QDataStream & operator>>(QDataStream & s, Vector3d & v) {
s >> v.x >> v.y >> v.z;
return s;
}
inline QDataStream & operator<<(QDataStream & s, const Vector3i & v) {
s << v.p0 << v.p1 << v.p2;
return s;
}
inline QDataStream & operator>>(QDataStream & s, Vector3i & v) {
s >> v.p0 >> v.p1 >> v.p2;
return s;
}
QColor colorFromString(const QString & str); QColor colorFromString(const QString & str);
inline float cosABV(const QVector3D & v0, const QVector3D & v1) { inline float cosABV(const QVector3D & v0, const QVector3D & v1) {
@@ -314,14 +557,23 @@ inline float cosABV(const QVector3D & v0, const QVector3D & v1) {
if (l == 0.f) return 0.; if (l == 0.f) return 0.;
return (QVector3D::dotProduct(v0, v1)) / l; return (QVector3D::dotProduct(v0, v1)) / l;
} }
inline QVector3D projection(const QVector3D & v, const QVector3D & to) {return to.normalized() * v.length() * cosABV(v, to);} inline QVector3D projection(const QVector3D & v, const QVector3D & to) {
return to.normalized() * v.length() * cosABV(v, to);
}
QVector3D orthToVector(const QVector3D & v, const float & scale = 1.); QVector3D orthToVector(const QVector3D & v, const float & scale = 1.);
QVector3D rotateVector(const QVector3D & v, const QVector3D & a); QVector3D rotateVector(const QVector3D & v, const QVector3D & a);
void setVectorLength(QVector3D & v, const float & l); void setVectorLength(QVector3D & v, const float & l);
void lengthenVector(QVector3D & v, const float & l); void lengthenVector(QVector3D & v, const float & l);
inline float squareLength(const QVector3D & from, const QVector3D & to) {return (to.x() - from.x())*(to.x() - from.x()) + (to.y() - from.y())*(to.y() - from.y()) + (to.z() - from.z())*(to.z() - from.z());} inline float squareLength(const QVector3D & from, const QVector3D & to) {
inline QVector3D directionFromAngles(const QVector3D & a) {return rotateVector(QVector3D(1., 0., 0.), a);} return (to.x() - from.x()) * (to.x() - from.x()) + (to.y() - from.y()) * (to.y() - from.y()) +
inline float frac(const float & x, const float & b) {return x - int(x / b) * b;} (to.z() - from.z()) * (to.z() - from.z());
}
inline QVector3D directionFromAngles(const QVector3D & a) {
return rotateVector(QVector3D(1., 0., 0.), a);
}
inline float frac(const float & x, const float & b) {
return x - int(x / b) * b;
}
class GLObjectBase; class GLObjectBase;
class QGLView; class QGLView;
@@ -329,9 +581,9 @@ class Light;
class Camera; class Camera;
class GLTextureManagerBase; class GLTextureManagerBase;
class QGLViewBase class QGLViewBase {
{
friend class GLObjectBase; friend class GLObjectBase;
public: public:
QGLViewBase(); QGLViewBase();
virtual ~QGLViewBase(); virtual ~QGLViewBase();
@@ -339,6 +591,7 @@ public:
const Camera * camera() const; const Camera * camera() const;
void setCamera(Camera * camera); void setCamera(Camera * camera);
GLTextureManagerBase * textureManager(); GLTextureManagerBase * textureManager();
protected: protected:
virtual void collectLights() = 0; virtual void collectLights() = 0;
Camera * camera_; Camera * camera_;

View File

@@ -91,19 +91,23 @@ bool GLVBO::rebuffer(bool clear_) {
if (!normals_.isEmpty()) { if (!normals_.isEmpty()) {
data << normals_; data << normals_;
has_normals = true; has_normals = true;
} else has_normals = false; } else
has_normals = false;
if (!texcoords_.isEmpty()) { if (!texcoords_.isEmpty()) {
data << texcoords_; data << texcoords_;
has_texcoords = true; has_texcoords = true;
} else has_texcoords = false; } else
has_texcoords = false;
if (!colors_.isEmpty()) { if (!colors_.isEmpty()) {
data << colors_; data << colors_;
has_colors = true; has_colors = true;
} else has_colors = false; } else
has_colors = false;
if (!tangents_.isEmpty()) { if (!tangents_.isEmpty()) {
data << tangents_ << bitangents_; data << tangents_ << bitangents_;
has_binormals = true; has_binormals = true;
} else has_binormals = false; } else
has_binormals = false;
// glBindVertexArray(va_); // glBindVertexArray(va_);
// qDebug() << "load buffer" << data.size() << buffer_; // qDebug() << "load buffer" << data.size() << buffer_;
glBindBuffer(GL_ARRAY_BUFFER, buffer_); glBindBuffer(GL_ARRAY_BUFFER, buffer_);
@@ -198,15 +202,18 @@ void GLVBO::draw(GLenum type, QOpenGLShaderProgram * prog, bool simplest) {
if (has_normals) { if (has_normals) {
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, offsets[0]); glNormalPointer(GL_FLOAT, 0, offsets[0]);
} else glDisableClientState(GL_NORMAL_ARRAY); } else
glDisableClientState(GL_NORMAL_ARRAY);
if (has_texcoords) { if (has_texcoords) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, offsets[1]); glTexCoordPointer(2, GL_FLOAT, 0, offsets[1]);
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY); } else
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (has_colors) { if (has_colors) {
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, offsets[2]); glColorPointer(4, GL_FLOAT, 0, offsets[2]);
} else glDisableClientState(GL_COLOR_ARRAY); } else
glDisableClientState(GL_COLOR_ARRAY);
} }
} }
// qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3]; // qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3];

View File

@@ -19,14 +19,14 @@
#ifndef GLVBO_H #ifndef GLVBO_H
#define GLVBO_H #define GLVBO_H
#include "gltypes.h"
#include "chunkstream.h" #include "chunkstream.h"
#include "gltypes.h"
class GLVBO : protected QOpenGLFunctions class GLVBO: protected QOpenGLFunctions {
{
friend class GLObjectBase; friend class GLObjectBase;
friend QDataStream & operator<<(QDataStream & s, const GLVBO & m); friend QDataStream & operator<<(QDataStream & s, const GLVBO & m);
friend QDataStream & operator>>(QDataStream & s, GLVBO & m); friend QDataStream & operator>>(QDataStream & s, GLVBO & m);
public: public:
GLVBO(GLenum usage = GL_DYNAMIC_DRAW); GLVBO(GLenum usage = GL_DYNAMIC_DRAW);
~GLVBO(); ~GLVBO();
@@ -44,10 +44,22 @@ public:
bool isInit() const { return buffer_ != 0; } bool isInit() const { return buffer_ != 0; }
bool isEmpty() const { return vertices_.size() < 3; } bool isEmpty() const { return vertices_.size() < 3; }
QVector<GLfloat> & vertices() {changed = true; return vertices_;} QVector<GLfloat> & vertices() {
QVector<GLfloat> & normals() {changed = true; return normals_;} changed = true;
QVector<GLfloat> & texcoords() {changed = true; return texcoords_;} return vertices_;
QVector<GLfloat> & colors() {changed = true; return colors_;} }
QVector<GLfloat> & normals() {
changed = true;
return normals_;
}
QVector<GLfloat> & texcoords() {
changed = true;
return texcoords_;
}
QVector<GLfloat> & colors() {
changed = true;
return colors_;
}
void translatePoints(const QVector3D & dp); void translatePoints(const QVector3D & dp);
void scalePoints(const QVector3D & dp); void scalePoints(const QVector3D & dp);
@@ -66,16 +78,17 @@ private:
GLuint buffer_, va_; GLuint buffer_, va_;
int vert_count; int vert_count;
bool changed, has_normals, has_texcoords, has_colors, has_binormals; bool changed, has_normals, has_texcoords, has_colors, has_binormals;
}; };
inline QDataStream & operator<<(QDataStream & s, const GLVBO & m) { inline QDataStream & operator<<(QDataStream & s, const GLVBO & m) {
ChunkStream cs; ChunkStream cs;
// qDebug() << "place VBO" << m.vertices_.size() << m.normals_.size() << m.texcoords_.size() << m.colors_.size() << "..."; // qDebug() << "place VBO" << m.vertices_.size() << m.normals_.size() << m.texcoords_.size() << m.colors_.size() << "...";
cs << cs.chunk(1, m.vertices_) << cs.chunk(2, m.normals_) << cs.chunk(3, m.texcoords_) << cs.chunk(4, m.colors_) << cs.chunk(5, m.usage); cs << cs.chunk(1, m.vertices_) << cs.chunk(2, m.normals_) << cs.chunk(3, m.texcoords_) << cs.chunk(4, m.colors_)
<< cs.chunk(5, m.usage);
// qDebug() << "place VBO done" << cs.data().size() << "..."; // qDebug() << "place VBO done" << cs.data().size() << "...";
s << qCompress(cs.data()); return s; s << qCompress(cs.data());
return s;
} }
inline QDataStream & operator>>(QDataStream & s, GLVBO & m) { inline QDataStream & operator>>(QDataStream & s, GLVBO & m) {
QByteArray ba; QByteArray ba;

View File

@@ -1,6 +1,8 @@
#include "glwidget.h" #include "glwidget.h"
#include "renderer_simple.h"
#include "renderer_deferred_shading.h" #include "renderer_deferred_shading.h"
#include "renderer_simple.h"
#include <QVBoxLayout> #include <QVBoxLayout>
@@ -68,8 +70,7 @@ bool GLWidget::isMouseSelectionEnabled() const {
} }
bool GLWidget::isCameraOrbit() const bool GLWidget::isCameraOrbit() const {
{
return view_->isCameraOrbit(); return view_->isCameraOrbit();
} }

View File

@@ -8,8 +8,7 @@ class QGLView;
class GLRendererBase; class GLRendererBase;
class GLObjectBase; class GLObjectBase;
class GLWidget : public QWidget class GLWidget: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY(QColor backColor READ backColor WRITE setBackColor) Q_PROPERTY(QColor backColor READ backColor WRITE setBackColor)
Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth) Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth)
@@ -27,6 +26,7 @@ class GLWidget : public QWidget
Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
Q_PROPERTY(qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) Q_PROPERTY(qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
public: public:
explicit GLWidget(QWidget * parent = nullptr); explicit GLWidget(QWidget * parent = nullptr);
QGLView * view() { return view_; } QGLView * view() { return view_; }

View File

@@ -51,22 +51,46 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
v0 = points[cf.p0]; v0 = points[cf.p0];
v1 = points[cf.p1]; v1 = points[cf.p1];
v2 = points[cf.p2]; v2 = points[cf.p2];
vertices[ind] = v0.x; normals[ind] = cn0.x; ++ind; vertices[ind] = v0.x;
vertices[ind] = v0.y; normals[ind] = cn0.y; ++ind; normals[ind] = cn0.x;
vertices[ind] = v0.z; normals[ind] = cn0.z; ++ind; ++ind;
vertices[ind] = v1.x; normals[ind] = cn0.x; ++ind; vertices[ind] = v0.y;
vertices[ind] = v1.y; normals[ind] = cn0.y; ++ind; normals[ind] = cn0.y;
vertices[ind] = v1.z; normals[ind] = cn0.z; ++ind; ++ind;
vertices[ind] = v2.x; normals[ind] = cn0.x; ++ind; vertices[ind] = v0.z;
vertices[ind] = v2.y; normals[ind] = cn0.y; ++ind; normals[ind] = cn0.z;
vertices[ind] = v2.z; normals[ind] = cn0.z; ++ind; ++ind;
vertices[ind] = v1.x;
normals[ind] = cn0.x;
++ind;
vertices[ind] = v1.y;
normals[ind] = cn0.y;
++ind;
vertices[ind] = v1.z;
normals[ind] = cn0.z;
++ind;
vertices[ind] = v2.x;
normals[ind] = cn0.x;
++ind;
vertices[ind] = v2.y;
normals[ind] = cn0.y;
++ind;
vertices[ind] = v2.z;
normals[ind] = cn0.z;
++ind;
if (has_uv) { if (has_uv) {
uvs[induv] = puvws[cf.p0].x; ++induv; uvs[induv] = puvws[cf.p0].x;
uvs[induv] = puvws[cf.p0].y; ++induv; ++induv;
uvs[induv] = puvws[cf.p1].x; ++induv; uvs[induv] = puvws[cf.p0].y;
uvs[induv] = puvws[cf.p1].y; ++induv; ++induv;
uvs[induv] = puvws[cf.p2].x; ++induv; uvs[induv] = puvws[cf.p1].x;
uvs[induv] = puvws[cf.p2].y; ++induv; ++induv;
uvs[induv] = puvws[cf.p1].y;
++induv;
uvs[induv] = puvws[cf.p2].x;
++induv;
uvs[induv] = puvws[cf.p2].y;
++induv;
} }
} }
} else { } else {
@@ -81,18 +105,18 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
ncnt0 = ncnt1 = ncnt2 = 1; ncnt0 = ncnt1 = ncnt2 = 1;
for (int j = 0; j < faces.size(); ++j) { for (int j = 0; j < faces.size(); ++j) {
if (csg != smooth[j] || j == i) continue; if (csg != smooth[j] || j == i) continue;
if (faces[j].p0 == cf.p0 || faces[j].p1 == cf.p0 || faces[j].p2 == cf.p0 || if (faces[j].p0 == cf.p0 || faces[j].p1 == cf.p0 || faces[j].p2 == cf.p0 || points[faces[j].p0] == v0 ||
points[faces[j].p0] == v0 || points[faces[j].p1] == v0 || points[faces[j].p2] == v0) { points[faces[j].p1] == v0 || points[faces[j].p2] == v0) {
cn0 += fnormals[j]; cn0 += fnormals[j];
++ncnt0; ++ncnt0;
} }
if (faces[j].p0 == cf.p1 || faces[j].p1 == cf.p1 || faces[j].p2 == cf.p1 || if (faces[j].p0 == cf.p1 || faces[j].p1 == cf.p1 || faces[j].p2 == cf.p1 || points[faces[j].p0] == v1 ||
points[faces[j].p0] == v1 || points[faces[j].p1] == v1 || points[faces[j].p2] == v1) { points[faces[j].p1] == v1 || points[faces[j].p2] == v1) {
cn1 += fnormals[j]; cn1 += fnormals[j];
++ncnt1; ++ncnt1;
} }
if (faces[j].p0 == cf.p2 || faces[j].p1 == cf.p2 || faces[j].p2 == cf.p2 || if (faces[j].p0 == cf.p2 || faces[j].p1 == cf.p2 || faces[j].p2 == cf.p2 || points[faces[j].p0] == v2 ||
points[faces[j].p0] == v2 || points[faces[j].p1] == v2 || points[faces[j].p2] == v2) { points[faces[j].p1] == v2 || points[faces[j].p2] == v2) {
cn2 += fnormals[j]; cn2 += fnormals[j];
++ncnt2; ++ncnt2;
} }
@@ -100,22 +124,46 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
cn0 /= ncnt0; cn0 /= ncnt0;
cn1 /= ncnt1; cn1 /= ncnt1;
cn2 /= ncnt2; cn2 /= ncnt2;
vertices[ind] = v0.x; normals[ind] = cn0.x; ++ind; vertices[ind] = v0.x;
vertices[ind] = v0.y; normals[ind] = cn0.y; ++ind; normals[ind] = cn0.x;
vertices[ind] = v0.z; normals[ind] = cn0.z; ++ind; ++ind;
vertices[ind] = v1.x; normals[ind] = cn1.x; ++ind; vertices[ind] = v0.y;
vertices[ind] = v1.y; normals[ind] = cn1.y; ++ind; normals[ind] = cn0.y;
vertices[ind] = v1.z; normals[ind] = cn1.z; ++ind; ++ind;
vertices[ind] = v2.x; normals[ind] = cn2.x; ++ind; vertices[ind] = v0.z;
vertices[ind] = v2.y; normals[ind] = cn2.y; ++ind; normals[ind] = cn0.z;
vertices[ind] = v2.z; normals[ind] = cn2.z; ++ind; ++ind;
vertices[ind] = v1.x;
normals[ind] = cn1.x;
++ind;
vertices[ind] = v1.y;
normals[ind] = cn1.y;
++ind;
vertices[ind] = v1.z;
normals[ind] = cn1.z;
++ind;
vertices[ind] = v2.x;
normals[ind] = cn2.x;
++ind;
vertices[ind] = v2.y;
normals[ind] = cn2.y;
++ind;
vertices[ind] = v2.z;
normals[ind] = cn2.z;
++ind;
if (has_uv) { if (has_uv) {
uvs[induv] = puvws[cf.p0].x; ++induv; uvs[induv] = puvws[cf.p0].x;
uvs[induv] = puvws[cf.p0].y; ++induv; ++induv;
uvs[induv] = puvws[cf.p1].x; ++induv; uvs[induv] = puvws[cf.p0].y;
uvs[induv] = puvws[cf.p1].y; ++induv; ++induv;
uvs[induv] = puvws[cf.p2].x; ++induv; uvs[induv] = puvws[cf.p1].x;
uvs[induv] = puvws[cf.p2].y; ++induv; ++induv;
uvs[induv] = puvws[cf.p1].y;
++induv;
uvs[induv] = puvws[cf.p2].x;
++induv;
uvs[induv] = puvws[cf.p2].y;
++induv;
} }
} }
} }
@@ -124,8 +172,7 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
Material Loader3DS::materialByName(const QVector<Material> & materials, const QString & name) { Material Loader3DS::materialByName(const QVector<Material> & materials, const QString & name) {
foreach(const Material & m, materials) foreach(const Material & m, materials)
if (m.name == name) if (m.name == name) return m;
return m;
return Material(); return Material();
} }
@@ -288,8 +335,7 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, float scale) {
break; break;
case LOADER_3DS_CHUNK_MATERIAL: case LOADER_3DS_CHUNK_MATERIAL:
// stream.skipRawData(cc.size - 6); // stream.skipRawData(cc.size - 6);
if (!mat.name.isEmpty()) if (!mat.name.isEmpty()) materials << mat;
materials << mat;
mat = Material(); mat = Material();
break; break;
case LOADER_3DS_CHUNK_MATERIAL_NAME: case LOADER_3DS_CHUNK_MATERIAL_NAME:
@@ -314,15 +360,9 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, float scale) {
mat.color_specular = QColor::fromRgb(((uchar *)&col)[0], ((uchar *)&col)[1], ((uchar *)&col)[2]); mat.color_specular = QColor::fromRgb(((uchar *)&col)[0], ((uchar *)&col)[1], ((uchar *)&col)[2]);
// qDebug() << "mat diffuse" << mat.color_diffuse; // qDebug() << "mat diffuse" << mat.color_diffuse;
break; break;
case LOADER_3DS_CHUNK_TEXTURE_MAP: case LOADER_3DS_CHUNK_TEXTURE_MAP: cur_map = LOADER_3DS_CHUNK_TEXTURE_MAP; break;
cur_map = LOADER_3DS_CHUNK_TEXTURE_MAP; case LOADER_3DS_CHUNK_BUMP_MAP: cur_map = LOADER_3DS_CHUNK_BUMP_MAP; break;
break; case LOADER_3DS_CHUNK_REFLECTION_MAP: cur_map = LOADER_3DS_CHUNK_REFLECTION_MAP; break;
case LOADER_3DS_CHUNK_BUMP_MAP:
cur_map = LOADER_3DS_CHUNK_BUMP_MAP;
break;
case LOADER_3DS_CHUNK_REFLECTION_MAP:
cur_map = LOADER_3DS_CHUNK_REFLECTION_MAP;
break;
case LOADER_3DS_CHUNK_MAP_FILENAME: case LOADER_3DS_CHUNK_MAP_FILENAME:
name = readCharsUntilNull(stream); name = readCharsUntilNull(stream);
// qDebug() << " mat map" << QString::number(cur_map, 16) << name; // qDebug() << " mat map" << QString::number(cur_map, 16) << name;
@@ -334,8 +374,7 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, float scale) {
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6); default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
} }
} }
if (!mat.name.isEmpty()) if (!mat.name.isEmpty()) materials << mat;
materials << mat;
foreach(const Material & m, materials) foreach(const Material & m, materials)
qDebug() << m.name; qDebug() << m.name;
if (co != nullptr) { if (co != nullptr) {

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