diff --git a/DSView/DSView.qrc b/DSView/DSView.qrc index 5968cc45..b2799fad 100644 --- a/DSView/DSView.qrc +++ b/DSView/DSView.qrc @@ -68,5 +68,9 @@ icons/Hamming.png icons/Hann.png icons/Rectangle.png + icons/close.png + icons/maximize.png + icons/minimize.png + icons/restore.png diff --git a/DSView/darkstyle/style.qss b/DSView/darkstyle/style.qss index 975afee6..ddf6b5e8 100755 --- a/DSView/darkstyle/style.qss +++ b/DSView/darkstyle/style.qss @@ -531,7 +531,6 @@ QMenu::separator margin-right: 5px; } - QFrame { border-radius: 2px; @@ -800,28 +799,39 @@ QTabBar::tab:bottom:!selected:hover { /* LEFT TABS */ QTabBar::tab:left { color: #b1b1b1; - border: 1px solid #4A4949; + border: 1px transparent #4A4949; border-left: 1px transparent black; - background-color: #302F2F; + background-color: #48576b; padding: 5px; - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; } QTabBar::tab:left:!selected { color: #b1b1b1; - background-color: #201F1F; + background-color: #302F2F; border: 1px transparent #4A4949; border-right: 1px transparent #4A4949; border-top-right-radius: 0px; border-bottom-right-radius: 0px; } -QTabBar::tab:left:!selected:hover { +QTabBar::tab:left:hover { background-color: #48576b; } +QTabBar::tab:left:disabled +{ + color: #3A3939; + background-color: #302F2F; + border: 1px transparent #4A4949; + border-right: 1px transparent #4A4949; + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; +} + + /* RIGHT TABS */ QTabBar::tab:right { @@ -975,6 +985,44 @@ QSlider::handle:vertical { margin: 0 -4px; border-radius: 2px; } +QToolButton#MaximizeButton { + background-color: transparent; + border-left: 1px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0.0 #302F2F, stop: 0.3 #606060, + stop: 0.5 #707070, + stop: 0.7 #606060, stop: 1 #302F2F); + border-right: 1px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0.0 #302F2F, stop: 0.3 #606060, + stop: 0.5 #707070, + stop: 0.7 #606060, stop: 1 #302F2F); + border-radius: 0px; + margin: 0px; + padding: 0px; +} + +QToolButton#MinimizeButton, +QToolButton#CloseButton { + background-color: transparent; + border: 1px transparent #808080; + border-radius: 0px; + margin: 0px; + padding: 0px; +} + +QToolButton#MinimizeButton:hover, QToolButton#MinimizeButton::menu-button:hover, +QToolButton#MaximizeButton:hover, QToolButton#MaximizeButton::menu-button:hover{ + background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0.0 #302F2F, stop: 0.4 #4E4D4D, + stop: 0.5 #4A4949, + stop: 0.6 #4E4D4D, stop: 1 #302F2F); +} + +QToolButton#CloseButton:hover, QToolButton#CloseButton::menu-button:hover { +background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0.0 #302F2F, stop: 0.2 #A82F2F, + stop: 0.5 #E83E4A, + stop: 0.8 #A82F2F, stop: 1 #302F2F); +} QToolButton { background-color: transparent; diff --git a/DSView/icons/close.png b/DSView/icons/close.png new file mode 100755 index 00000000..529f2ed1 Binary files /dev/null and b/DSView/icons/close.png differ diff --git a/DSView/icons/maximize.png b/DSView/icons/maximize.png new file mode 100755 index 00000000..bb4bffb8 Binary files /dev/null and b/DSView/icons/maximize.png differ diff --git a/DSView/icons/minimize.png b/DSView/icons/minimize.png new file mode 100755 index 00000000..7c9a9fd3 Binary files /dev/null and b/DSView/icons/minimize.png differ diff --git a/DSView/icons/restore.png b/DSView/icons/restore.png new file mode 100755 index 00000000..ceaa6235 Binary files /dev/null and b/DSView/icons/restore.png differ diff --git a/DSView/main.cpp b/DSView/main.cpp index 58b022b5..08d94c03 100644 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -37,7 +37,7 @@ #include "dsapplication.h" #include "pv/devicemanager.h" -#include "pv/mainwindow.h" +#include "pv/mainframe.h" #include "config.h" @@ -134,13 +134,13 @@ int main(int argc, char *argv[]) // Create the device manager, initialise the drivers pv::DeviceManager device_manager(sr_ctx); - // Initialise the main window - pv::MainWindow w(device_manager, open_file); - //QFile qss(":/stylesheet.qss"); - QFile qss(":qdarkstyle/style.qss"); - qss.open(QFile::ReadOnly); - a.setStyleSheet(qss.readAll()); - qss.close(); + // Initialise the main frame + pv::MainFrame w(device_manager, open_file); + //QFile qss(":/stylesheet.qss"); + QFile qss(":qdarkstyle/style.qss"); + qss.open(QFile::ReadOnly); + a.setStyleSheet(qss.readAll()); + qss.close(); w.show(); // Run the application diff --git a/DSView/pv/device/devinst.h b/DSView/pv/device/devinst.h index c5e58d62..dec1b525 100644 --- a/DSView/pv/device/devinst.h +++ b/DSView/pv/device/devinst.h @@ -126,6 +126,7 @@ public: virtual void* get_id() const; signals: + void device_updated(); void config_changed(); protected: diff --git a/DSView/pv/devicemanager.cpp b/DSView/pv/devicemanager.cpp index 45ebbd4c..7b986105 100644 --- a/DSView/pv/devicemanager.cpp +++ b/DSView/pv/devicemanager.cpp @@ -47,8 +47,6 @@ using std::ostringstream; using std::runtime_error; using std::string; -extern char AppDataPath[256]; - namespace pv { DeviceManager::DeviceManager(struct sr_context *sr_ctx) : diff --git a/DSView/pv/dialogs/about.cpp b/DSView/pv/dialogs/about.cpp index b402cb52..93cd4dce 100644 --- a/DSView/pv/dialogs/about.cpp +++ b/DSView/pv/dialogs/about.cpp @@ -21,45 +21,41 @@ */ -#include +#include +#include #include "about.h" -#include - -/* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ -#define __STDC_FORMAT_MACROS -#include -#include - namespace pv { namespace dialogs { About::About(QWidget *parent) : - QDialog(parent), - ui(new Ui::About) + DSDialog(parent, true) { - ui->setupUi(this); + QPixmap pix(":/icons/dsl_logo.png"); + _logo = new QLabel(this); + _logo->setPixmap(pix); + _logo->setAlignment(Qt::AlignCenter); - /* Setup the version field */ - ui->versionInfo->setText(tr("%1 %2
%4") - .arg(QApplication::applicationName()) - .arg(QApplication::applicationVersion()) - .arg(QApplication::organizationDomain())); - ui->versionInfo->setOpenExternalLinks(true); + _info = new QLabel(this); + _info->setText(tr("%1 %2
%4") + .arg(QApplication::applicationName()) + .arg(QApplication::applicationVersion()) + .arg(QApplication::organizationDomain())); + _info->setOpenExternalLinks(true); + _info->setAlignment(Qt::AlignCenter); - connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + QVBoxLayout *xlayout = new QVBoxLayout(); + xlayout->addWidget(_logo); + xlayout->addWidget(_info); + + layout()->addLayout(xlayout); + setTitle(tr("About")); + setFixedWidth(500); } About::~About() { - delete ui; -} - -void About::accept() -{ - using namespace Qt; - QDialog::accept(); } } // namespace dialogs diff --git a/DSView/pv/dialogs/about.h b/DSView/pv/dialogs/about.h index d31b7607..59b14233 100644 --- a/DSView/pv/dialogs/about.h +++ b/DSView/pv/dialogs/about.h @@ -24,18 +24,13 @@ #ifndef DSVIEW_PV_ABOUT_H #define DSVIEW_PV_ABOUT_H -#include - -#include - -namespace Ui { -class About; -} +#include +#include "dsdialog.h" namespace pv { namespace dialogs { -class About : public QDialog +class About : public DSDialog { Q_OBJECT @@ -43,11 +38,9 @@ public: explicit About(QWidget *parent = 0); ~About(); -protected: - void accept(); - private: - Ui::About *ui; + QLabel *_logo; + QLabel *_info; }; } // namespace dialogs diff --git a/DSView/pv/dialogs/calibration.cpp b/DSView/pv/dialogs/calibration.cpp index fe2572aa..465affe6 100755 --- a/DSView/pv/dialogs/calibration.cpp +++ b/DSView/pv/dialogs/calibration.cpp @@ -43,11 +43,10 @@ const QString Calibration::VGAIN = tr(" VGAIN"); const QString Calibration::VOFF = tr(" VOFF"); Calibration::Calibration(QWidget *parent) : - QDialog(parent) + DSDialog(parent) { this->setFixedSize(400, 200); this->setWindowOpacity(0.7); - this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); this->setModal(false); _dev_inst = NULL; @@ -56,16 +55,19 @@ Calibration::Calibration(QWidget *parent) : _exit_btn = new QPushButton(tr("Exit"), this); _flayout = new QFormLayout(); - QGridLayout *glayout = new QGridLayout(this); - glayout->addLayout(_flayout, 0, 0, 1, 5); - glayout->addWidget(_save_btn, 1, 0); - glayout->addWidget(new QWidget(this), 1, 1); + QGridLayout *glayout = new QGridLayout(); + + glayout->addLayout(_flayout, 1, 0, 1, 5); + glayout->addWidget(_save_btn, 2, 0); + glayout->addWidget(new QWidget(this), 2, 1); glayout->setColumnStretch(1, 1); - glayout->addWidget(_reset_btn, 1, 2); - glayout->addWidget(new QWidget(this), 1, 3); + glayout->addWidget(_reset_btn, 2, 2); + glayout->addWidget(new QWidget(this), 2, 3); glayout->setColumnStretch(3, 1); - glayout->addWidget(_exit_btn, 1, 4); - setLayout(glayout); + glayout->addWidget(_exit_btn, 2, 4); + + layout()->addLayout(glayout); + setTitle(tr("Manual Calibration")); connect(_save_btn, SIGNAL(clicked()), this, SLOT(on_save())); connect(_reset_btn, SIGNAL(clicked()), this, SLOT(on_reset())); diff --git a/DSView/pv/dialogs/calibration.h b/DSView/pv/dialogs/calibration.h index 3cc49827..9e469f1b 100755 --- a/DSView/pv/dialogs/calibration.h +++ b/DSView/pv/dialogs/calibration.h @@ -23,7 +23,6 @@ #ifndef DSVIEW_PV_CALIBRATION_H #define DSVIEW_PV_CALIBRATION_H -#include #include #include #include @@ -34,11 +33,13 @@ #include #include +#include "../toolbars/titlebar.h" +#include "dsdialog.h" namespace pv { namespace dialogs { -class Calibration : public QDialog +class Calibration : public DSDialog { Q_OBJECT @@ -63,6 +64,7 @@ private slots: private: boost::shared_ptr _dev_inst; + toolbars::TitleBar *_titlebar; QPushButton *_save_btn; QPushButton *_reset_btn; QPushButton *_exit_btn; diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp index b2c8db05..970bf4ad 100644 --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -27,8 +27,8 @@ #include #include -#include +#include "dsmessagebox.h" #include using namespace boost; @@ -38,16 +38,12 @@ namespace pv { namespace dialogs { DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptr dev_inst) : - QDialog(parent), + DSDialog(parent), _dev_inst(dev_inst), - _layout(this), _button_box(QDialogButtonBox::Ok, Qt::Horizontal, this), _device_options_binding(_dev_inst->dev_inst()) { - setWindowTitle(tr("Configure Device")); - setLayout(&_layout); - _props_box = new QGroupBox(tr("Mode"), this); _props_box->setLayout(&_props_box_layout); _props_box_layout.addWidget(get_property_form()); @@ -58,7 +54,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptrsetLayout(&_probes_box_layout); _layout.addWidget(_probes_box); - } else { + } else if (_dev_inst->name().contains("DSCope")){ _config_button = new QPushButton(tr("Zero Adjustment"), this); _layout.addWidget(_config_button); connect(_config_button, SIGNAL(clicked()), this, SLOT(zero_adj())); @@ -71,8 +67,12 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptraddLayout(&_layout); + setTitle(tr("Device Options")); + connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); //connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject())); + connect(_dev_inst.get(), SIGNAL(device_updated()), this, SLOT(reject())); GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_OPERATION_MODE); if (gvar != NULL) { @@ -113,7 +113,9 @@ void DeviceOptions::accept() void DeviceOptions::reject() { - accept(); + using namespace Qt; + + QDialog::reject(); } QWidget* DeviceOptions::get_property_form() @@ -232,15 +234,14 @@ void DeviceOptions::zero_adj() using namespace Qt; QDialog::accept(); - QMessageBox msg(this); - msg.setText(tr("Information")); - msg.setInformativeText(tr("Zero adjustment program will be started. Please keep all channels out of singal input. It can take a while!")); - //msg.setStandardButtons(QMessageBox::); - msg.addButton(tr("Ok"), QMessageBox::AcceptRole); - msg.addButton(tr("Cancel"), QMessageBox::RejectRole); - msg.setIcon(QMessageBox::Information); - int ret = msg.exec(); - if ( ret == QMessageBox::AcceptRole) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Information")); + msg.mBox()->setInformativeText(tr("Zero adjustment program will be started. Please keep all channels out of singal input. It can take a while!")); + //msg.mBox()->setStandardButtons(QMessageBox::); + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->addButton(tr("Cancel"), QMessageBox::RejectRole); + msg.mBox()->setIcon(QMessageBox::Information); + if (msg.exec()) { _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(true)); } } diff --git a/DSView/pv/dialogs/deviceoptions.h b/DSView/pv/dialogs/deviceoptions.h index e1c3c6a3..c2dd9ee2 100644 --- a/DSView/pv/dialogs/deviceoptions.h +++ b/DSView/pv/dialogs/deviceoptions.h @@ -42,11 +42,13 @@ #include #include +#include "../toolbars/titlebar.h" +#include "../dialogs/dsdialog.h" namespace pv { namespace dialogs { -class DeviceOptions : public QDialog +class DeviceOptions : public DSDialog { Q_OBJECT @@ -76,6 +78,7 @@ private slots: private: boost::shared_ptr _dev_inst; QVBoxLayout _layout; + toolbars::TitleBar *_titlebar; QGroupBox *_probes_box; QGridLayout _probes_box_layout; diff --git a/DSView/pv/dialogs/dsdialog.cpp b/DSView/pv/dialogs/dsdialog.cpp new file mode 100755 index 00000000..a8f0202e --- /dev/null +++ b/DSView/pv/dialogs/dsdialog.cpp @@ -0,0 +1,144 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "dsdialog.h" +#include "shadow.h" + +#include +#include +#include +#include +#include + +namespace pv { +namespace dialogs { + +DSDialog::DSDialog(QWidget *parent, bool hasClose) : + QDialog(parent), + _moving(false) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_TranslucentBackground); + + build_main(hasClose); + + _layout = new QVBoxLayout(this); + _layout->addWidget(_main); + setLayout(_layout); +} + +void DSDialog::accept() +{ + using namespace Qt; + + QDialog::accept(); +} + +void DSDialog::reject() +{ + using namespace Qt; + + QDialog::reject(); +} + +bool DSDialog::eventFilter(QObject *object, QEvent *event) +{ + const QEvent::Type type = event->type(); + const QMouseEvent *const mouse_event = (QMouseEvent*)event; + if (type == QEvent::MouseMove) { + if (_moving && mouse_event->buttons().testFlag(Qt::LeftButton)) { + move(mouse_event->globalPos() - _startPos); + } + return true; + } else if (type == QEvent::MouseButtonPress) { + if (mouse_event->buttons().testFlag(Qt::LeftButton)) { + _moving = true; +#ifndef _WIN32 + _startPos = mouse_event->pos() + + QPoint(_layout->margin(), _layout->margin()) + + QPoint(_layout->spacing(), _layout->spacing()) + + QPoint(_mlayout->margin(), _mlayout->margin()) + + QPoint(_mlayout->spacing(), _mlayout->spacing()); +#else + _startPos = mouse_event->pos() + + QPoint(_layout->margin(), _layout->margin()) + + QPoint(_layout->spacing(), _layout->spacing()); +#endif + } + } else if (type == QEvent::MouseButtonRelease) { + if (mouse_event->buttons().testFlag(Qt::LeftButton)) { + _moving = false; + } + } + return false; +} + +QVBoxLayout* DSDialog::layout() +{ + return _mlayout; +} + +QWidget* DSDialog::mainWidget() +{ + return _main; +} + +void DSDialog::setTitle(QString title) +{ + _titlebar->setTitle(title); +} + +void DSDialog::reload(bool hasClose) +{ + QString title; + if (_titlebar) + title = _titlebar->title(); + if (_main) + delete _main; + + build_main(hasClose); + _titlebar->setTitle(title); + _layout->addWidget(_main); +} + +void DSDialog::build_main(bool hasClose) +{ + _main = new QWidget(this); + _mlayout = new QVBoxLayout(_main); + _main->setLayout(_mlayout); + //_mlayout->setMargin(5); + //_mlayout->setSpacing(5); + + Shadow *bodyShadow = new Shadow(_main); + bodyShadow->setBlurRadius(10.0); + bodyShadow->setDistance(3.0); + bodyShadow->setColor(QColor(0, 0, 0, 80)); + _main->setAutoFillBackground(true); + _main->setGraphicsEffect(bodyShadow); + + _titlebar = new toolbars::TitleBar(false, this, hasClose); + _titlebar->installEventFilter(this); + _mlayout->addWidget(_titlebar); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/dsdialog.h b/DSView/pv/dialogs/dsdialog.h new file mode 100755 index 00000000..cefc614d --- /dev/null +++ b/DSView/pv/dialogs/dsdialog.h @@ -0,0 +1,68 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_DSDIALOG_H +#define DSVIEW_PV_DSDIALOG_H + +#include +#include +#include + +#include "../toolbars/titlebar.h" + +namespace pv { +namespace dialogs { + +class DSDialog : public QDialog +{ + Q_OBJECT + +public: + DSDialog(QWidget *parent = 0, bool hasClose = false); + QVBoxLayout *layout(); + QWidget *mainWidget(); + + void setTitle(QString title); + void reload(bool hasClose); + +protected: + void accept(); + void reject(); + //void mousePressEvent(QMouseEvent *event); + //void mouseReleaseEvent(QMouseEvent *event); + bool eventFilter(QObject *object, QEvent *event); +private: + void build_main(bool hasClose); + +private: + QVBoxLayout *_layout; + QVBoxLayout *_mlayout; + QWidget *_main; + toolbars::TitleBar *_titlebar; + bool _moving; + QPoint _startPos; +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_DSDIALOG_H diff --git a/DSView/pv/dialogs/dsmessagebox.cpp b/DSView/pv/dialogs/dsmessagebox.cpp new file mode 100755 index 00000000..d7e44441 --- /dev/null +++ b/DSView/pv/dialogs/dsmessagebox.cpp @@ -0,0 +1,129 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "dsmessagebox.h" +#include "shadow.h" + +#include +#include +#include +#include +#include + +namespace pv { +namespace dialogs { + +DSMessageBox::DSMessageBox(QWidget *parent) : + QDialog(parent), + _moving(false) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_TranslucentBackground); + _main = new QWidget(this); + QVBoxLayout *mlayout = new QVBoxLayout(_main); + _main->setLayout(mlayout); + + Shadow *bodyShadow = new Shadow(); + bodyShadow->setBlurRadius(10.0); + bodyShadow->setDistance(3.0); + bodyShadow->setColor(QColor(0, 0, 0, 80)); + _main->setAutoFillBackground(true); + _main->setGraphicsEffect(bodyShadow); + + _msg = new QMessageBox(this); + _msg->setWindowFlags(Qt::FramelessWindowHint | Qt::Widget); + + _titlebar = new toolbars::TitleBar(false, this); + _titlebar->setTitle(tr("Message")); + _titlebar->installEventFilter(this); + + mlayout->addWidget(_titlebar); + mlayout->addWidget(_msg); + + _layout = new QVBoxLayout(this); + _layout->addWidget(_main); + setLayout(_layout); + + //connect(_msg, SIGNAL(finished(int)), this, SLOT(accept())); + connect(_msg, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(on_button(QAbstractButton*))); +} + +void DSMessageBox::accept() +{ + using namespace Qt; + + QDialog::accept(); +} + +void DSMessageBox::reject() +{ + using namespace Qt; + + QDialog::reject(); +} + +bool DSMessageBox::eventFilter(QObject *object, QEvent *event) +{ + const QEvent::Type type = event->type(); + const QMouseEvent *const mouse_event = (QMouseEvent*)event; + if (type == QEvent::MouseMove) { + if (_moving && mouse_event->buttons().testFlag(Qt::LeftButton)) { + move(mouse_event->globalPos() - _startPos); + } + return true; + } else if (type == QEvent::MouseButtonPress) { + if (mouse_event->buttons().testFlag(Qt::LeftButton)) { + _moving = true; + _startPos = mouse_event->pos() + + QPoint(_layout->margin(), _layout->margin()) + + QPoint(_layout->spacing(), _layout->spacing()); + } + } else if (type == QEvent::MouseButtonRelease) { + if (mouse_event->buttons().testFlag(Qt::LeftButton)) { + _moving = false; + } + } + return false; +} + +QMessageBox* DSMessageBox::mBox() +{ + return _msg; +} + +int DSMessageBox::exec() +{ + //_msg->show(); + return QDialog::exec(); +} + +void DSMessageBox::on_button(QAbstractButton *btn) +{ + QMessageBox::ButtonRole role = _msg->buttonRole(btn); + if (role == QMessageBox::AcceptRole) + accept(); + else + reject(); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/streamoptions.h b/DSView/pv/dialogs/dsmessagebox.h old mode 100644 new mode 100755 similarity index 52% rename from DSView/pv/dialogs/streamoptions.h rename to DSView/pv/dialogs/dsmessagebox.h index 1c9c148d..5fc2ea30 --- a/DSView/pv/dialogs/streamoptions.h +++ b/DSView/pv/dialogs/dsmessagebox.h @@ -2,7 +2,7 @@ * This file is part of the DSView project. * DSView is based on PulseView. * - * Copyright (C) 2013 DreamSourceLab + * Copyright (C) 2016 DreamSourceLab * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,56 +20,49 @@ */ -#ifndef DSVIEW_PV_STREAMOPTIONS_H -#define DSVIEW_PV_STREAMOPTIONS_H +#ifndef DSVIEW_PV_DSMESSAGEBOX_H +#define DSVIEW_PV_DSMESSAGEBOX_H #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include "../toolbars/titlebar.h" namespace pv { namespace dialogs { -class StreamOptions : public QDialog +class DSMessageBox : public QDialog { Q_OBJECT public: - StreamOptions(QWidget *parent, boost::shared_ptr dev_inst, - uint64_t sample_count, bool stream); + DSMessageBox(QWidget *parent); + QMessageBox *mBox(); + + int exec(); protected: - void accept(); + void accept(); void reject(); + //void mousePressEvent(QMouseEvent *event); + //void mouseReleaseEvent(QMouseEvent *event); + bool eventFilter(QObject *object, QEvent *event); + +private slots: + void on_button(QAbstractButton* btn); private: - boost::shared_ptr _dev_inst; - uint64_t _sample_count; - QVBoxLayout _layout; - - QRadioButton * _op0; - QRadioButton * _op1; - - bool _stream; - - QDialogButtonBox _button_box; + QVBoxLayout *_layout; + QWidget *_main; + QMessageBox *_msg; + toolbars::TitleBar *_titlebar; + bool _moving; + QPoint _startPos; }; } // namespace dialogs } // namespace pv -#endif // DSVIEW_PV_STREAMOPTIONS_H +#endif // DSVIEW_PV_DSMESSAGEBOX_H diff --git a/DSView/pv/dialogs/dsomeasure.cpp b/DSView/pv/dialogs/dsomeasure.cpp index 6f5921fd..f59e7c9a 100644 --- a/DSView/pv/dialogs/dsomeasure.cpp +++ b/DSView/pv/dialogs/dsomeasure.cpp @@ -21,6 +21,7 @@ #include "dsomeasure.h" +#include "../device/devinst.h" #include #include @@ -35,14 +36,12 @@ namespace pv { namespace dialogs { DsoMeasure::DsoMeasure(QWidget *parent, boost::shared_ptr dsoSig) : - QDialog(parent), + DSDialog(parent), _dsoSig(dsoSig), - _layout(this), _button_box(QDialogButtonBox::Ok, Qt::Horizontal, this) { - setWindowTitle(tr("DSO Measure Options")); - setLayout(&_layout); + setMinimumWidth(300); for (int i=DsoSignal::DSO_MS_BEGIN+1; iget_ms_string(i), this); @@ -54,8 +53,13 @@ DsoMeasure::DsoMeasure(QWidget *parent, boost::shared_ptr dsoSig) : _layout.addWidget(&_button_box); + layout()->addLayout(&_layout); + setTitle(tr("Measurements")); + connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); connect(&_button_box, SIGNAL(rejected()), this, SLOT(accept())); + + connect(_dsoSig->get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); } void DsoMeasure::set_measure(bool en) @@ -77,7 +81,9 @@ void DsoMeasure::accept() void DsoMeasure::reject() { - accept(); + using namespace Qt; + + QDialog::reject(); } } // namespace dialogs diff --git a/DSView/pv/dialogs/dsomeasure.h b/DSView/pv/dialogs/dsomeasure.h index 178b0732..a50689be 100644 --- a/DSView/pv/dialogs/dsomeasure.h +++ b/DSView/pv/dialogs/dsomeasure.h @@ -23,13 +23,14 @@ #ifndef DSVIEW_PV_DSOMEASURE_H #define DSVIEW_PV_DSOMEASURE_H -#include #include #include #include -#include +#include "../view/dsosignal.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" namespace pv { @@ -39,7 +40,7 @@ class DsoSignal; namespace dialogs { -class DsoMeasure : public QDialog +class DsoMeasure : public DSDialog { Q_OBJECT @@ -55,7 +56,7 @@ protected: private: boost::shared_ptr _dsoSig; - + toolbars::TitleBar *_titlebar; QVBoxLayout _layout; QDialogButtonBox _button_box; }; diff --git a/DSView/pv/dialogs/fftoptions.cpp b/DSView/pv/dialogs/fftoptions.cpp index d2344ca3..ebe8b0b1 100644 --- a/DSView/pv/dialogs/fftoptions.cpp +++ b/DSView/pv/dialogs/fftoptions.cpp @@ -26,7 +26,6 @@ #include #include -#include #include "../sigsession.h" #include "../data/mathstack.h" @@ -41,7 +40,7 @@ namespace pv { namespace dialogs { FftOptions::FftOptions(QWidget *parent, SigSession &session) : - QDialog(parent), + DSDialog(parent), _session(session), _button_box(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this) @@ -188,15 +187,18 @@ FftOptions::FftOptions(QWidget *parent, SigSession &session) : _hint_label->setPixmap(pixmap); _hlayout->addWidget(_hint_label); - _layout = new QVBoxLayout(this); + _layout = new QVBoxLayout(); _layout->addLayout(_hlayout); _layout->addWidget(&_button_box); - setLayout(_layout); + + layout()->addLayout(_layout); + setTitle(tr("FFT Options")); connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject())); connect(_window_combobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(window_changed(QString))); connect(_len_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(len_changed(int))); + connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); } void FftOptions::accept() diff --git a/DSView/pv/dialogs/fftoptions.h b/DSView/pv/dialogs/fftoptions.h index 2ef9a8e9..9dcb20e4 100644 --- a/DSView/pv/dialogs/fftoptions.h +++ b/DSView/pv/dialogs/fftoptions.h @@ -23,7 +23,6 @@ #ifndef DSVIEW_PV_FFTOPTIONS_H #define DSVIEW_PV_FFTOPTIONS_H -#include #include #include #include @@ -34,6 +33,8 @@ #include #include "../device/devinst.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" namespace pv { @@ -41,7 +42,7 @@ class SigSession; namespace dialogs { -class FftOptions : public QDialog +class FftOptions : public DSDialog { Q_OBJECT @@ -63,6 +64,7 @@ private: SigSession &_session; uint64_t _sample_limit; + toolbars::TitleBar *_titlebar; QComboBox *_len_combobox; QComboBox *_interval_combobox; QCheckBox *_en_checkbox; diff --git a/DSView/pv/dialogs/messagebox.cpp b/DSView/pv/dialogs/messagebox.cpp new file mode 100644 index 00000000..d0ab4eda --- /dev/null +++ b/DSView/pv/dialogs/messagebox.cpp @@ -0,0 +1,86 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "messagebox.h" + +#include +#include + +namespace pv { +namespace dialogs { + +MessageBox::MessageBox(QWidget *parent) : + QDialog(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + + _msg = new QMessageBox(this); + _msg->setWindowFlags(Qt::FramelessWindowHint | Qt::Widget); + + _titlebar = new toolbars::TitleBar(false, parent); + _titlebar->setTitle(tr("Message")); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(_titlebar); + layout->addWidget(_msg); + setLayout(layout); + + //connect(_msg, SIGNAL(finished(int)), this, SLOT(accept())); + connect(_msg, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(on_button(QAbstractButton*))); +} + +void MessageBox::accept() +{ + using namespace Qt; + + QDialog::accept(); +} + +void MessageBox::reject() +{ + using namespace Qt; + + QDialog::reject(); +} + +QMessageBox* MessageBox::mBox() +{ + return _msg; +} + +int MessageBox::exec() +{ + //_msg->show(); + return QDialog::exec(); +} + +void MessageBox::on_button(QAbstractButton *btn) +{ + QMessageBox::ButtonRole role = _msg->buttonRole(btn); + if (role == QMessageBox::AcceptRole) + accept(); + else + reject(); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/messagebox.h b/DSView/pv/dialogs/messagebox.h new file mode 100644 index 00000000..ca9170b3 --- /dev/null +++ b/DSView/pv/dialogs/messagebox.h @@ -0,0 +1,59 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_MESSAGE_H +#define DSVIEW_PV_MESSAGE_H + +#include +#include + +#include "../toolbars/titlebar.h" + +namespace pv { +namespace dialogs { + +class MessageBox : public QDialog +{ + Q_OBJECT + +public: + MessageBox(QWidget *parent); + QMessageBox *mBox(); + + int exec(); + +protected: + void accept(); + void reject(); + +private slots: + void on_button(QAbstractButton* btn); + +private: + QMessageBox *_msg; + toolbars::TitleBar *_titlebar; +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_MESSAGE_H diff --git a/DSView/pv/dialogs/protocolexp.cpp b/DSView/pv/dialogs/protocolexp.cpp index af0ef69c..b4a6f988 100644 --- a/DSView/pv/dialogs/protocolexp.cpp +++ b/DSView/pv/dialogs/protocolexp.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -48,7 +47,7 @@ namespace pv { namespace dialogs { ProtocolExp::ProtocolExp(QWidget *parent, SigSession &session) : - QDialog(parent), + DSDialog(parent), _session(session), _button_box(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this), @@ -84,13 +83,17 @@ ProtocolExp::ProtocolExp(QWidget *parent, SigSession &session) : } } - _layout = new QVBoxLayout(this); + _layout = new QVBoxLayout(); _layout->addLayout(_flayout); _layout->addWidget(&_button_box); - setLayout(_layout); + + layout()->addLayout(_layout); + setTitle(tr("Protocol Export")); connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject())); + connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); + } void ProtocolExp::accept() diff --git a/DSView/pv/dialogs/protocolexp.h b/DSView/pv/dialogs/protocolexp.h index 0323082d..b978c604 100644 --- a/DSView/pv/dialogs/protocolexp.h +++ b/DSView/pv/dialogs/protocolexp.h @@ -23,7 +23,6 @@ #ifndef DSVIEW_PV_PROTOCOLEXP_H #define DSVIEW_PV_PROTOCOLEXP_H -#include #include #include #include @@ -35,6 +34,8 @@ #include "../device/devinst.h" #include "../prop/binding/deviceoptions.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" namespace pv { @@ -48,7 +49,7 @@ class Row; namespace dialogs { -class ProtocolExp : public QDialog +class ProtocolExp : public DSDialog { Q_OBJECT @@ -68,6 +69,7 @@ private slots: private: SigSession &_session; + toolbars::TitleBar *_titlebar; QComboBox *_format_combobox; std::list _row_sel_list; std::list _row_label_list; diff --git a/DSView/pv/dialogs/protocollist.cpp b/DSView/pv/dialogs/protocollist.cpp index da2451a0..e8d4b5a8 100644 --- a/DSView/pv/dialogs/protocollist.cpp +++ b/DSView/pv/dialogs/protocollist.cpp @@ -26,7 +26,6 @@ #include #include -#include #include "../sigsession.h" #include "../data/decoderstack.h" @@ -41,7 +40,7 @@ namespace pv { namespace dialogs { ProtocolList::ProtocolList(QWidget *parent, SigSession &session) : - QDialog(parent), + DSDialog(parent), _session(session), _button_box(QDialogButtonBox::Ok, Qt::Horizontal, this) @@ -66,14 +65,19 @@ ProtocolList::ProtocolList(QWidget *parent, SigSession &session) : _flayout = new QFormLayout(); _flayout->addRow(new QLabel(tr("Decoded Protocols: "), this), _protocol_combobox); - _layout = new QVBoxLayout(this); + _layout = new QVBoxLayout(); _layout->addLayout(_flayout); _layout->addWidget(&_button_box); - setLayout(_layout); + + setMinimumWidth(300); + layout()->addLayout(_layout); + setTitle(tr("Protocol List Viewer")); connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); connect(_protocol_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(set_protocol(int))); set_protocol(_protocol_combobox->currentIndex()); + connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); + } void ProtocolList::accept() diff --git a/DSView/pv/dialogs/protocollist.h b/DSView/pv/dialogs/protocollist.h index 0f116f7a..8c4524fd 100644 --- a/DSView/pv/dialogs/protocollist.h +++ b/DSView/pv/dialogs/protocollist.h @@ -23,7 +23,6 @@ #ifndef DSVIEW_PV_PROTOCOLLIST_H #define DSVIEW_PV_PROTOCOLLIST_H -#include #include #include #include @@ -35,6 +34,8 @@ #include "../device/devinst.h" #include "../prop/binding/deviceoptions.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" namespace pv { @@ -42,7 +43,7 @@ class SigSession; namespace dialogs { -class ProtocolList : public QDialog +class ProtocolList : public DSDialog { Q_OBJECT @@ -60,6 +61,7 @@ private slots: private: SigSession &_session; + toolbars::TitleBar *_titlebar; QComboBox *_protocol_combobox; std::list _show_checkbox_list; std::list _show_label_list; diff --git a/DSView/pv/dialogs/search.cpp b/DSView/pv/dialogs/search.cpp index 3f177f60..5f41fc44 100644 --- a/DSView/pv/dialogs/search.cpp +++ b/DSView/pv/dialogs/search.cpp @@ -27,11 +27,11 @@ namespace pv { namespace dialogs { -Search::Search(QWidget *parent, struct sr_dev_inst *sdi, QString pattern) : - QDialog(parent), - _sdi(sdi) +Search::Search(QWidget *parent, boost::shared_ptr dev_inst, QString pattern) : + DSDialog(parent), + _dev_inst(dev_inst) { - assert(_sdi); + assert(_dev_inst); QFont font("Monaco"); font.setStyleHint(QFont::Monospace); @@ -54,18 +54,19 @@ Search::Search(QWidget *parent, struct sr_dev_inst *sdi, QString pattern) : search_buttonBox.addButton(QDialogButtonBox::Cancel); QGridLayout *search_layout = new QGridLayout(); - search_layout->addWidget(search_label, 0, 1); - search_layout->addWidget(new QLabel(tr("Search Value: ")), 1,0, Qt::AlignRight); - search_layout->addWidget(&search_lineEdit, 1, 1); - search_layout->addWidget(new QLabel(" "), 2,0); - search_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")), 3, 0); - search_layout->addWidget(&search_buttonBox, 4, 2); - //search_layout->addStretch(1); + search_layout->addWidget(search_label, 1, 1); + search_layout->addWidget(new QLabel(tr("Search Value: ")), 2,0, Qt::AlignRight); + search_layout->addWidget(&search_lineEdit, 2, 1); + search_layout->addWidget(new QLabel(" "), 3,0); + search_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")), 4, 0); + search_layout->addWidget(&search_buttonBox, 5, 2); - setLayout(search_layout); + layout()->addLayout(search_layout); + setTitle(tr("Search Options")); connect(&search_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(&search_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(_dev_inst.get(), SIGNAL(device_updated()), this, SLOT(reject())); } Search::~Search() diff --git a/DSView/pv/dialogs/search.h b/DSView/pv/dialogs/search.h index 9efd762d..7a9d15ac 100644 --- a/DSView/pv/dialogs/search.h +++ b/DSView/pv/dialogs/search.h @@ -23,7 +23,6 @@ #ifndef DSVIEW_PV_SEARCH_H #define DSVIEW_PV_SEARCH_H -#include #include #include #include @@ -31,17 +30,22 @@ #include #include "../sigsession.h" #include +#include "../toolbars/titlebar.h" +#include "dsdialog.h" +#include "../device/devinst.h" + +#include namespace pv { namespace dialogs { -class Search : public QDialog +class Search : public DSDialog { Q_OBJECT public: - Search(QWidget *parent = 0, sr_dev_inst *sdi = 0, QString pattern = ""); + Search(QWidget *parent = 0, boost::shared_ptr dev_inst = 0, QString pattern = ""); ~Search(); QString get_pattern(); @@ -54,9 +58,10 @@ signals: public slots: private: + toolbars::TitleBar *_titlebar; QLineEdit search_lineEdit; QDialogButtonBox search_buttonBox; - sr_dev_inst *_sdi; + boost::shared_ptr _dev_inst; }; } // namespace decoder diff --git a/DSView/pv/dialogs/shadow.cpp b/DSView/pv/dialogs/shadow.cpp new file mode 100755 index 00000000..0fc91ee4 --- /dev/null +++ b/DSView/pv/dialogs/shadow.cpp @@ -0,0 +1,104 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "shadow.h" +#include + +QT_BEGIN_NAMESPACE + extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 ); +QT_END_NAMESPACE + +namespace pv { +namespace dialogs { + +Shadow::Shadow(QObject *parent) : + QGraphicsEffect(parent), + _distance(4.0f), + _blurRadius(10.0f), + _color(0, 0, 0, 80) +{ +} + +void Shadow::draw(QPainter* painter) +{ + // if nothing to show outside the item, just draw source + if ((blurRadius() + distance()) <= 0) { + drawSource(painter); + return; + } + + PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect; + QPoint offset; + const QPixmap px = sourcePixmap(Qt::DeviceCoordinates, &offset, mode); + + // return if no source + if (px.isNull()) + return; + + // save world transform + QTransform restoreTransform = painter->worldTransform(); + painter->setWorldTransform(QTransform()); + + // Calculate size for the background image + QSize szi(px.size().width() + 2 * distance(), px.size().height() + 2 * distance()); + + QImage tmp(szi, QImage::Format_ARGB32_Premultiplied); + QPixmap scaled = px.scaled(szi); + tmp.fill(0); + QPainter tmpPainter(&tmp); + tmpPainter.setCompositionMode(QPainter::CompositionMode_Source); + tmpPainter.drawPixmap(QPointF(-distance(), -distance()), scaled); + tmpPainter.end(); + + // blur the alpha channel + QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied); + blurred.fill(0); + QPainter blurPainter(&blurred); + qt_blurImage(&blurPainter, tmp, blurRadius(), false, true); + blurPainter.end(); + + tmp = blurred; + + // blacken the image... + tmpPainter.begin(&tmp); + tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); + tmpPainter.fillRect(tmp.rect(), color()); + tmpPainter.end(); + + // draw the blurred shadow... + painter->drawImage(offset, tmp); + + // draw the actual pixmap... + painter->drawPixmap(offset, px, QRectF()); + + // restore world transform + painter->setWorldTransform(restoreTransform); +} + +QRectF Shadow::boundingRectFor(const QRectF& rect) const +{ + qreal delta = blurRadius() + distance(); + return rect.united(rect.adjusted(-delta, -delta, delta, delta)); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/shadow.h b/DSView/pv/dialogs/shadow.h new file mode 100755 index 00000000..e37bbbad --- /dev/null +++ b/DSView/pv/dialogs/shadow.h @@ -0,0 +1,59 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_SHADOW_H +#define DSVIEW_PV_SHADOW_H + +#include +#include + +namespace pv { +namespace dialogs { + +class Shadow : public QGraphicsEffect +{ + Q_OBJECT +public: + explicit Shadow(QObject *parent = 0); + + void draw(QPainter* painter); + QRectF boundingRectFor(const QRectF& rect) const; + + inline void setDistance(qreal distance) { _distance = distance; updateBoundingRect(); } + inline qreal distance() const { return _distance; } + + inline void setBlurRadius(qreal blurRadius) { _blurRadius = blurRadius; updateBoundingRect(); } + inline qreal blurRadius() const { return _blurRadius; } + + inline void setColor(const QColor& color) { _color = color; } + inline QColor color() const { return _color; } + +private: + qreal _distance; + qreal _blurRadius; + QColor _color; +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_SHADOW_H diff --git a/DSView/pv/dialogs/storeprogress.cpp b/DSView/pv/dialogs/storeprogress.cpp index f608f548..cbd57200 100644 --- a/DSView/pv/dialogs/storeprogress.cpp +++ b/DSView/pv/dialogs/storeprogress.cpp @@ -19,8 +19,7 @@ */ #include "storeprogress.h" - -#include +#include "dsmessagebox.h" namespace pv { namespace dialogs { @@ -49,11 +48,11 @@ void StoreProgress::run() void StoreProgress::show_error() { - QMessageBox msg(parentWidget()); - msg.setText(tr("Failed to save session.")); - msg.setInformativeText(_session.error()); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(parentWidget()); + msg.mBox()->setText(tr("Failed to save session.")); + msg.mBox()->setInformativeText(_session.error()); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } diff --git a/DSView/pv/dialogs/storeprogress.h b/DSView/pv/dialogs/storeprogress.h index 25c77ab0..c582e3e1 100644 --- a/DSView/pv/dialogs/storeprogress.h +++ b/DSView/pv/dialogs/storeprogress.h @@ -28,6 +28,7 @@ #include #include +#include "../toolbars/titlebar.h" namespace pv { @@ -57,6 +58,8 @@ private slots: private: pv::StoreSession _session; + + toolbars::TitleBar *_titlebar; }; } // dialogs diff --git a/DSView/pv/dialogs/streamoptions.cpp b/DSView/pv/dialogs/streamoptions.cpp deleted file mode 100644 index 7c0432dd..00000000 --- a/DSView/pv/dialogs/streamoptions.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "streamoptions.h" - -#include - -#include -#include -#include - -#include - -using namespace boost; -using namespace std; - -namespace pv { -namespace dialogs { - -StreamOptions::StreamOptions(QWidget *parent, boost::shared_ptr dev_inst, - uint64_t sample_count, bool stream) : - QDialog(parent), - _dev_inst(dev_inst), - _sample_count(sample_count), - _layout(this), - _stream(stream), - _button_box(QDialogButtonBox::Ok, - Qt::Horizontal, this) -{ - setWindowTitle(tr("Stream Mode Options")); - setLayout(&_layout); - - QLabel *_info = new QLabel(this); - if (_stream) - _info->setText(tr("Stream Mode Active!")); - else - _info->setText(tr("Buffer Mode Active!")); - - _layout.addWidget(_info); - - if (_stream) { - _op0 = new QRadioButton(this); - _op1 = new QRadioButton(this); - _op0->setText(tr("16 Channels, Max 10MHz sample rate")); - _op1->setText(tr(" 8 Channels, Max 25MHz sample rate")); - _layout.addWidget(_op0); - _layout.addWidget(_op1); - - if (_sample_count >= SR_GB(1)) { - _op0->setDisabled(true); - _op1->setChecked(true); - }else{ - _op0->setChecked(true); - } - } - - _layout.addWidget(&_button_box); - - connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); - connect(&_button_box, SIGNAL(rejected()), this, SLOT(accept())); -} - -void StreamOptions::accept() -{ - using namespace Qt; - - uint64_t sample_rate = _dev_inst->get_sample_rate(); - if (_stream) { - if (_op0->isChecked()) - sample_rate = (sample_rate <= SR_MHZ(10)) ? sample_rate : SR_MHZ(10); - else if (_op1->isChecked()) - sample_rate = (sample_rate > SR_MHZ(10) && sample_rate <= SR_MHZ(25)) ? sample_rate : SR_MHZ(25); - } - _dev_inst->set_config(NULL, NULL, - SR_CONF_SAMPLERATE, - g_variant_new_uint64(sample_rate)); - - QDialog::accept(); -} - -void StreamOptions::reject() -{ - accept(); -} - -} // namespace dialogs -} // namespace pv diff --git a/DSView/pv/dialogs/waitingdialog.cpp b/DSView/pv/dialogs/waitingdialog.cpp index 1bd53daa..7996b988 100644 --- a/DSView/pv/dialogs/waitingdialog.cpp +++ b/DSView/pv/dialogs/waitingdialog.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "libsigrok4DSL/libsigrok.h" #include "../view/trace.h" @@ -43,22 +44,18 @@ const QString WaitingDialog::TIPS_WAIT = tr("Waiting"); const QString WaitingDialog::TIPS_FINISHED = tr("Finished!"); WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptr dev_inst) : - QDialog(parent), + DSDialog(parent), _dev_inst(dev_inst), - _button_box(QDialogButtonBox::Save | QDialogButtonBox::Abort, + _button_box(QDialogButtonBox::Abort, Qt::Horizontal, this) { this->setFixedSize((GIF_WIDTH+TIP_WIDTH)*1.2, (GIF_HEIGHT+TIP_HEIGHT)*4); - int midx = this->width() / 2; - int midy = this->height() / 2; - this->setWindowOpacity(0.5); - this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); + this->setWindowOpacity(0.7); label = new QLabel(this); - label->setStyleSheet("background-color: transparent;"); - label->setGeometry(midx-GIF_WIDTH/2, midy-GIF_HEIGHT/2, GIF_WIDTH, GIF_HEIGHT); movie = new QMovie(":/icons/wait.gif"); label->setMovie(movie); + label->setAlignment(Qt::AlignCenter); tips = new QLabel(this); tips->setText(TIPS_WAIT); @@ -66,17 +63,23 @@ WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptrsetFont(font); - tips->setGeometry(midx-TIP_WIDTH/2, midy+GIF_HEIGHT/2, TIP_WIDTH, TIP_HEIGHT); + tips->setAlignment(Qt::AlignCenter); index = 0; timer = new QTimer(); connect(timer, SIGNAL(timeout()), this, SLOT(changeText())); - - _button_box.setGeometry(width()-_button_box.width()-30, height()-_button_box.height()-15, - _button_box.width(), _button_box.height()); connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject())); - _button_box.buttons().front()->setVisible(false); + connect(_dev_inst.get(), SIGNAL(device_updated()), this, SLOT(stop())); + + + QVBoxLayout *mlayout = new QVBoxLayout(); + mlayout->addWidget(label, Qt::AlignHCenter); + mlayout->addWidget(tips, Qt::AlignHCenter); + mlayout->addWidget(&_button_box); + + layout()->addLayout(mlayout); + setTitle(tr("Zero Adjustment")); } void WaitingDialog::accept() @@ -137,6 +140,15 @@ void WaitingDialog::reject() dlg.exec(); } +void WaitingDialog::stop() +{ + using namespace Qt; + + movie->stop(); + timer->stop(); + QDialog::reject(); +} + void WaitingDialog::start() { movie->start(); @@ -162,7 +174,7 @@ void WaitingDialog::changeText() timer->stop(); tips->setAlignment(Qt::AlignHCenter); tips->setText(TIPS_FINISHED); - _button_box.buttons().front()->setVisible(true); + _button_box.addButton(QDialogButtonBox::Save); } } } else { diff --git a/DSView/pv/dialogs/waitingdialog.h b/DSView/pv/dialogs/waitingdialog.h index 7693dd78..b611c2c4 100644 --- a/DSView/pv/dialogs/waitingdialog.h +++ b/DSView/pv/dialogs/waitingdialog.h @@ -23,7 +23,6 @@ #ifndef DSVIEW_PV_WAITINGDIALOG_H #define DSVIEW_PV_WAITINGDIALOG_H -#include #include #include #include @@ -32,11 +31,13 @@ #include #include +#include "../toolbars/titlebar.h" +#include "dsdialog.h" namespace pv { namespace dialogs { -class WaitingDialog : public QDialog +class WaitingDialog : public DSDialog { Q_OBJECT @@ -60,10 +61,11 @@ protected: private slots: void changeText(); + void stop(); private: boost::shared_ptr _dev_inst; - + toolbars::TitleBar *_titlebar; QDialogButtonBox _button_box; int index; diff --git a/DSView/pv/dock/dsotriggerdock.cpp b/DSView/pv/dock/dsotriggerdock.cpp index f7746d63..38c0542d 100644 --- a/DSView/pv/dock/dsotriggerdock.cpp +++ b/DSView/pv/dock/dsotriggerdock.cpp @@ -23,13 +23,13 @@ #include "dsotriggerdock.h" #include "../sigsession.h" #include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" #include #include #include #include #include -#include #include #include @@ -167,11 +167,11 @@ void DsoTriggerDock::pos_changed(int pos) SR_CONF_HORIZ_TRIGGERPOS, g_variant_new_byte((uint8_t)pos)); if (!ret) { - QMessageBox msg(this); - msg.setText(tr("Trigger Setting Issue")); - msg.setInformativeText(tr("Change horiz trigger position failed!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change horiz trigger position failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } @@ -196,11 +196,11 @@ void DsoTriggerDock::hold_changed(int hold) g_variant_new_uint64(holdoff)); if (!ret) { - QMessageBox msg(this); - msg.setText(tr("Trigger Setting Issue")); - msg.setInformativeText(tr("Change trigger hold off time failed!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger hold off time failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } } @@ -214,11 +214,11 @@ void DsoTriggerDock::source_changed() SR_CONF_TRIGGER_SOURCE, g_variant_new_byte(id)); if (!ret) { - QMessageBox msg(this); - msg.setText(tr("Trigger Setting Issue")); - msg.setInformativeText(tr("Change trigger source failed!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger source failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } } @@ -232,11 +232,11 @@ void DsoTriggerDock::type_changed() SR_CONF_TRIGGER_SLOPE, g_variant_new_byte(id)); if (!ret) { - QMessageBox msg(this); - msg.setText(tr("Trigger Setting Issue")); - msg.setInformativeText(tr("Change trigger type failed!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger type failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } } diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp index 27f83a83..eaabcb8d 100644 --- a/DSView/pv/dock/protocoldock.cpp +++ b/DSView/pv/dock/protocoldock.cpp @@ -28,11 +28,11 @@ #include "../data/decoderstack.h" #include "../dialogs/protocollist.h" #include "../dialogs/protocolexp.h" +#include "../dialogs/dsmessagebox.h" #include #include #include -#include #include #include #include @@ -223,11 +223,11 @@ int ProtocolDock::decoder_name_cmp(const void *a, const void *b) void ProtocolDock::add_protocol() { if (_session.get_device()->dev_inst()->mode != LOGIC) { - QMessageBox msg(this); - msg.setText(tr("Protocol Analyzer")); - msg.setInformativeText(tr("Protocol Analyzer is only valid in Digital Mode!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Protocol Analyzer")); + msg.mBox()->setInformativeText(tr("Protocol Analyzer is only valid in Digital Mode!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } else { srd_decoder *const decoder = @@ -330,11 +330,11 @@ void ProtocolDock::del_protocol() _progress_label_list.clear(); _protocol_index_list.clear(); } else { - QMessageBox msg(this); - msg.setText(tr("Protocol Analyzer")); - msg.setInformativeText(tr("No Protocol Analyzer to delete!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(NULL); + msg.mBox()->setText(tr("Protocol Analyzer")); + msg.mBox()->setInformativeText(tr("No Protocol Analyzer to delete!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } } else { diff --git a/DSView/pv/dock/searchdock.cpp b/DSView/pv/dock/searchdock.cpp index c3801a31..c0b1871b 100644 --- a/DSView/pv/dock/searchdock.cpp +++ b/DSView/pv/dock/searchdock.cpp @@ -30,13 +30,13 @@ #include "../data/snapshot.h" #include "../data/logicsnapshot.h" #include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" #include #include #include #include #include -#include #include #include @@ -118,31 +118,31 @@ void SearchDock::on_previous() last_pos = _view.get_search_pos(); if (last_pos == 0) { - QMessageBox msg(this); - msg.setText(tr("Search")); - msg.setInformativeText(tr("Search cursor at the start position!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Search cursor at the start position!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } else { data = (uint8_t*)_session.get_buf(unit_size, length); if (data == NULL) { - QMessageBox msg(this); - msg.setText(tr("Search")); - msg.setInformativeText(tr("No Sample data!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("No Sample data!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } else { const bool ret = search_value(data, unit_size, length, last_pos, 1, value); if (!ret) { - QMessageBox msg(this); - msg.setText(tr("Search")); - msg.setInformativeText(tr("Pattern ") + value + tr(" not found!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Pattern ") + value + tr(" not found!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } else { @@ -163,30 +163,30 @@ void SearchDock::on_next() last_pos = _view.get_search_pos(); if (last_pos == length - 1) { - QMessageBox msg(this); - msg.setText(tr("Search")); - msg.setInformativeText(tr("Search cursor at the end position!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Search cursor at the end position!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } else { if (data == NULL) { - QMessageBox msg(this); - msg.setText(tr("Search")); - msg.setInformativeText(tr("No Sample data!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("No Sample data!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } else { const int ret = search_value(data, unit_size, length, last_pos, 0, value); if (!ret) { - QMessageBox msg(this); - msg.setText(tr("Search")); - msg.setInformativeText(tr("Pattern ") + value + tr(" not found!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Pattern ") + value + tr(" not found!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } else { @@ -198,7 +198,7 @@ void SearchDock::on_next() void SearchDock::on_set() { - dialogs::Search dlg(this, _session.get_device()->dev_inst(), _pattern); + dialogs::Search dlg(this, _session.get_device(), _pattern); if (dlg.exec()) { _pattern = dlg.get_pattern(); _pattern.remove(QChar(' '), Qt::CaseInsensitive); diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp index 5dcb218a..bef00fd4 100644 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -23,13 +23,13 @@ #include "triggerdock.h" #include "../sigsession.h" #include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" #include #include #include #include #include -#include #include #include "libsigrok4DSL/libsigrok.h" @@ -293,22 +293,22 @@ void TriggerDock::adv_trigger() g_variant_unref(gvar); } if (stream) { - QMessageBox msg(this); - msg.setText(tr("Trigger")); - msg.setInformativeText(tr("Stream Mode Don't Support Advanced Trigger!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger")); + msg.mBox()->setInformativeText(tr("Stream Mode Don't Support Advanced Trigger!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); simple_radioButton->setChecked(true); } else { widget_enable(0); } } else { - QMessageBox msg(this); - msg.setText(tr("Trigger")); - msg.setInformativeText(tr("Advanced Trigger need DSLogic Hardware Support!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger")); + msg.mBox()->setInformativeText(tr("Advanced Trigger need DSLogic Hardware Support!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); simple_radioButton->setChecked(true); } diff --git a/DSView/pv/mainframe.cpp b/DSView/pv/mainframe.cpp new file mode 100644 index 00000000..6049f41a --- /dev/null +++ b/DSView/pv/mainframe.cpp @@ -0,0 +1,307 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "mainframe.h" + +#include "toolbars/titlebar.h" +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace pv { + +MainFrame::MainFrame(DeviceManager &device_manager, + const char *open_file_name) +{ + setAttribute(Qt::WA_TranslucentBackground); + // Make this a borderless window which can't + // be resized or moved via the window system + setWindowFlags(Qt::FramelessWindowHint); + setMinimumHeight(680); + setMinimumWidth(800); + //resize(1024, 768); + + _moving = false; + _startPos = None; + _freezing = false; + + // MainWindow + _mainWindow = new MainWindow(device_manager, open_file_name, this); + _mainWindow->setWindowFlags(Qt::Widget); + + // Title + _titleBar = new toolbars::TitleBar(true, this); + _titleBar->installEventFilter(this); + _titleBar->setTitle(_mainWindow->windowTitle()); + + QVBoxLayout *vbox = new QVBoxLayout(); + vbox->setMargin(0); + vbox->setSpacing(0); + vbox->addWidget(_titleBar); + vbox->addWidget(_mainWindow); + + _top_left = new widgets::Border (TopLeft, this); + _top_left->setFixedSize(Margin, Margin); + _top_left->installEventFilter(this); + _top = new widgets::Border (Top, this); + _top->setFixedHeight(Margin); + _top->installEventFilter(this); + _top_right = new widgets::Border (TopRight, this); + _top_right->setFixedSize(Margin, Margin); + _top_right->installEventFilter(this); + + _left = new widgets::Border (Left, this); + _left->setFixedWidth(Margin); + _left->installEventFilter(this); + _right = new widgets::Border (Right, this); + _right->setFixedWidth(Margin); + _right->installEventFilter(this); + + _bottom_left = new widgets::Border (BottomLeft, this); + _bottom_left->setFixedSize(Margin, Margin); + _bottom_left->installEventFilter(this); + _bottom = new widgets::Border (Bottom, this); + _bottom->setFixedHeight(Margin); + _bottom->installEventFilter(this); + _bottom_right = new widgets::Border (BottomRight, this); + _bottom_right->setFixedSize(Margin, Margin); + _bottom_right->installEventFilter(this); + + _layout = new QGridLayout(this); + _layout->setMargin(0); + _layout->setSpacing(0); + _layout->addWidget(_top_left, 0, 0); + _layout->addWidget(_top, 0, 1); + _layout->addWidget(_top_right, 0, 2); + _layout->addWidget(_left, 1, 0); + _layout->addLayout(vbox, 1, 1); + _layout->addWidget(_right, 1, 2); + _layout->addWidget(_bottom_left, 2, 0); + _layout->addWidget(_bottom, 2, 1); + _layout->addWidget(_bottom_right, 2, 2); + + connect(&_timer, SIGNAL(timeout()), this, SLOT(unfreezing())); +} + +bool MainFrame::close() +{ + _mainWindow->session_save(); + return QFrame::close(); +} + +void MainFrame::unfreezing() +{ + _freezing = false; +} + +void MainFrame::hide_border() +{ + _top_left->setVisible(false); + _top_right->setVisible(false); + _top->setVisible(false); + _left->setVisible(false); + _right->setVisible(false); + _bottom_left->setVisible(false); + _bottom->setVisible(false); + _bottom_right->setVisible(false); +} + +void MainFrame::show_border() +{ + _top_left->setVisible(true); + _top_right->setVisible(true); + _top->setVisible(true); + _left->setVisible(true); + _right->setVisible(true); + _bottom_left->setVisible(true); + _bottom->setVisible(true); + _bottom_right->setVisible(true); +} + +void MainFrame::showNormal() +{ + show_border(); + QFrame::showNormal(); +} + +void MainFrame::showMaximized() +{ + hide_border(); + QFrame::showMaximized(); +} + +bool MainFrame::eventFilter(QObject *object, QEvent *event) +{ + const QEvent::Type type = event->type(); + const QMouseEvent *const mouse_event = (QMouseEvent*)event; + int newWidth; + int newHeight; + int newLeft; + int newTop; + + if (type == QEvent::MouseMove && !isMaximized()) { + if (!(mouse_event->buttons() || Qt::NoButton)) { + if (object == _top_left) { + _startPos = TopLeft; + setCursor(Qt::SizeFDiagCursor); + } else if (object == _bottom_right) { + _startPos = BottomRight; + setCursor(Qt::SizeFDiagCursor); + } else if (object == _top_right) { + _startPos = TopRight; + setCursor(Qt::SizeBDiagCursor); + } else if (object == _bottom_left) { + _startPos = BottomLeft; + setCursor(Qt::SizeBDiagCursor); + } else if (object == _left) { + _startPos = Left; + setCursor(Qt::SizeHorCursor); + } else if (object == _right) { + _startPos = Right; + setCursor(Qt::SizeHorCursor); + } else if (object == _bottom) { + _startPos = Bottom; + setCursor(Qt::SizeVerCursor); + } else if (object == _top) { + _startPos = Top; + setCursor(Qt::SizeVerCursor); + } else { + _startPos = None; + setCursor(Qt::ArrowCursor); + } + } else if(mouse_event->buttons().testFlag(Qt::LeftButton)) { + if (_moving) { + this->move(mouse_event->globalPos() - _lastMousePosition); + } else if (!_freezing){ + switch (_startPos) { + case TopLeft: + newWidth = std::max(_dragStartGeometry.right() - mouse_event->globalX(), minimumWidth()); + newHeight = std::max(_dragStartGeometry.bottom() - mouse_event->globalY(), minimumHeight()); + newLeft = geometry().left(); + newTop = geometry().top(); + if (newWidth > minimumWidth()) + newLeft = mouse_event->globalX(); + if (newHeight > minimumHeight()) + newTop = mouse_event->globalY(); + setGeometry(newLeft, newTop, + newWidth, newHeight); + break; + case BottomLeft: + newWidth = std::max(_dragStartGeometry.right() - mouse_event->globalX(), minimumWidth()); + newHeight = std::max(mouse_event->globalY() - _dragStartGeometry.top(), minimumHeight()); + newLeft = geometry().left(); + if (newWidth > minimumWidth()) + newLeft = mouse_event->globalX(); + setGeometry(newLeft, _dragStartGeometry.top(), + newWidth, newHeight); + break; + case TopRight: + newWidth = std::max(mouse_event->globalX() - _dragStartGeometry.left(), minimumWidth()); + newHeight = std::max(_dragStartGeometry.bottom() - mouse_event->globalY(), minimumHeight()); + newTop = geometry().top(); + if (newHeight > minimumHeight()) + newTop = mouse_event->globalY(); + setGeometry(_dragStartGeometry.left(), newTop, + newWidth, newHeight); + break; + case BottomRight: + newWidth = std::max(mouse_event->globalX() - _dragStartGeometry.left(), minimumWidth()); + newHeight = std::max(mouse_event->globalY() - _dragStartGeometry.top(), minimumHeight()); + setGeometry(_dragStartGeometry.left(), _dragStartGeometry.top(), + newWidth, newHeight); + break; + case Left: + newWidth = _dragStartGeometry.right() - mouse_event->globalX(); + if (newWidth > minimumWidth()) + setGeometry(mouse_event->globalX(), _dragStartGeometry.top(), + newWidth, height()); + break; + case Right: + newWidth = mouse_event->globalX() - _dragStartGeometry.left(); + if (newWidth > minimumWidth()) + setGeometry(_dragStartGeometry.left(), _dragStartGeometry.top(), + newWidth, height()); + break; + case Top: + newHeight = _dragStartGeometry.bottom() - mouse_event->globalY(); + if (newHeight > minimumHeight()) + setGeometry(_dragStartGeometry.left(), mouse_event->globalY(), + width(), newHeight); + break; + case Bottom: + newHeight = mouse_event->globalY() - _dragStartGeometry.top(); + if (newHeight > minimumHeight()) + setGeometry(_dragStartGeometry.left(), _dragStartGeometry.top(), + width(), newHeight); + break; + default: + break; + } + _freezing = true; + } + return true; + } + } else if (type == QEvent::MouseButtonPress) { + if (mouse_event->button() == Qt::LeftButton) + if (_titleBar->rect().contains(mouse_event->pos()) && + _startPos == None) { + _moving = true; + _lastMousePosition = mouse_event->pos() + + QPoint(Margin, Margin) + + QPoint(geometry().left() - frameGeometry().left(), frameGeometry().right() - geometry().right()); + } + if (_startPos != None) + _draging = true; + _timer.start(50); + _dragStartGeometry = geometry(); + } else if (type == QEvent::MouseButtonRelease) { + if (mouse_event->button() == Qt::LeftButton) { + _moving = false; + _draging = false; + _timer.stop(); + } + } else if (!_draging && type == QEvent::Leave) { + _startPos = None; + setCursor(Qt::ArrowCursor); + } else if (type == QEvent::Resize) { + if (isMaximized()) { + hide_border(); + } else { + show_border(); + } + _titleBar->setRestoreButton(isMaximized()); + _layout->update(); + } + + return QObject::eventFilter(object, event); +} + +} // namespace pv diff --git a/DSView/pv/mainframe.h b/DSView/pv/mainframe.h new file mode 100644 index 00000000..eafc317c --- /dev/null +++ b/DSView/pv/mainframe.h @@ -0,0 +1,103 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_MAINFRAME_H +#define DSVIEW_PV_MAINFRAME_H + +#include "widgets/border.h" + +#include +#include +#include + +namespace pv { + +class DeviceManager; +class MainWindow; + +namespace toolbars { +class TitleBar; +} + +class MainFrame : public QFrame +{ + Q_OBJECT + +public: + static const int Margin = 8; + + enum borderTypes{ + None, + TopLeft, + Left, + BottomLeft, + Bottom, + BottomRight, + Right, + TopRight, + Top + }borderTypes; + +public: + MainFrame(DeviceManager &device_manager, + const char *open_file_name = NULL); + + void showMaxRestore(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +public slots: + void unfreezing(); + bool close(); + void showNormal(); + void showMaximized(); +private: + void hide_border(); + void show_border(); + +private: + toolbars::TitleBar *_titleBar; + MainWindow *_mainWindow; + + QGridLayout *_layout; + widgets::Border *_left; + widgets::Border *_right; + widgets::Border *_top; + widgets::Border *_bottom; + widgets::Border *_top_left; + widgets::Border *_top_right; + widgets::Border *_bottom_left; + widgets::Border *_bottom_right; + + bool _moving; + bool _draging; + QPoint _lastMousePosition; + QRect _dragStartGeometry; + int _startPos; + QTimer _timer; + bool _freezing; +}; + +} // namespace pv + +#endif // DSVIEW_PV_MAINFRAME_H diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 5dc78610..ca9825e4 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -56,11 +56,13 @@ #include "dialogs/deviceoptions.h" #include "dialogs/storeprogress.h" #include "dialogs/waitingdialog.h" +#include "dialogs/dsmessagebox.h" #include "toolbars/samplingbar.h" #include "toolbars/trigbar.h" #include "toolbars/filebar.h" #include "toolbars/logobar.h" +#include "toolbars/titlebar.h" #include "dock/triggerdock.h" #include "dock/dsotriggerdock.h" @@ -87,8 +89,6 @@ using boost::dynamic_pointer_cast; using std::list; using std::vector; -extern char AppDataPath[256]; - namespace pv { MainWindow::MainWindow(DeviceManager &device_manager, @@ -113,9 +113,8 @@ MainWindow::MainWindow(DeviceManager &device_manager, void MainWindow::setup_ui() { setObjectName(QString::fromUtf8("MainWindow")); - setMinimumHeight(680); - setMinimumWidth(800); - resize(1024, 768); + layout()->setMargin(0); + layout()->setSpacing(0); // Set the window icon QIcon icon; @@ -126,7 +125,7 @@ void MainWindow::setup_ui() // Setup the central widget _central_widget = new QWidget(this); _vertical_layout = new QVBoxLayout(_central_widget); - _vertical_layout->setSpacing(6); + _vertical_layout->setSpacing(0); _vertical_layout->setContentsMargins(0, 0, 0, 0); setCentralWidget(_central_widget); @@ -356,16 +355,17 @@ void MainWindow::load_file(QString file_name) void MainWindow::show_session_error( const QString text, const QString info_text) { - QMessageBox msg(this); - msg.setText(text); - msg.setInformativeText(info_text); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(text); + msg.mBox()->setInformativeText(info_text); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } void MainWindow::device_attach() { + _session.get_device()->device_updated(); //_session.stop_hot_plug_proc(); if (_session.get_capture_state() == SigSession::Running) @@ -384,12 +384,14 @@ void MainWindow::device_attach() void MainWindow::device_detach() { + _session.get_device()->device_updated(); //_session.stop_hot_plug_proc(); if (_session.get_capture_state() == SigSession::Running) _session.stop_capture(); session_save(); + _view->hide_calibration(); struct sr_dev_driver **const drivers = sr_driver_list(); struct sr_dev_driver **driver; @@ -453,33 +455,33 @@ void MainWindow::test_data_error() { _session.stop_capture(); - QMessageBox msg(this); - msg.setText(tr("Data Error")); - msg.setInformativeText(tr("the receive data are not consist with pre-defined test data")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Data Error")); + msg.mBox()->setInformativeText(tr("the receive data are not consist with pre-defined test data")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } void MainWindow::malloc_error() { _session.stop_capture(); - QMessageBox msg(this); - msg.setText(tr("Malloc Error")); - msg.setInformativeText(tr("Memory is not enough for this sample!\nPlease reduce the sample depth!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Malloc Error")); + msg.mBox()->setInformativeText(tr("Memory is not enough for this sample!\nPlease reduce the sample depth!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } void MainWindow::hardware_connect_failed() { _session.stop_capture(); - QMessageBox msg(this); - msg.setText(tr("Hardware Connect Failed")); - msg.setInformativeText(tr("Please check hardware connection!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Hardware Connect Failed")); + msg.mBox()->setInformativeText(tr("Please check hardware connection!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } @@ -606,11 +608,11 @@ bool MainWindow::load_session(QString name) { QFile sessionFile(name); if (!sessionFile.open(QIODevice::ReadOnly)) { - QMessageBox msg(this); - msg.setText(tr("File Error")); - msg.setInformativeText(tr("Couldn't open session file!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("File Error")); + msg.mBox()->setInformativeText(tr("Couldn't open session file!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return false; } @@ -623,11 +625,11 @@ bool MainWindow::load_session(QString name) const sr_dev_inst *const sdi = _session.get_device()->dev_inst(); if (strcmp(sdi->driver->name, sessionObj["Device"].toString().toLocal8Bit()) != 0 || sdi->mode != sessionObj["DeviceMode"].toDouble()) { - QMessageBox msg(this); - msg.setText(tr("Session Error")); - msg.setInformativeText(tr("Session File is not compatible with current device or mode!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Session Error")); + msg.mBox()->setInformativeText(tr("Session File is not compatible with current device or mode!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return false; } @@ -719,11 +721,11 @@ bool MainWindow::store_session(QString name) { QFile sessionFile(name); if (!sessionFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - QMessageBox msg(this); - msg.setText(tr("File Error")); - msg.setInformativeText(tr("Couldn't open session file to write!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("File Error")); + msg.mBox()->setInformativeText(tr("Couldn't open session file to write!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return false; } @@ -805,10 +807,8 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) { (void) object; - if( event->type() == QEvent::KeyPress ) { - const vector< shared_ptr > sigs( - _session.get_signals()); - + if ( event->type() == QEvent::KeyPress ) { + const vector< shared_ptr > sigs(_session.get_signals()); QKeyEvent *ke = (QKeyEvent *) event; switch(ke->key()) { case Qt::Key_S: diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 5159d077..f6cdb0b6 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -76,6 +76,8 @@ public: const char *open_file_name = NULL, QWidget *parent = 0); + void session_save(); + protected: void closeEvent(QCloseEvent *event); @@ -86,8 +88,6 @@ private: bool eventFilter(QObject *object, QEvent *event); - void session_save(); - private slots: void load_file(QString file_name); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 3abb5eac..1c9e7f1e 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -56,11 +56,11 @@ #include #include -#include #include #include #include #include +#include #include #include @@ -194,7 +194,7 @@ void SigSession::set_file(QString name) throw(QString) } } -void SigSession::save_file(const QString name, int type){ +void SigSession::save_file(const QString name, QWidget* parent, int type){ unsigned char* data; int unit_size; uint64_t sample_count; @@ -231,8 +231,23 @@ void SigSession::save_file(const QString name, int type){ sample_count = snapshot->get_sample_count(); } - sr_session_save(name.toLocal8Bit().data(), _dev_inst->dev_inst(), - data, unit_size, sample_count, _trigger_time.toMSecsSinceEpoch(), _trigger_pos); + QFuture future; + future = QtConcurrent::run([&]{ + sr_session_save(name.toLocal8Bit().data(), _dev_inst->dev_inst(), + data, unit_size, sample_count, _trigger_time.toMSecsSinceEpoch(), _trigger_pos); + }); + Qt::WindowFlags flags = Qt::CustomizeWindowHint; + QProgressDialog dlg(tr("Save Capture to File... It can take a while."), + tr("Cancel"),0,0,parent,flags); + dlg.setWindowModality(Qt::WindowModal); + dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); + dlg.setCancelButton(NULL); + + QFutureWatcher watcher; + watcher.setFuture(future); + connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + + dlg.exec(); } QList SigSession::getSuportedExportFormats(){ diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 5a9d8fa8..d046cbde 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -119,7 +119,7 @@ public: void set_file(QString name) throw(QString); - void save_file(const QString name, int type); + void save_file(const QString name, QWidget* parent, int type); void set_default_device(boost::function error_handler); void export_file(const QString name, QWidget* parent, const QString ext); diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index 6007ad66..9f10daa6 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -25,17 +25,15 @@ #include #include -#include #include #include #include "filebar.h" #include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" #include -extern char AppDataPath[256]; - namespace pv { namespace toolbars { @@ -144,11 +142,11 @@ void FileBar::session_error( void FileBar::show_session_error( const QString text, const QString info_text) { - QMessageBox msg(this); - msg.setText(text); - msg.setInformativeText(info_text); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(text); + msg.mBox()->setInformativeText(info_text); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } @@ -157,11 +155,11 @@ void FileBar::on_actionExport_triggered(){ uint64_t length; const void* buf = _session.get_buf(unit_size, length); if (!buf) { - QMessageBox msg(this); - msg.setText(tr("Data Export")); - msg.setInformativeText(tr("No Data to Save!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Data Export")); + msg.mBox()->setInformativeText(tr("No Data to Save!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } else { QList supportedFormats = _session.getSuportedExportFormats(); @@ -191,11 +189,11 @@ void FileBar::on_actionSave_triggered() uint64_t length; const void* buf = _session.get_buf(unit_size, length); if (!buf) { - QMessageBox msg(this); - msg.setText(tr("File Save")); - msg.setInformativeText(tr("No Data to Save!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("File Save")); + msg.mBox()->setInformativeText(tr("No Data to Save!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } else { QString file_name = QFileDialog::getSaveFileName( @@ -206,7 +204,7 @@ void FileBar::on_actionSave_triggered() QFileInfo f(file_name); if(f.suffix().compare("dsl")) file_name.append(tr(".dsl")); - _session.save_file(file_name, _session.get_device()->dev_inst()->mode); + _session.save_file(file_name, this, _session.get_device()->dev_inst()->mode); } } } @@ -226,11 +224,11 @@ void FileBar::on_actionDefault_triggered() { QDir dir(DS_RES_PATH); if (!dir.exists()) { - QMessageBox msg(this); - msg.setText(tr("Session Load")); - msg.setInformativeText(tr("Cannot find default session file for this device!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Session Load")); + msg.mBox()->setInformativeText(tr("Cannot find default session file for this device!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); return; } diff --git a/DSView/pv/toolbars/logobar.cpp b/DSView/pv/toolbars/logobar.cpp index 8f19e614..91d52539 100644 --- a/DSView/pv/toolbars/logobar.cpp +++ b/DSView/pv/toolbars/logobar.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -32,6 +31,7 @@ #include "logobar.h" #include "../dialogs/about.h" +#include "../dialogs/dsmessagebox.h" namespace pv { namespace toolbars { @@ -93,11 +93,11 @@ void LogoBar::session_error( void LogoBar::show_session_error( const QString text, const QString info_text) { - QMessageBox msg(this); - msg.setText(text); - msg.setInformativeText(info_text); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(text); + msg.mBox()->setInformativeText(info_text); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index 15cf2c81..b2ca6c0c 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include "samplingbar.h" @@ -39,7 +38,7 @@ #include "../device/devinst.h" #include "../dialogs/deviceoptions.h" #include "../dialogs/waitingdialog.h" -#include "../dialogs/streamoptions.h" +#include "../dialogs/dsmessagebox.h" #include "../view/dsosignal.h" using namespace boost; @@ -97,6 +96,8 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : _instant(false) { setMovable(false); + layout()->setMargin(0); + layout()->setSpacing(0); connect(&_device_selector, SIGNAL(currentIndexChanged (int)), this, SLOT(on_device_selected())); @@ -124,7 +125,9 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : connect(&_sample_rate, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplerate_sel(int))); - addWidget(new QLabel(tr(" "))); + QWidget *leftMargin = new QWidget(this); + leftMargin->setFixedWidth(4); + addWidget(leftMargin); addWidget(&_device_selector); addWidget(&_configure_button); addWidget(&_sample_count); @@ -211,8 +214,10 @@ void SamplingBar::on_configure() if (gvar != NULL) { bool zero = g_variant_get_boolean(gvar); g_variant_unref(gvar); - if (zero) + if (zero) { zero_adj(); + return; + } } gvar = dev_inst->get_config(NULL, NULL, SR_CONF_CALI); @@ -221,25 +226,25 @@ void SamplingBar::on_configure() g_variant_unref(gvar); if (cali) { show_calibration(); + return; } } } - } - - GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TEST); - if (gvar != NULL) { - bool test = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - if (test) { - update_sample_count_selector_value(); - update_sample_rate_selector_value(); - #ifndef TEST_MODE - _sample_count.setDisabled(true); - _sample_rate.setDisabled(true); - #endif - } else if (dev_inst->dev_inst()->mode != DSO) { - _sample_count.setDisabled(false); - _sample_rate.setDisabled(false); + gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TEST); + if (gvar != NULL) { + bool test = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + if (test) { + update_sample_count_selector_value(); + update_sample_rate_selector_value(); + #ifndef TEST_MODE + _sample_count.setDisabled(true); + _sample_rate.setDisabled(true); + #endif + } else if (dev_inst->dev_inst()->mode != DSO) { + _sample_count.setDisabled(false); + _sample_rate.setDisabled(false); + } } } } @@ -257,7 +262,8 @@ void SamplingBar::zero_adj() pv::dialogs::WaitingDialog wait(this, get_selected_device()); wait.start(); - run_stop(); + if (_session.get_capture_state() == pv::SigSession::Running) + run_stop(); } uint64_t SamplingBar::get_record_length() const @@ -649,15 +655,14 @@ void SamplingBar::on_run_stop() bool zero = g_variant_get_boolean(gvar); g_variant_unref(gvar); if (zero) { - QMessageBox msg(this); - msg.setText(tr("Zero Adjustment")); - msg.setInformativeText(tr("Please adjust zero skew and save the result!")); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Zero Adjustment")); + msg.mBox()->setInformativeText(tr("Please adjust zero skew and save the result!")); //msg.setStandardButtons(QMessageBox::Ok); - msg.addButton(tr("Ok"), QMessageBox::AcceptRole); - msg.addButton(tr("Skip"), QMessageBox::RejectRole); - msg.setIcon(QMessageBox::Warning); - int ret = msg.exec(); - if ( ret == QMessageBox::AcceptRole) { + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->addButton(tr("Skip"), QMessageBox::RejectRole); + msg.mBox()->setIcon(QMessageBox::Warning); + if (msg.exec()) { zero_adj(); } else { dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false)); @@ -687,15 +692,14 @@ void SamplingBar::on_instant_stop() bool zero = g_variant_get_boolean(gvar); g_variant_unref(gvar); if (zero) { - QMessageBox msg(this); - msg.setText(tr("Zero Adjustment")); - msg.setInformativeText(tr("Zero adjustment program will be started. Please keep all channels out of singal input. It can take a while!")); - //msg.setStandardButtons(QMessageBox::Ok); - msg.addButton(tr("Ok"), QMessageBox::AcceptRole); - msg.addButton(tr("Skip"), QMessageBox::RejectRole); - msg.setIcon(QMessageBox::Warning); - int ret = msg.exec(); - if ( ret == QMessageBox::AcceptRole) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Zero Adjustment")); + msg.mBox()->setInformativeText(tr("Zero adjustment program will be started. Please keep all channels out of singal input. It can take a while!")); + //msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->addButton(tr("Skip"), QMessageBox::RejectRole); + msg.mBox()->setIcon(QMessageBox::Warning); + if (msg.exec()) { zero_adj(); } else { dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false)); @@ -758,11 +762,11 @@ void SamplingBar::enable_instant(bool enable) void SamplingBar::show_session_error( const QString text, const QString info_text) { - QMessageBox msg(this); - msg.setText(text); - msg.setInformativeText(info_text); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(text); + msg.mBox()->setInformativeText(info_text); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); msg.exec(); } diff --git a/DSView/pv/toolbars/titlebar.cpp b/DSView/pv/toolbars/titlebar.cpp new file mode 100644 index 00000000..942a3fd8 --- /dev/null +++ b/DSView/pv/toolbars/titlebar.cpp @@ -0,0 +1,189 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "titlebar.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_WIN +#pragma comment(lib, "user32.lib") +#include +#endif + +namespace pv { +namespace toolbars { + +TitleBar::TitleBar(bool top, QWidget *parent, bool hasClose) : + _moving(false), + _isTop(top), + _hasClose(hasClose), + QWidget(parent) +{ + setObjectName("TitleBar"); + setFixedHeight(28); + + _title = new QLabel(this); + QHBoxLayout *hbox = new QHBoxLayout(this); + hbox->addWidget(_title); + + if (_isTop) { + _minimizeButton = new QToolButton(this); + _minimizeButton->setObjectName("MinimizeButton"); + _minimizeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/minimize.png"))); + _maximizeButton = new QToolButton(this); + _maximizeButton->setObjectName("MaximizeButton"); + _maximizeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/maximize.png"))); + + hbox->addWidget(_minimizeButton); + hbox->addWidget(_maximizeButton); + + connect(this, SIGNAL( normalShow() ), parent, SLOT(showNormal() ) ); + connect(this, SIGNAL( maximizedShow() ), parent, SLOT(showMaximized() ) ); + connect(_minimizeButton, SIGNAL( clicked() ), this, SLOT(showSmall() ) ); + connect(_maximizeButton, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) ); + } + + if (_isTop || _hasClose) { + _closeButton= new QToolButton(this); + _closeButton->setObjectName("CloseButton"); + _closeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/close.png"))); + hbox->addWidget(_closeButton); + connect(_closeButton, SIGNAL( clicked() ), parent, SLOT(close() ) ); + } + + hbox->insertStretch(0, 500); + hbox->insertStretch(2, 500); + hbox->setMargin(0); + hbox->setSpacing(0); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); +} + +void TitleBar::paintEvent(QPaintEvent *) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing, true); + p.setPen(QColor(48, 47, 47, 255)); + p.setBrush(QColor(48, 47, 47, 255)); + p.drawRect(rect()); + + const int xgap = 2.5; + const int xstart = 10; + p.setPen(QPen(QColor(213, 15, 37, 255), 2, Qt::SolidLine)); + p.drawLine(xstart + xgap*0, height()*0.50, xstart + xgap*0, height()*0.66); + p.drawLine(xstart + xgap*18, height()*0.34, xstart + xgap*18, height()*0.50); + + p.setPen(QPen(QColor(238, 178, 17, 255), 2, Qt::SolidLine)); + p.drawLine(xstart + xgap*2, height()*0.50, xstart + xgap*2, height()*0.83); + p.drawLine(xstart + xgap*16, height()*0.17, xstart + xgap*16, height()*0.50); + + p.setPen(QPen(QColor(17, 133, 209, 255), 2, Qt::SolidLine)); + p.drawLine(xstart + xgap*4, height()*0.50, xstart + xgap*4, height()*1.00); + p.drawLine(xstart + xgap*14, height()*0.00, xstart + xgap*14, height()*0.50); + + p.setPen(QPen(QColor(0, 153, 37, 200), 2, Qt::SolidLine)); + p.drawLine(xstart + xgap*6, height()*0.50, xstart + xgap*6, height()*0.83); + p.drawLine(xstart + xgap*12, height()*0.17, xstart + xgap*12, height()*0.50); + + p.setPen(QPen(QColor(109, 50, 156, 255), 2, Qt::SolidLine)); + p.drawLine(xstart + xgap*8, height()*0.50, xstart + xgap*8, height()*0.66); + p.drawLine(xstart + xgap*10, height()*0.34, xstart + xgap*10, height()*0.50); +} + +void TitleBar::setTitle(QString title) +{ + _title->setText(title); +} + +QPoint TitleBar::get_startPos() const +{ + return _startPos; +} + +QString TitleBar::title() const +{ + return _title->text(); +} + +void TitleBar::showMaxRestore() +{ + if (parentWidget()->isMaximized()) { + _maximizeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/maximize.png"))); + normalShow(); + } else { + _maximizeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/restore.png"))); + maximizedShow(); + } +} + +void TitleBar::setRestoreButton(bool max) +{ + if (!max) { + _maximizeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/maximize.png"))); + } else { + _maximizeButton->setIcon(QIcon::fromTheme("titlebar", + QIcon(":/icons/restore.png"))); + } +} + +void TitleBar::mousePressEvent(QMouseEvent* event) +{ + if(event->button() == Qt::LeftButton && !parentWidget()->isMaximized()) { + _moving = true; + _startPos = mapToParent(event->pos()); + } +} + +void TitleBar::mouseMoveEvent(QMouseEvent *event) +{ + if(_moving && event->buttons().testFlag(Qt::LeftButton)) { + parentWidget()->move(event->globalPos() - _startPos); + } +} + +void TitleBar::mouseReleaseEvent(QMouseEvent* event) +{ + if(event->button() == Qt::LeftButton) { + _moving = false; + } +} + +void TitleBar::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (_isTop) + showMaxRestore(); + QWidget::mouseDoubleClickEvent(event); +} + +} // namespace toolbars +} // namespace pv diff --git a/DSView/pv/toolbars/titlebar.h b/DSView/pv/toolbars/titlebar.h new file mode 100644 index 00000000..d0c785d7 --- /dev/null +++ b/DSView/pv/toolbars/titlebar.h @@ -0,0 +1,72 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_TOOLBARS_TITLEBAR_H +#define DSVIEW_PV_TOOLBARS_TITLEBAR_H + +#include +class QLabel; +class QToolButton; + +namespace pv { +namespace toolbars { + +class TitleBar : public QWidget +{ + Q_OBJECT + +public: + TitleBar(bool top, QWidget *parent, bool hasClose = false); + void setTitle(QString title); + QPoint get_startPos() const; + QString title() const; + +signals: + void normalShow(); + void maximizedShow(); + +public slots: + void showSmall() { parentWidget()->showMinimized(); } + void showMaxRestore(); + void setRestoreButton(bool max); + +protected: + void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + QLabel *_title; + QToolButton *_minimizeButton; + QToolButton *_maximizeButton; + QToolButton *_closeButton; + + bool _moving; + bool _isTop; + bool _hasClose; + QPoint _startPos; +}; + +} // namespace toolbars +} // namespace pv + +#endif // DSVIEW_PV_TOOLBARS_TITLEBAR_H diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index 2cce5a7e..1887de34 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -52,6 +52,7 @@ extern "C" { #include "../widgets/decodermenu.h" #include "../device/devinst.h" #include "../view/cursor.h" +#include "../toolbars/titlebar.h" using namespace boost; using namespace std; @@ -380,7 +381,8 @@ void DecodeTrace::paint_fore(QPainter &p, int left, int right) bool DecodeTrace::create_popup() { int ret = false; - _popup = new QDialog(); + _popup = new dialogs::DSDialog(); + create_popup_form(); if (QDialog::Accepted == _popup->exec()) @@ -397,8 +399,7 @@ bool DecodeTrace::create_popup() } } - if (_popup_form) - QWidget().setLayout(_popup_form); + delete _popup_form; delete _popup; _popup = NULL; _popup_form = NULL; @@ -414,14 +415,13 @@ void DecodeTrace::create_popup_form() // which then goes out of scope destroying the layout and all the child // widgets. if (_popup_form) - QWidget().setLayout(_popup_form); + _popup->reload(false); + + _popup_form = new QFormLayout(); + _popup->layout()->addLayout(_popup_form); + _popup->setTitle(tr("Decoder Options")); - _popup_form = new QFormLayout(_popup); - _popup->setLayout(_popup_form); populate_popup_form(_popup, _popup_form); - const int width = _popup_form->sizeHint().width(); - const int height = _popup_form->sizeHint().height(); - _popup->resize(width, height); } void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index ff65a1a8..9ee89d84 100644 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -29,11 +29,11 @@ #include #include -#include #include #include +#include "../dialogs/dsdialog.h" struct srd_channel; struct srd_decoder; @@ -224,7 +224,7 @@ private: std::vector _cur_row_headings; QFormLayout *_popup_form; - QDialog *_popup; + dialogs::DSDialog *_popup; }; } // namespace view diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp index b9283f2b..f28554aa 100644 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include using boost::shared_ptr; @@ -50,6 +49,8 @@ DevMode::DevMode(QWidget *parent, SigSession &session) : _layout(new QGridLayout(this)) { + _layout->setMargin(5); + _layout->setSpacing(0); setLayout(_layout); } diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp index 3b46006b..b358c202 100644 --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -46,7 +46,6 @@ #include #include #include -#include using namespace boost; using namespace std; diff --git a/DSView/pv/view/signal.cpp b/DSView/pv/view/signal.cpp index 40c66101..b61b8d70 100644 --- a/DSView/pv/view/signal.cpp +++ b/DSView/pv/view/signal.cpp @@ -67,5 +67,10 @@ void Signal::paint_axis(QPainter &p, int y, int left, int right) p.drawLine(QPointF(left, y + 0.5f), QPointF(right, y + 0.5f)); } +boost::shared_ptr Signal::get_device() const +{ + return _dev_inst; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/signal.h b/DSView/pv/view/signal.h index 4a18ad24..82e17e92 100644 --- a/DSView/pv/view/signal.h +++ b/DSView/pv/view/signal.h @@ -89,6 +89,8 @@ public: */ //virtual void paint_label(QPainter &p, int right, bool hover, int action); + boost::shared_ptr get_device() const; + protected: /** diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index f35d7a2e..7c9cd6cc 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -579,6 +579,12 @@ void View::signals_changed() uint8_t max_height = MaxHeightUnit; vector< boost::shared_ptr > time_traces; vector< boost::shared_ptr > fft_traces; + + if (_session.get_device()->dev_inst()->mode == LOGIC) + _viewbottom->setFixedHeight(StatusHeight); + else + _viewbottom->setFixedHeight(10); + BOOST_FOREACH(const boost::shared_ptr t, get_traces(ALL_VIEW)) { if (_trace_view_map[t->get_type()] == TIME_VIEW) time_traces.push_back(t); @@ -666,7 +672,6 @@ bool View::eventFilter(QObject *object, QEvent *event) { const QEvent::Type type = event->type(); if (type == QEvent::MouseMove) { - const QMouseEvent *const mouse_event = (QMouseEvent*)event; if (object == _ruler || object == _time_viewport || object == _fft_viewport) { //_hover_point = QPoint(mouse_event->x(), 0); @@ -683,7 +688,6 @@ bool View::eventFilter(QObject *object, QEvent *event) _hover_point = QPoint(-1, -1); hover_point_changed(); - } else if (type == QEvent::Leave) { _hover_point = QPoint(-1, -1); hover_point_changed(); diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index af6f9337..cfc5466b 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -84,7 +84,7 @@ public: static constexpr double MaxViewRate = 1.0; static const int MaxPixelsPerSample = 100; - static const int StatusHeight = 25; + static const int StatusHeight = 20; public: explicit View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent = 0); @@ -193,7 +193,6 @@ public: void viewport_update(); - signals: void hover_point_changed(); @@ -233,6 +232,7 @@ public slots: void show_region(uint64_t start, uint64_t end); // -- calibration void update_calibration(); + void hide_calibration(); void status_clear(); private slots: @@ -256,7 +256,6 @@ private slots: // calibration for oscilloscope void show_calibration(); - void hide_calibration(); void on_measure_updated(); void splitterMoved(int pos, int index); diff --git a/DSView/pv/widgets/border.cpp b/DSView/pv/widgets/border.cpp new file mode 100644 index 00000000..e11d6d6f --- /dev/null +++ b/DSView/pv/widgets/border.cpp @@ -0,0 +1,107 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "border.h" +#include "../mainframe.h" + +#include +#include +#include + +namespace pv { +namespace widgets { + +Border::Border(int type, QWidget *parent) : + _type(type), + QWidget(parent) +{ + setAttribute(Qt::WA_TranslucentBackground); + setMouseTracking(true); +} + +void Border::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setPen(Qt::NoPen); + painter.setRenderHint(QPainter::Antialiasing, true); + QLinearGradient linearGrad(QPointF(width(), height()), QPointF(0, 0)); + linearGrad.setColorAt(0, QColor(48, 47, 47, 255)); + linearGrad.setColorAt(0.25, QColor(48, 47, 47, 255)); + linearGrad.setColorAt(0.5, QColor(48, 47, 47, 255)); + linearGrad.setColorAt(0.75, QColor(48, 47, 47, 100)); + linearGrad.setColorAt(1, QColor(48, 47, 47, 10)); + + QRadialGradient radialGrad(QPointF(0, 0), width()); + radialGrad.setColorAt(0, QColor(48, 47, 47, 255)); + radialGrad.setColorAt(0.25, QColor(48, 47, 47, 255)); + radialGrad.setColorAt(0.5, QColor(48, 47, 47, 255)); + radialGrad.setColorAt(0.75, QColor(48, 47, 47, 100)); + radialGrad.setColorAt(1, QColor(48, 47, 47, 10)); + + if (_type == pv::MainFrame::TopLeft) { + QRectF rectangle(0, 0, width()*2, height()*2); + radialGrad.setCenter(QPointF(width(), height())); + radialGrad.setFocalPoint(QPointF(width(), height())); + painter.setBrush(QBrush(radialGrad)); + painter.drawPie(rectangle, 90 * 16, 180 * 16); + } else if (_type == pv::MainFrame::TopRight) { + QRectF rectangle(-width(), 0, width()*2, height()*2); + radialGrad.setCenter(QPointF(0, height())); + radialGrad.setFocalPoint(QPointF(0, height())); + painter.setBrush(QBrush(radialGrad)); + painter.drawPie(rectangle, 0 * 16, 90 * 16); + } else if (_type == pv::MainFrame::BottomLeft) { + QRectF rectangle(0, -height(), width()*2, height()*2); + radialGrad.setCenter(QPointF(width(), 0)); + radialGrad.setFocalPoint(QPointF(width(), 0)); + painter.setBrush(QBrush(radialGrad)); + painter.drawPie(rectangle, 180 * 16, 270 * 16); + } else if (_type == pv::MainFrame::BottomRight) { + QRectF rectangle(-width(), -height(), width()*2, height()*2); + radialGrad.setCenter(QPointF(0, 0)); + radialGrad.setFocalPoint(QPointF(0, 0)); + painter.setBrush(QBrush(radialGrad)); + painter.drawPie(rectangle, 270 * 16, 360 * 16); + } else if (_type == pv::MainFrame::Top) { + linearGrad.setStart(QPointF(0, height())); + linearGrad.setFinalStop(QPointF(0, 0)); + painter.setBrush(QBrush(linearGrad)); + painter.drawRect(rect()); + } else if (_type == pv::MainFrame::Bottom) { + linearGrad.setStart(QPointF(0, 0)); + linearGrad.setFinalStop(QPointF(0, height())); + painter.setBrush(QBrush(linearGrad)); + painter.drawRect(rect()); + } else if (_type == pv::MainFrame::Left) { + linearGrad.setStart(QPointF(width(), 0)); + linearGrad.setFinalStop(QPointF(0, 0)); + painter.setBrush(QBrush(linearGrad)); + painter.drawRect(rect()); + } else if (_type == pv::MainFrame::Right) { + linearGrad.setStart(QPointF(0, 0)); + linearGrad.setFinalStop(QPointF(width(), 0)); + painter.setBrush(QBrush(linearGrad)); + painter.drawRect(rect()); + } +} + +} // namespace widgets +} // namespace pv diff --git a/DSView/pv/widgets/border.h b/DSView/pv/widgets/border.h new file mode 100644 index 00000000..970ac42f --- /dev/null +++ b/DSView/pv/widgets/border.h @@ -0,0 +1,46 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_WIDGETS_BORDER_H +#define DSVIEW_PV_WIDGETS_BORDER_H + +#include + +namespace pv { +namespace widgets { + +class Border : public QWidget +{ + Q_OBJECT +public: + explicit Border(int type, QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *); + +private: + int _type; +}; + +} // namespace widgets +} // namespace pv + +#endif // DSVIEW_PV_WIDGETS_BORDER_H diff --git a/DSView/pv/widgets/decodergroupbox.cpp b/DSView/pv/widgets/decodergroupbox.cpp index ab028284..b7bf92e2 100644 --- a/DSView/pv/widgets/decodergroupbox.cpp +++ b/DSView/pv/widgets/decodergroupbox.cpp @@ -52,7 +52,7 @@ DecoderGroupBox::DecoderGroupBox(boost::shared_ptr &decoder_ setLayout(_layout); _layout->addWidget(new QLabel(QString("

%1

").arg(_dec->decoder()->name), this), - 0, 0); + 0, 0); _layout->setColumnStretch(0, 1); const srd_decoder *const d = _dec->decoder();