mirror of
https://github.com/DreamSourceLab/DSView.git
synced 2025-01-23 13:42:55 +08:00
Used the native window on windows
This commit is contained in:
parent
decde39462
commit
a7754ab2a3
@ -237,9 +237,9 @@ bool bHighScale = true;
|
||||
{
|
||||
pv::MainFrame w;
|
||||
control->Start();
|
||||
w.show();
|
||||
w.readSettings();
|
||||
w.show_doc(); //to show the dailog for open help document
|
||||
w.ShowFormInit();
|
||||
w.ShowHelpDocAsync(); //to show the dailog for open help document
|
||||
|
||||
ret = a.exec(); //Run the application
|
||||
control->Stop();
|
||||
|
||||
|
@ -159,7 +159,7 @@ void DSDialog::build_base(bool hasClose)
|
||||
_main_widget->setAutoFillBackground(true);
|
||||
this->setGraphicsEffect(_shadow);
|
||||
|
||||
_titlebar = new toolbars::TitleBar(false, this, hasClose);
|
||||
_titlebar = new toolbars::TitleBar(false, this, NULL,hasClose);
|
||||
_main_layout->addWidget(_titlebar);
|
||||
|
||||
_titleSpaceLine = new QWidget(this);
|
||||
|
@ -58,7 +58,7 @@ DSMessageBox::DSMessageBox(QWidget *parent,const QString title) :
|
||||
|
||||
_shadow = new Shadow(this);
|
||||
_msg = new QMessageBox(this);
|
||||
_titlebar = new toolbars::TitleBar(false, this);
|
||||
_titlebar = new toolbars::TitleBar(false, this, NULL, false);
|
||||
_layout = new QVBoxLayout(this);
|
||||
|
||||
_shadow->setBlurRadius(10.0);
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QFont>
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QDesktopWidget>
|
||||
#endif
|
||||
@ -56,9 +55,12 @@
|
||||
#include "appcontrol.h"
|
||||
#include "ui/langresource.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "winnativewidget.h"
|
||||
#endif
|
||||
|
||||
namespace pv {
|
||||
|
||||
MainFrame::MainFrame()
|
||||
@ -71,51 +73,33 @@ MainFrame::MainFrame()
|
||||
_mainWindow = NULL;
|
||||
_is_native_title = false;
|
||||
_is_resize_ready = false;
|
||||
_move_event_count = false;
|
||||
_is_resize_reset_timer = false;
|
||||
_resize_event_count = 0;
|
||||
_parentNativeWidget = NULL;
|
||||
_mainWindow = NULL;
|
||||
_is_max_status = false;
|
||||
|
||||
AppControl::Instance()->SetTopWindow(this);
|
||||
|
||||
bool is_win32 = false;
|
||||
|
||||
// Make this a borderless window which can't
|
||||
// be resized or moved via the window system
|
||||
#ifdef _WIN32
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
|
||||
_is_native_title = true;
|
||||
is_win32 = true;
|
||||
_taskBtn = NULL;
|
||||
#else
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
_is_native_title = false;
|
||||
#endif
|
||||
|
||||
//_is_native_title = true;
|
||||
|
||||
setMinimumWidth(MainWindow::Min_Width);
|
||||
setMinimumHeight(MainWindow::Min_Height);
|
||||
// setMinimumWidth(MainWindow::Min_Width);
|
||||
// setMinimumHeight(MainWindow::Min_Height);
|
||||
|
||||
// Set the window icon
|
||||
QIcon icon;
|
||||
|
||||
if (_is_native_title && is_win32){
|
||||
icon.addFile(QString::fromUtf8(":/icons/win_title_logo.svg"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
}
|
||||
else{
|
||||
icon.addFile(QString::fromUtf8(":/icons/logo.svg"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
}
|
||||
|
||||
setWindowIcon(icon);
|
||||
|
||||
// Title
|
||||
_titleBar = new toolbars::TitleBar(true, this);
|
||||
|
||||
if (_is_native_title){
|
||||
_titleBar->setVisible(false);
|
||||
_titleBar->set_native();
|
||||
}
|
||||
else{
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
|
||||
// MainWindow
|
||||
_titleBar = new toolbars::TitleBar(true, this, this, false);
|
||||
_mainWindow = new MainWindow(_titleBar, this);
|
||||
_mainWindow->setWindowFlags(Qt::Widget);
|
||||
|
||||
@ -129,10 +113,7 @@ MainFrame::MainFrame()
|
||||
_layout->setSpacing(0);
|
||||
_layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
if (_is_native_title){
|
||||
_layout->addLayout(vbox, 0, 0);
|
||||
}
|
||||
else
|
||||
if (true)
|
||||
{
|
||||
_top_left = new widgets::Border (TopLeft, this);
|
||||
_top_left->setFixedSize(Margin, Margin);
|
||||
@ -179,11 +160,184 @@ MainFrame::MainFrame()
|
||||
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(unfreezing()));
|
||||
|
||||
QTimer::singleShot(500, this, [this](){
|
||||
QTimer::singleShot(2000, this, [this](){
|
||||
_is_resize_ready = true;
|
||||
});
|
||||
|
||||
installEventFilter(this);
|
||||
|
||||
//PrintRegionProc();
|
||||
}
|
||||
|
||||
void MainFrame::PrintRegionProc()
|
||||
{
|
||||
PrintRegion();
|
||||
|
||||
QTimer::singleShot(4000, this, [this](){
|
||||
PrintRegionProc();
|
||||
});
|
||||
}
|
||||
|
||||
void MainFrame::PrintRegion()
|
||||
{
|
||||
QRect rc = geometry();
|
||||
|
||||
int x = rc.left();
|
||||
int y = rc.top();
|
||||
int w = rc.width();
|
||||
int h = rc.height();
|
||||
|
||||
dsv_info("print region, x:%d, y:%d, w:%d, h:%d",
|
||||
x, y, w, h);
|
||||
}
|
||||
|
||||
void MainFrame::AttachNativeWindow()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
|
||||
QRect rc = geometry();
|
||||
|
||||
int x = rc.left() * k;
|
||||
int y = rc.top() * k;
|
||||
int w = rc.width() * k;
|
||||
int h = rc.height() * k;
|
||||
|
||||
if (_parentNativeWidget != NULL){
|
||||
_parentNativeWidget->SetChildWidget(NULL);
|
||||
delete _parentNativeWidget;
|
||||
}
|
||||
|
||||
_parentNativeWidget = new WinNativeWidget(x, y, w, h);
|
||||
_parentNativeWidget->setGeometry(x, y, w, h);
|
||||
_parentNativeWidget->SetChildWidget(this);
|
||||
|
||||
if (_parentNativeWidget->Handle())
|
||||
{
|
||||
_parentNativeWidget->Show(true);
|
||||
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
setProperty("_q_embedded_native_parent_handle", (WId)_parentNativeWidget->Handle());
|
||||
SetWindowLong((HWND)winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
|
||||
|
||||
SetParent((HWND)winId(), _parentNativeWidget->Handle());
|
||||
QEvent e(QEvent::EmbeddingControl);
|
||||
QApplication::sendEvent(this, &e);
|
||||
|
||||
QTimer::singleShot(10, this, [this](){
|
||||
move(0,0);
|
||||
setVisible(true);
|
||||
|
||||
if (_initWndInfo.isMaxSize){
|
||||
showMaximized();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::MoveWindow(int x, int y)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
int k = window()->devicePixelRatio();
|
||||
_parentNativeWidget->Move(x * k, y * k);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
move(x, y);
|
||||
}
|
||||
|
||||
QPoint MainFrame::GetParentPos()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
RECT rc;
|
||||
int k = window()->devicePixelRatio();
|
||||
GetWindowRect(_parentNativeWidget->Handle(), &rc);
|
||||
return QPoint(rc.left / k, rc.top / k);
|
||||
}
|
||||
#endif
|
||||
|
||||
return pos();
|
||||
}
|
||||
|
||||
bool MainFrame::ParentIsMaxsized()
|
||||
{
|
||||
return _is_max_status;
|
||||
}
|
||||
|
||||
void MainFrame::MoveBegin()
|
||||
{
|
||||
// dsv_info("Move begin.");
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL)
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
|
||||
HMONITOR hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
|
||||
MONITORINFOEX inf;
|
||||
inf.cbSize = sizeof(inf);
|
||||
|
||||
if (GetMonitorInfo(hMonitor, &inf)) {
|
||||
int x = inf.rcMonitor.left;
|
||||
int y = inf.rcMonitor.top;
|
||||
int w = inf.rcMonitor.right - inf.rcMonitor.left;
|
||||
int h = inf.rcMonitor.bottom - inf.rcMonitor.top;
|
||||
|
||||
_move_screen_region = QRect(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::MoveEnd()
|
||||
{
|
||||
// dsv_info("Move end.");
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
|
||||
HMONITOR hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
|
||||
MONITORINFOEX inf;
|
||||
inf.cbSize = sizeof(inf);
|
||||
|
||||
if (GetMonitorInfo(hMonitor, &inf)) {
|
||||
int x = inf.rcMonitor.left;
|
||||
int y = inf.rcMonitor.top;
|
||||
int w = inf.rcMonitor.right - inf.rcMonitor.left;
|
||||
int h = inf.rcMonitor.bottom - inf.rcMonitor.top;
|
||||
|
||||
// End at the same screen.
|
||||
if (x == _move_screen_region.left() && w == _move_screen_region.width()){
|
||||
dsv_info("Move to the same screen.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dsv_info("Move to another screen.");
|
||||
|
||||
QRect rc = GetFormRegion();
|
||||
|
||||
SetParent((HWND)winId(), NULL);
|
||||
QEvent e(QEvent::EmbeddingControl);
|
||||
QApplication::sendEvent(this, &e);
|
||||
_parentNativeWidget->SetChildWidget(NULL);
|
||||
|
||||
setGeometry(rc.left(), rc.top(), rc.width(), rc.height());
|
||||
|
||||
this->AttachNativeWindow();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::resizeEvent(QResizeEvent *event)
|
||||
@ -194,28 +348,14 @@ void MainFrame::resizeEvent(QResizeEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMaximized()) {
|
||||
if (_is_max_status) {
|
||||
hide_border();
|
||||
}
|
||||
else {
|
||||
show_border();
|
||||
|
||||
_resize_event_count++;
|
||||
|
||||
if (_resize_event_count >= 2){
|
||||
saveNormalRegion();
|
||||
}
|
||||
else if (!_is_resize_reset_timer){
|
||||
_is_resize_reset_timer = true;
|
||||
|
||||
QTimer::singleShot(500, this, [this](){
|
||||
_is_resize_reset_timer = false;
|
||||
_resize_event_count = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_titleBar->setRestoreButton(isMaximized());
|
||||
_titleBar->setRestoreButton(_is_max_status);
|
||||
_layout->update();
|
||||
}
|
||||
|
||||
@ -224,6 +364,14 @@ void MainFrame::closeEvent(QCloseEvent *event)
|
||||
writeSettings();
|
||||
|
||||
if (_mainWindow->able_to_close()){
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
_parentNativeWidget->SetChildWidget(NULL);
|
||||
_parentNativeWidget->Show(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
event->accept();
|
||||
}
|
||||
else{
|
||||
@ -238,10 +386,6 @@ void MainFrame::unfreezing()
|
||||
|
||||
void MainFrame::hide_border()
|
||||
{
|
||||
if (_is_native_title){
|
||||
return;
|
||||
}
|
||||
|
||||
_top_left->setVisible(false);
|
||||
_top_right->setVisible(false);
|
||||
_top->setVisible(false);
|
||||
@ -254,10 +398,6 @@ void MainFrame::hide_border()
|
||||
|
||||
void MainFrame::show_border()
|
||||
{
|
||||
if (_is_native_title){
|
||||
return;
|
||||
}
|
||||
|
||||
_top_left->setVisible(true);
|
||||
_top_right->setVisible(true);
|
||||
_top->setVisible(true);
|
||||
@ -271,77 +411,99 @@ void MainFrame::show_border()
|
||||
void MainFrame::showNormal()
|
||||
{
|
||||
show_border();
|
||||
|
||||
dsv_info("Show as normal.");
|
||||
|
||||
_is_max_status = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget){
|
||||
_parentNativeWidget->ShowNormal();
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
QFrame::showNormal();
|
||||
}
|
||||
|
||||
void MainFrame::showMaximized()
|
||||
{
|
||||
hide_border();
|
||||
|
||||
dsv_info("Show as maxsize.");
|
||||
|
||||
_is_max_status = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget){
|
||||
_parentNativeWidget->ShowMax();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
QFrame::showMaximized();
|
||||
}
|
||||
|
||||
void MainFrame::showMinimized()
|
||||
{
|
||||
dsv_info("Show as minsize.");
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget){
|
||||
_parentNativeWidget->ShowMin();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
QFrame::showMinimized();
|
||||
}
|
||||
|
||||
void MainFrame::changeEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::WindowStateChange && _is_resize_ready) {
|
||||
//dsv_info("Window state changed.");
|
||||
QWindowStateChangeEvent *stateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
|
||||
if (stateChangeEvent->oldState() & Qt::WindowMaximized
|
||||
&& !(windowState() & Qt::WindowMaximized)) {
|
||||
moveToNormal();
|
||||
|
||||
}
|
||||
}
|
||||
QFrame::changeEvent(event);
|
||||
}
|
||||
|
||||
void MainFrame::moveToNormal()
|
||||
void MainFrame::moveToWinNaitiveNormal()
|
||||
{
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
int left = app.frameOptions.left;
|
||||
int top = app.frameOptions.top;
|
||||
int right = app.frameOptions.right;
|
||||
int bottom = app.frameOptions.bottom;
|
||||
int x = app.frameOptions.x;
|
||||
int y = app.frameOptions.y;
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
|
||||
if (_is_native_title && y != NO_POINT_VALUE){
|
||||
move(x, y);
|
||||
}
|
||||
else{
|
||||
move(left, top);
|
||||
}
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
|
||||
if (right - left > 0){
|
||||
resize(right - left, bottom - top);
|
||||
int x = _normalRegion.x * k;
|
||||
int y = _normalRegion.y * k;
|
||||
int w = _normalRegion.w * k;
|
||||
int h = _normalRegion.h * k;
|
||||
|
||||
_parentNativeWidget->setGeometry(x, y, w, h);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Move && _is_resize_ready){
|
||||
if (isMaximized() == false){
|
||||
_move_event_count++;
|
||||
if (_move_event_count >= 2){
|
||||
if (_is_max_status == false && _titleBar->IsMoving()){
|
||||
saveNormalRegion();
|
||||
}
|
||||
}
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
_move_event_count = 0;
|
||||
|
||||
if (_is_native_title){
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
|
||||
const QEvent::Type type = event->type();
|
||||
const QMouseEvent *const mouse_event = (QMouseEvent*)event;
|
||||
int newWidth;
|
||||
int newHeight;
|
||||
int newLeft;
|
||||
int newTop;
|
||||
int newWidth = 0;
|
||||
int newHeight = 0;
|
||||
int newLeft = 0;
|
||||
int newTop = 0;
|
||||
|
||||
if (type != QEvent::MouseMove
|
||||
&& type != QEvent::MouseButtonPress
|
||||
@ -351,7 +513,7 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
}
|
||||
|
||||
//when window is maximized, or is moving, call return
|
||||
if (isMaximized() || _titleBar->IsMoving()){
|
||||
if (_is_max_status || _titleBar->IsMoving()){
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
|
||||
@ -390,86 +552,104 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
|
||||
if (type == QEvent::MouseMove) {
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
int x0 = (int)mouse_event->globalPosition().x();
|
||||
int y0 = (int)mouse_event->globalPosition().y();
|
||||
QPoint pt;
|
||||
|
||||
#ifdef _WIN32
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
pt.setX(p.x);
|
||||
pt.setY(p.y);
|
||||
#else
|
||||
int x0 = mouse_event->globalX();
|
||||
int y0 = mouse_event->globalY();
|
||||
pt = mouse_event->globalPos();
|
||||
#endif
|
||||
int datX = pt.x() - _clickPos.x();
|
||||
int datY = pt.y() - _clickPos.y();
|
||||
int l = _dragStartRegion.left();
|
||||
int t = _dragStartRegion.top();
|
||||
int r = _dragStartRegion.right();
|
||||
int b = _dragStartRegion.bottom();
|
||||
|
||||
if(mouse_event->buttons().testFlag(Qt::LeftButton)) {
|
||||
if (!_freezing) {
|
||||
|
||||
// Do nothing this time.
|
||||
if (_freezing){
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
|
||||
int minW = MainWindow::Min_Width;
|
||||
int minH = MainWindow::Min_Height;
|
||||
|
||||
switch (_hit_border) {
|
||||
case TopLeft:
|
||||
newWidth = std::max(_dragStartGeometry.right() - x0, minimumWidth());
|
||||
newHeight = std::max(_dragStartGeometry.bottom() - y0, minimumHeight());
|
||||
newLeft = geometry().left();
|
||||
newTop = geometry().top();
|
||||
if (newWidth > minimumWidth())
|
||||
newLeft = x0;
|
||||
if (newHeight > minimumHeight())
|
||||
newTop = y0;
|
||||
setGeometry(newLeft, newTop, newWidth, newHeight);
|
||||
l += datX;
|
||||
t += datY;
|
||||
if (r - l < minW)
|
||||
l = r - minW;
|
||||
if (b - t < minH)
|
||||
t = b - minH;
|
||||
break;
|
||||
|
||||
case BottomLeft:
|
||||
newWidth = std::max(_dragStartGeometry.right() - x0, minimumWidth());
|
||||
newHeight = std::max(y0 - _dragStartGeometry.top(), minimumHeight());
|
||||
newLeft = geometry().left();
|
||||
if (newWidth > minimumWidth())
|
||||
newLeft = x0;
|
||||
setGeometry(newLeft, _dragStartGeometry.top(), newWidth, newHeight);
|
||||
l += datX;
|
||||
b += datY;
|
||||
if (r - l < minW)
|
||||
l = r - minW;
|
||||
if (b - t < minH)
|
||||
b = t + minH;
|
||||
break;
|
||||
|
||||
case TopRight:
|
||||
newWidth = std::max(x0 - _dragStartGeometry.left(), minimumWidth());
|
||||
newHeight = std::max(_dragStartGeometry.bottom() - y0, minimumHeight());
|
||||
newTop = geometry().top();
|
||||
if (newHeight > minimumHeight())
|
||||
newTop = y0;
|
||||
setGeometry(_dragStartGeometry.left(), newTop, newWidth, newHeight);
|
||||
r += datX;
|
||||
t += datY;
|
||||
if (r - l < minW)
|
||||
r = l + minW;
|
||||
if (b - t < minH)
|
||||
t = b - minH;
|
||||
break;
|
||||
|
||||
case BottomRight:
|
||||
newWidth = std::max(x0 - _dragStartGeometry.left(), minimumWidth());
|
||||
newHeight = std::max(y0 - _dragStartGeometry.top(), minimumHeight());
|
||||
setGeometry(_dragStartGeometry.left(), _dragStartGeometry.top(), newWidth, newHeight);
|
||||
r += datX;
|
||||
b += datY;
|
||||
if (r - l < minW)
|
||||
r = l + minW;
|
||||
if (b - t < minH)
|
||||
b = t + minH;
|
||||
break;
|
||||
|
||||
case Left:
|
||||
newWidth = _dragStartGeometry.right() - x0;
|
||||
if (newWidth > minimumWidth()){
|
||||
setGeometry(x0, _dragStartGeometry.top(), newWidth, height());
|
||||
}
|
||||
l += datX;
|
||||
if (r - l < minW)
|
||||
l = r - minW;
|
||||
break;
|
||||
|
||||
case Right:
|
||||
newWidth = x0 - _dragStartGeometry.left();
|
||||
if (newWidth > minimumWidth()){
|
||||
setGeometry(_dragStartGeometry.left(), _dragStartGeometry.top(), newWidth, height());
|
||||
}
|
||||
r += datX;
|
||||
if (r - l < minW)
|
||||
r = l + minW;
|
||||
break;
|
||||
|
||||
case Top:
|
||||
newHeight = _dragStartGeometry.bottom() - y0;
|
||||
if (newHeight > minimumHeight()){
|
||||
setGeometry(_dragStartGeometry.left(), y0,width(), newHeight);
|
||||
}
|
||||
t += datY;
|
||||
if (b - t < minH)
|
||||
t = b - minH;
|
||||
break;
|
||||
|
||||
case Bottom:
|
||||
newHeight = y0 - _dragStartGeometry.top();
|
||||
if (newHeight > minimumHeight()){
|
||||
setGeometry(_dragStartGeometry.left(), _dragStartGeometry.top(), width(), newHeight);
|
||||
}
|
||||
b += datY;
|
||||
if (b - t < minH)
|
||||
b = t + minH;
|
||||
break;
|
||||
|
||||
default:
|
||||
r = l;
|
||||
break;
|
||||
}
|
||||
_freezing = true;
|
||||
|
||||
if (r != l){
|
||||
SetFormRegion(l, t, r-l, b-t);
|
||||
saveNormalRegion();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -478,14 +658,25 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
if (_hit_border != None)
|
||||
_bDraging = true;
|
||||
_timer.start(50);
|
||||
_dragStartGeometry = geometry();
|
||||
|
||||
#ifdef _WIN32
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
_clickPos.setX(p.x);
|
||||
_clickPos.setY(p.y);
|
||||
#else
|
||||
_clickPos = mouse_event->globalPos();
|
||||
#endif
|
||||
|
||||
_dragStartRegion = GetFormRegion();
|
||||
}
|
||||
else if (type == QEvent::MouseButtonRelease) {
|
||||
if (mouse_event->button() == Qt::LeftButton) {
|
||||
_bDraging = false;
|
||||
_timer.stop();
|
||||
}
|
||||
} else if (!_bDraging && type == QEvent::Leave) {
|
||||
}
|
||||
else if (!_bDraging && type == QEvent::Leave) {
|
||||
_hit_border = None;
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
@ -499,38 +690,153 @@ void MainFrame::saveNormalRegion()
|
||||
if (!_is_resize_ready){
|
||||
return;
|
||||
}
|
||||
if (isMaximized()){
|
||||
if (_is_max_status){
|
||||
return;
|
||||
}
|
||||
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
RECT rc;
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
|
||||
GetWindowRect(_parentNativeWidget->Handle(), &rc);
|
||||
app.frameOptions.left = rc.left / k;
|
||||
app.frameOptions.top = rc.top / k;
|
||||
app.frameOptions.right = rc.right / k;
|
||||
app.frameOptions.bottom = rc.bottom / k;
|
||||
app.frameOptions.x = rc.left / k;
|
||||
app.frameOptions.y = rc.top / k;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_parentNativeWidget == NULL){
|
||||
QRect rc = geometry();
|
||||
app.frameOptions.left = rc.left();
|
||||
app.frameOptions.top = rc.top();
|
||||
app.frameOptions.right = rc.right();
|
||||
app.frameOptions.bottom = rc.bottom();
|
||||
|
||||
QRect frc = frameGeometry();
|
||||
app.frameOptions.x = frc.x();
|
||||
app.frameOptions.y = frc.y();
|
||||
app.frameOptions.x = rc.left();
|
||||
app.frameOptions.y = rc.top();
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::writeSettings()
|
||||
{
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
app.frameOptions.isMax = isMaximized();
|
||||
app.frameOptions.isMax = _is_max_status;
|
||||
|
||||
if (isMaximized() == false && isVisible()){
|
||||
if (_is_max_status == false && isVisible()){
|
||||
saveNormalRegion();
|
||||
}
|
||||
app.SaveFrame();
|
||||
|
||||
int x = app.frameOptions.x;
|
||||
int y = app.frameOptions.y;
|
||||
int w = app.frameOptions.right - app.frameOptions.left;
|
||||
int h = app.frameOptions.bottom - app.frameOptions.top;
|
||||
|
||||
dsv_info("Save form, x:%d, y:%d, w:%d, h:%d", x, y, w, h);
|
||||
}
|
||||
|
||||
void MainFrame::readSettings()
|
||||
void MainFrame::ShowFormInit()
|
||||
{
|
||||
if (_layout == NULL)
|
||||
return;
|
||||
ReadSettings();
|
||||
|
||||
int x = _initWndInfo.r.x;
|
||||
int y = _initWndInfo.r.y;
|
||||
int w = _initWndInfo.r.w;
|
||||
int h = _initWndInfo.r.h;
|
||||
|
||||
if (w % 2 == 0){
|
||||
w++;
|
||||
}
|
||||
if (h % 2 == 0){
|
||||
h++;
|
||||
}
|
||||
|
||||
bool isWin32 = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
isWin32 = true;
|
||||
#endif
|
||||
|
||||
if (_initWndInfo.isMaxSize)
|
||||
{
|
||||
if (isWin32 && _is_native_title){
|
||||
hide_border();
|
||||
move(_normalRegion.x, _normalRegion.y);
|
||||
resize(_normalRegion.w, _normalRegion.h);
|
||||
}
|
||||
else{
|
||||
move(x, y);
|
||||
showMaximized();
|
||||
}
|
||||
}
|
||||
else{
|
||||
move(x, y);
|
||||
resize(w, h);
|
||||
}
|
||||
|
||||
QFrame::show();
|
||||
|
||||
dsv_info("Init form, x:%d, y:%d, w:%d, h:%d", x, y, w, h);
|
||||
|
||||
if (_is_native_title){
|
||||
AttachNativeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::SetFormRegion(int x, int y, int w, int h)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
if (_parentNativeWidget != NULL){
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
|
||||
x *= k;
|
||||
y *= k;
|
||||
w *= k;
|
||||
h *= k;
|
||||
|
||||
_parentNativeWidget->setGeometry(x, y, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
setGeometry(x, y, w, h);
|
||||
}
|
||||
|
||||
QRect MainFrame::GetFormRegion()
|
||||
{
|
||||
QRect rc;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
if (_parentNativeWidget != NULL){
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
RECT r;
|
||||
GetWindowRect(_parentNativeWidget->Handle(), &r);
|
||||
int x = r.left;
|
||||
int y = r.top;
|
||||
int w = r.right-r.left;
|
||||
int h = r.bottom-r.top;
|
||||
rc = QRect(x/k, y/k, w/k, h/k);
|
||||
}
|
||||
else{
|
||||
rc = geometry();
|
||||
}
|
||||
#else
|
||||
rc = geometry();
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void MainFrame::ReadSettings()
|
||||
{
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
|
||||
if (app.frameOptions.language > 0){
|
||||
@ -543,21 +849,30 @@ void MainFrame::readSettings()
|
||||
int bottom = app.frameOptions.bottom;
|
||||
int x = app.frameOptions.x;
|
||||
int y = app.frameOptions.y;
|
||||
int ox = app.frameOptions.ox;
|
||||
int oy = app.frameOptions.oy;
|
||||
|
||||
if (x == NO_POINT_VALUE){
|
||||
x = left;
|
||||
y = top;
|
||||
}
|
||||
|
||||
dsv_info("Loaded region, x:%d, y:%d, w:%d, h:%d",
|
||||
x, y, right-left, bottom-top);
|
||||
|
||||
bool bReset = false;
|
||||
int scrIndex = -1;
|
||||
|
||||
QRect winRc = {left, top, right-left, bottom-top};
|
||||
QRect winRc = {x, y, right-left, bottom-top};
|
||||
|
||||
for (int i=0; i<QGuiApplication::screens().size(); i++){
|
||||
QRect rc = QGuiApplication::screens().at(i)->availableGeometry();
|
||||
QRect inrc = rc.intersected(winRc);
|
||||
QString name = QGuiApplication::screens().at(i)->name();
|
||||
|
||||
if (inrc.width() > 10 || inrc.height() > 10){
|
||||
dsv_info("Screen name:%s, region, left:%d, top:%d, right:%d, bottom:%d",
|
||||
name.toStdString().c_str(), rc.left(), rc.top(), rc.right(), rc.bottom() );
|
||||
|
||||
if (scrIndex == -1 && (inrc.width() > 10 || inrc.height() > 10)){
|
||||
scrIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -567,11 +882,17 @@ void MainFrame::readSettings()
|
||||
else{
|
||||
QRect rc = QGuiApplication::screens().at(scrIndex)->availableGeometry();
|
||||
QRect inrc = rc.intersected(winRc);
|
||||
if (inrc.width() < 70 || inrc.height() < 70){
|
||||
if (inrc.width() < 70 || inrc.height() < 70 || winRc.width() < 300){
|
||||
bReset = true;
|
||||
}
|
||||
}
|
||||
|
||||
_initWndInfo.r.x = 0;
|
||||
_initWndInfo.r.y = 0;
|
||||
_initWndInfo.r.w = 0;
|
||||
_initWndInfo.r.h = 0;
|
||||
_initWndInfo.isMaxSize = false;
|
||||
|
||||
if (app.frameOptions.isMax)
|
||||
{
|
||||
QRect rc;
|
||||
@ -586,10 +907,25 @@ void MainFrame::readSettings()
|
||||
scrName = QGuiApplication::screens().at(scrIndex)->name();
|
||||
}
|
||||
|
||||
move(rc.left(), rc.top());
|
||||
_initWndInfo.r.x = rc.left();
|
||||
_initWndInfo.r.y = rc.top();
|
||||
_initWndInfo.r.w = rc.width();
|
||||
_initWndInfo.r.h = rc.height();
|
||||
_initWndInfo.isMaxSize = true;
|
||||
|
||||
showMaximized(); // show max by system api
|
||||
dsv_info("show as max, screen:%s", scrName.toStdString().c_str());
|
||||
_normalRegion.x = x;
|
||||
_normalRegion.y = y;
|
||||
_normalRegion.w = right-left;
|
||||
_normalRegion.h = bottom-top;
|
||||
|
||||
QRect inrc = rc.intersected(winRc);
|
||||
if (inrc.width() < 70 || inrc.height() < 70 || winRc.width() < 300){
|
||||
_normalRegion.x = rc.left() + (rc.width() - _normalRegion.w) / 2;
|
||||
_normalRegion.y = rc.top() + (rc.height() - _normalRegion.h) / 2;
|
||||
}
|
||||
|
||||
dsv_info("Show as max, screen:%s, x:%d, y:%d, w:%d, h:%d",
|
||||
scrName.toStdString().c_str(), rc.x(), rc.y(), rc.width(), rc.height());
|
||||
}
|
||||
else if (bReset)
|
||||
{
|
||||
@ -610,30 +946,42 @@ void MainFrame::readSettings()
|
||||
const int x0 = rc.left() + (rc.width() - w) / 2;
|
||||
const int y0 = rc.top() + (rc.height() - h) / 2;
|
||||
|
||||
move(x0, y0);
|
||||
resize(w, h);
|
||||
_initWndInfo.r.x = x0;
|
||||
_initWndInfo.r.y = y0;
|
||||
_initWndInfo.r.w = w;
|
||||
_initWndInfo.r.h = h;
|
||||
_normalRegion = _initWndInfo.r;
|
||||
|
||||
dsv_info("reset, screen:%s", scrName.toStdString().c_str());
|
||||
dsv_info("Reset, screen:%s, x:%d, y:%d, w:%d, h:%d",
|
||||
scrName.toStdString().c_str(), rc.left(), rc.top(), rc.width(), rc.height());
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (y != NO_POINT_VALUE){
|
||||
move(x, y);
|
||||
_initWndInfo.r.x = x;
|
||||
_initWndInfo.r.y = y;
|
||||
}
|
||||
else{
|
||||
move(left, top);
|
||||
_initWndInfo.r.x = left;
|
||||
_initWndInfo.r.y = top;
|
||||
}
|
||||
#else
|
||||
move(left, top);
|
||||
_initWndInfo.r.x = left;
|
||||
_initWndInfo.r.y = top;
|
||||
#endif
|
||||
_initWndInfo.r.w = right - left;
|
||||
_initWndInfo.r.h = bottom - top;
|
||||
_normalRegion = _initWndInfo.r;
|
||||
QString scrName = QGuiApplication::screens().at(scrIndex)->name();
|
||||
QRect rc = QGuiApplication::screens().at(scrIndex)->availableGeometry();
|
||||
|
||||
if (right - left > 0){
|
||||
resize(right - left, bottom - top);
|
||||
dsv_info("Restore, screen:%s, x:%d, y:%d, w:%d, h:%d",
|
||||
scrName.toStdString().c_str() ,rc.left(), rc.top(), rc.width(), rc.height());
|
||||
}
|
||||
|
||||
dsv_info("restore, screen:%s", QGuiApplication::screens().at(scrIndex)->name().toStdString().c_str());
|
||||
}
|
||||
dsv_info("Normal region, x:%d, y:%d, w:%d, h:%d",
|
||||
_normalRegion.x, _normalRegion.y, _normalRegion.w, _normalRegion.h);
|
||||
|
||||
// restore dockwidgets
|
||||
_mainWindow->restore_dock();
|
||||
@ -644,7 +992,7 @@ void MainFrame::readSettings()
|
||||
void MainFrame::showEvent(QShowEvent *event)
|
||||
{
|
||||
// Taskbar Progress Effert for Win7 and Above
|
||||
if (_taskBtn->window() == NULL) {
|
||||
if (_taskBtn && _taskBtn->window() == NULL) {
|
||||
_taskBtn->setWindow(windowHandle());
|
||||
_taskPrg = _taskBtn->progress();
|
||||
}
|
||||
@ -666,6 +1014,13 @@ void MainFrame::setTaskbarProgress(int progress)
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::ShowHelpDocAsync()
|
||||
{
|
||||
QTimer::singleShot(300, this, [this](){
|
||||
show_doc();
|
||||
});
|
||||
}
|
||||
|
||||
void MainFrame::show_doc()
|
||||
{
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
|
@ -28,25 +28,45 @@
|
||||
#include <QFrame>
|
||||
#include <QGridLayout>
|
||||
#include <QTimer>
|
||||
#include <QRect>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <QWinTaskbarButton>
|
||||
#include <QWinTaskbarProgress>
|
||||
#endif
|
||||
|
||||
#include "toolbars/titlebar.h"
|
||||
|
||||
namespace pv {
|
||||
|
||||
class MainWindow;
|
||||
|
||||
namespace toolbars {
|
||||
class TitleBar;
|
||||
}
|
||||
class WinNativeWidget;
|
||||
|
||||
namespace dialogs {
|
||||
class DSMessageBox;
|
||||
class DSDialog;
|
||||
}
|
||||
|
||||
class MainFrame : public QFrame
|
||||
struct Point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct FormRegion{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
struct FormInitInfo
|
||||
{
|
||||
FormRegion r;
|
||||
bool isMaxSize;
|
||||
};
|
||||
|
||||
class MainFrame : public QFrame, public ITitleParent
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -68,7 +88,11 @@ public:
|
||||
public:
|
||||
MainFrame();
|
||||
|
||||
void readSettings();
|
||||
void ShowFormInit();
|
||||
void ShowHelpDocAsync();
|
||||
|
||||
void PrintRegionProc();
|
||||
void PrintRegion();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
@ -88,7 +112,7 @@ public slots:
|
||||
void showNormal();
|
||||
void showMaximized();
|
||||
void showMinimized();
|
||||
void moveToNormal();
|
||||
void moveToWinNaitiveNormal();
|
||||
|
||||
private:
|
||||
void hide_border();
|
||||
@ -96,6 +120,19 @@ private:
|
||||
void writeSettings();
|
||||
void saveNormalRegion();
|
||||
|
||||
void ReadSettings();
|
||||
void AttachNativeWindow();
|
||||
|
||||
//ITitleParent
|
||||
void MoveWindow(int x, int y) override;
|
||||
QPoint GetParentPos() override;
|
||||
bool ParentIsMaxsized() override;
|
||||
void MoveBegin() override;
|
||||
void MoveEnd() override;
|
||||
|
||||
void SetFormRegion(int x, int y, int w, int h);
|
||||
QRect GetFormRegion();
|
||||
|
||||
private:
|
||||
toolbars::TitleBar *_titleBar;
|
||||
MainWindow *_mainWindow;
|
||||
@ -111,7 +148,6 @@ private:
|
||||
widgets::Border *_bottom_right;
|
||||
|
||||
bool _bDraging;
|
||||
QRect _dragStartGeometry;
|
||||
int _hit_border;
|
||||
QTimer _timer;
|
||||
bool _freezing;
|
||||
@ -123,9 +159,14 @@ private:
|
||||
|
||||
bool _is_native_title;
|
||||
bool _is_resize_ready;
|
||||
int _move_event_count;
|
||||
int _resize_event_count;
|
||||
bool _is_resize_reset_timer;
|
||||
|
||||
WinNativeWidget *_parentNativeWidget;
|
||||
FormInitInfo _initWndInfo;
|
||||
FormRegion _normalRegion;
|
||||
bool _is_max_status;
|
||||
QPoint _clickPos;
|
||||
QRect _dragStartRegion;
|
||||
QRect _move_screen_region;
|
||||
};
|
||||
|
||||
} // namespace pv
|
||||
|
@ -186,6 +186,7 @@ namespace pv
|
||||
_view = new pv::view::View(_session, _sampling_bar, this);
|
||||
_vertical_layout->addWidget(_view);
|
||||
|
||||
|
||||
setIconSize(QSize(40, 40));
|
||||
addToolBar(_sampling_bar);
|
||||
addToolBar(_trig_bar);
|
||||
@ -255,6 +256,7 @@ namespace pv
|
||||
|
||||
_sampling_bar->set_view(_view);
|
||||
|
||||
|
||||
// Add the font form
|
||||
AppControl::Instance()->add_font_form(_protocol_widget);
|
||||
AppControl::Instance()->add_font_form(_dso_trigger_widget);
|
||||
@ -1426,9 +1428,6 @@ namespace pv
|
||||
qApp->setStyleSheet(qss.readAll());
|
||||
qss.close();
|
||||
|
||||
#ifdef _WIN32
|
||||
setDark_Titlebar(reinterpret_cast<HWND>(_frame->winId()), style == THEME_STYLE_DARK);
|
||||
#endif
|
||||
|
||||
data_updated();
|
||||
}
|
||||
@ -2196,28 +2195,4 @@ namespace pv
|
||||
_view->update_all_trace_postion();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void MainWindow::setDark_Titlebar(HWND hwnd, bool isDarkStyle)
|
||||
{
|
||||
HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
HMODULE hUser32 = GetModuleHandleW(L"user32.dll");
|
||||
fnAllowDarkModeForWindow AllowDarkModeForWindow
|
||||
= reinterpret_cast<fnAllowDarkModeForWindow>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133)));
|
||||
fnSetPreferredAppMode SetPreferredAppMode
|
||||
= reinterpret_cast<fnSetPreferredAppMode>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135)));
|
||||
fnSetWindowCompositionAttribute SetWindowCompositionAttribute
|
||||
= reinterpret_cast<fnSetWindowCompositionAttribute>(GetProcAddress(hUser32, "SetWindowCompositionAttribute"));
|
||||
|
||||
SetPreferredAppMode(AllowDark);
|
||||
BOOL dark = isDarkStyle;
|
||||
AllowDarkModeForWindow(hwnd, dark);
|
||||
WINDOWCOMPOSITIONATTRIBDATA data = {
|
||||
WCA_USEDARKMODECOLORS,
|
||||
&dark,
|
||||
sizeof(dark)
|
||||
};
|
||||
SetWindowCompositionAttribute(hwnd, &data);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace pv
|
||||
|
@ -34,61 +34,6 @@
|
||||
#include <chrono>
|
||||
#include "dstimer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
#pragma comment (lib, "Dwmapi.lib")
|
||||
|
||||
enum PreferredAppMode {
|
||||
Default,
|
||||
AllowDark,
|
||||
ForceDark,
|
||||
ForceLight,
|
||||
Max
|
||||
};
|
||||
|
||||
enum WINDOWCOMPOSITIONATTRIB {
|
||||
WCA_UNDEFINED = 0,
|
||||
WCA_NCRENDERING_ENABLED = 1,
|
||||
WCA_NCRENDERING_POLICY = 2,
|
||||
WCA_TRANSITIONS_FORCEDISABLED = 3,
|
||||
WCA_ALLOW_NCPAINT = 4,
|
||||
WCA_CAPTION_BUTTON_BOUNDS = 5,
|
||||
WCA_NONCLIENT_RTL_LAYOUT = 6,
|
||||
WCA_FORCE_ICONIC_REPRESENTATION = 7,
|
||||
WCA_EXTENDED_FRAME_BOUNDS = 8,
|
||||
WCA_HAS_ICONIC_BITMAP = 9,
|
||||
WCA_THEME_ATTRIBUTES = 10,
|
||||
WCA_NCRENDERING_EXILED = 11,
|
||||
WCA_NCADORNMENTINFO = 12,
|
||||
WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
|
||||
WCA_VIDEO_OVERLAY_ACTIVE = 14,
|
||||
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
|
||||
WCA_DISALLOW_PEEK = 16,
|
||||
WCA_CLOAK = 17,
|
||||
WCA_CLOAKED = 18,
|
||||
WCA_ACCENT_POLICY = 19,
|
||||
WCA_FREEZE_REPRESENTATION = 20,
|
||||
WCA_EVER_UNCLOAKED = 21,
|
||||
WCA_VISUAL_OWNER = 22,
|
||||
WCA_HOLOGRAPHIC = 23,
|
||||
WCA_EXCLUDED_FROM_DDA = 24,
|
||||
WCA_PASSIVEUPDATEMODE = 25,
|
||||
WCA_USEDARKMODECOLORS = 26,
|
||||
WCA_LAST = 27
|
||||
};
|
||||
|
||||
struct WINDOWCOMPOSITIONATTRIBDATA {
|
||||
WINDOWCOMPOSITIONATTRIB Attrib;
|
||||
PVOID pvData;
|
||||
SIZE_T cbData;
|
||||
};
|
||||
|
||||
using fnAllowDarkModeForWindow = BOOL (WINAPI *)(HWND hWnd, BOOL allow);
|
||||
using fnSetPreferredAppMode = PreferredAppMode (WINAPI *)(PreferredAppMode appMode);
|
||||
using fnSetWindowCompositionAttribute = BOOL (WINAPI *)(HWND hwnd, WINDOWCOMPOSITIONATTRIBDATA *);
|
||||
#endif
|
||||
|
||||
class QAction;
|
||||
class QMenuBar;
|
||||
class QMenu;
|
||||
@ -213,9 +158,6 @@ private:
|
||||
void check_config_file_version();
|
||||
void load_demo_decoder_config(QString optname);
|
||||
|
||||
#ifdef _WIN32
|
||||
static void setDark_Titlebar(HWND hwnd, bool isDarkStyle);
|
||||
#endif
|
||||
|
||||
private:
|
||||
//ISessionCallback
|
||||
|
@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "titlebar.h"
|
||||
|
||||
#include <QStyle>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
@ -31,6 +30,12 @@
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <assert.h>
|
||||
#include <QTimer>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "../config/appconfig.h"
|
||||
#include "../appcontrol.h"
|
||||
#include "../dsvdef.h"
|
||||
@ -39,18 +44,21 @@
|
||||
namespace pv {
|
||||
namespace toolbars {
|
||||
|
||||
TitleBar::TitleBar(bool top, QWidget *parent, bool hasClose) :
|
||||
TitleBar::TitleBar(bool top, QWidget *parent, ITitleParent *titleParent, bool hasClose) :
|
||||
QWidget(parent)
|
||||
{
|
||||
_minimizeButton = NULL;
|
||||
_maximizeButton = NULL;
|
||||
_closeButton = NULL;
|
||||
_moving = false;
|
||||
_is_draging = false;
|
||||
_parent = parent;
|
||||
_isTop = top;
|
||||
_hasClose = hasClose;
|
||||
_title = NULL;
|
||||
_is_native = false;
|
||||
_titleParent = titleParent;
|
||||
_is_done_moved = false;
|
||||
|
||||
assert(parent);
|
||||
|
||||
@ -114,7 +122,7 @@ void TitleBar::reStyle()
|
||||
|
||||
if (_isTop) {
|
||||
_minimizeButton->setIcon(QIcon(iconPath+"/minimize.svg"));
|
||||
if (parentWidget()->isMaximized())
|
||||
if (ParentIsMaxsized())
|
||||
_maximizeButton->setIcon(QIcon(iconPath+"/restore.svg"));
|
||||
else
|
||||
_maximizeButton->setIcon(QIcon(iconPath+"/maximize.svg"));
|
||||
@ -123,6 +131,16 @@ void TitleBar::reStyle()
|
||||
_closeButton->setIcon(QIcon(iconPath+"/close.svg"));
|
||||
}
|
||||
|
||||
bool TitleBar::ParentIsMaxsized()
|
||||
{
|
||||
if (_titleParent != NULL){
|
||||
return _titleParent->ParentIsMaxsized();
|
||||
}
|
||||
else{
|
||||
return parentWidget()->isMaximized();
|
||||
}
|
||||
}
|
||||
|
||||
void TitleBar::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
//draw logo icon
|
||||
@ -182,7 +200,7 @@ QString TitleBar::title()
|
||||
void TitleBar::showMaxRestore()
|
||||
{
|
||||
QString iconPath = GetIconPath();
|
||||
if (parentWidget()->isMaximized()) {
|
||||
if (ParentIsMaxsized()) {
|
||||
_maximizeButton->setIcon(QIcon(iconPath+"/maximize.svg"));
|
||||
normalShow();
|
||||
} else {
|
||||
@ -203,7 +221,9 @@ void TitleBar::setRestoreButton(bool max)
|
||||
|
||||
void TitleBar::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
if(event->button() == Qt::LeftButton && !parentWidget()->isMaximized())
|
||||
bool ableMove = !ParentIsMaxsized();
|
||||
|
||||
if(event->button() == Qt::LeftButton && ableMove)
|
||||
{
|
||||
int x = event->pos().x();
|
||||
int y = event->pos().y();
|
||||
@ -212,9 +232,25 @@ void TitleBar::mousePressEvent(QMouseEvent* event)
|
||||
bool bClick = (x >= 6 && y >= 5 && x <= width() - 6); //top window need resize hit check
|
||||
|
||||
if (!bTopWidow || bClick ){
|
||||
_moving = true;
|
||||
_is_draging = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
_clickPos.setX(p.x);
|
||||
_clickPos.setY(p.y);
|
||||
#else
|
||||
_clickPos = event->globalPos();
|
||||
#endif
|
||||
if (_titleParent != NULL){
|
||||
_oldPos = _titleParent->GetParentPos();
|
||||
}
|
||||
else{
|
||||
_oldPos = _parent->pos();
|
||||
}
|
||||
|
||||
_is_done_moved = false;
|
||||
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
@ -224,10 +260,48 @@ void TitleBar::mousePressEvent(QMouseEvent* event)
|
||||
|
||||
void TitleBar::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if(_moving){
|
||||
int x = _oldPos.x() + (event->globalPos().x() - _clickPos.x());
|
||||
int y = _oldPos.y() + (event->globalPos().y() - _clickPos.y());
|
||||
if(_is_draging){
|
||||
|
||||
int datX = 0;
|
||||
int datY = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
int k = window()->devicePixelRatio();
|
||||
datX = (p.x - _clickPos.x()) / k;
|
||||
datY = (p.y - _clickPos.y()) / k;
|
||||
|
||||
#else
|
||||
datX = (event->globalPos().x() - _clickPos.x());
|
||||
datY = (event->globalPos().y() - _clickPos.y());
|
||||
#endif
|
||||
|
||||
int x = _oldPos.x() + datX;
|
||||
int y = _oldPos.y() + datY;
|
||||
|
||||
if (!_moving){
|
||||
if (ABS_VAL(datX) >= 2 || ABS_VAL(datY) >= 2){
|
||||
_moving = true;
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_titleParent != NULL){
|
||||
|
||||
if (!_is_done_moved){
|
||||
_is_done_moved = true;
|
||||
_titleParent->MoveBegin();
|
||||
}
|
||||
|
||||
_titleParent->MoveWindow(x, y);
|
||||
}
|
||||
else{
|
||||
_parent->move(x, y);
|
||||
}
|
||||
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
@ -236,16 +310,24 @@ void TitleBar::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
void TitleBar::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (_moving && _titleParent != NULL){
|
||||
_titleParent->MoveEnd();
|
||||
}
|
||||
_moving = false;
|
||||
_is_draging = false;
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (_isTop){
|
||||
showMaxRestore();
|
||||
}
|
||||
QWidget::mouseDoubleClickEvent(event);
|
||||
|
||||
if (_isTop){
|
||||
|
||||
QTimer::singleShot(200, this, [this](){
|
||||
showMaxRestore();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void TitleBar::update_font()
|
||||
|
@ -30,6 +30,17 @@ class QHBoxLayout;
|
||||
class QLabel;
|
||||
|
||||
namespace pv {
|
||||
|
||||
class ITitleParent
|
||||
{
|
||||
public:
|
||||
virtual void MoveWindow(int x, int y)=0;
|
||||
virtual QPoint GetParentPos()=0;
|
||||
virtual bool ParentIsMaxsized()=0;
|
||||
virtual void MoveBegin()=0;
|
||||
virtual void MoveEnd()=0;
|
||||
};
|
||||
|
||||
namespace toolbars {
|
||||
|
||||
class TitleBar : public QWidget, public IFontForm
|
||||
@ -37,7 +48,7 @@ class TitleBar : public QWidget, public IFontForm
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TitleBar(bool top, QWidget *parent, bool hasClose = false);
|
||||
TitleBar(bool top, QWidget *parent, ITitleParent *titleParent, bool hasClose);
|
||||
~TitleBar();
|
||||
|
||||
void setTitle(QString title);
|
||||
@ -54,6 +65,8 @@ private:
|
||||
void changeEvent(QEvent *event);
|
||||
void reStyle();
|
||||
|
||||
bool ParentIsMaxsized();
|
||||
|
||||
signals:
|
||||
void normalShow();
|
||||
void maximizedShow();
|
||||
@ -77,12 +90,15 @@ protected:
|
||||
QLabel *_title;
|
||||
|
||||
bool _moving;
|
||||
bool _is_draging;
|
||||
bool _isTop;
|
||||
bool _hasClose;
|
||||
QPoint _clickPos;
|
||||
QPoint _oldPos;
|
||||
QWidget *_parent;
|
||||
bool _is_native;
|
||||
ITitleParent *_titleParent;
|
||||
bool _is_done_moved;
|
||||
};
|
||||
|
||||
} // namespace toolbars
|
||||
|
232
DSView/pv/winnativewidget.cpp
Normal file
232
DSView/pv/winnativewidget.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
|
||||
/*
|
||||
* This file is part of the DSView project.
|
||||
* DSView is based on PulseView.
|
||||
*
|
||||
* Copyright (C) 2024 DreamSourceLab <support@dreamsourcelab.com>
|
||||
*
|
||||
* 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 "winnativewidget.h"
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QScreen>
|
||||
#include <dwmapi.h>
|
||||
#include <assert.h>
|
||||
#include <QString>
|
||||
#include "log.h"
|
||||
#include "../config.h"
|
||||
|
||||
#define NAI_WIN_CREATE_STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN
|
||||
|
||||
namespace pv {
|
||||
|
||||
WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, const int height)
|
||||
{
|
||||
_childWindow = nullptr;
|
||||
childWidget = nullptr;
|
||||
_hWnd = NULL;
|
||||
|
||||
HBRUSH windowBackground = CreateSolidBrush(RGB(255, 255, 255));
|
||||
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
||||
WNDCLASSEX wcx = { 0 };
|
||||
|
||||
wcx.cbSize = sizeof(WNDCLASSEX);
|
||||
wcx.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcx.hInstance = hInstance;
|
||||
wcx.lpfnWndProc = WndProc;
|
||||
wcx.cbClsExtra = 0;
|
||||
wcx.cbWndExtra = 0;
|
||||
wcx.lpszClassName = L"WindowClass";
|
||||
wcx.hbrBackground = windowBackground;
|
||||
wcx.hCursor = LoadCursor(hInstance, IDC_ARROW);
|
||||
|
||||
|
||||
RegisterClassEx(&wcx);
|
||||
if (FAILED(RegisterClassEx(&wcx)))
|
||||
{
|
||||
dsv_info("ERROR: can't register window class");
|
||||
assert(false);
|
||||
}
|
||||
|
||||
QString title = QApplication::applicationName() + " v" + QApplication::applicationVersion();
|
||||
wchar_t title_string_buffer[50];
|
||||
int title_len = title.toWCharArray(title_string_buffer);
|
||||
title_string_buffer[title_len] = 0;
|
||||
|
||||
_hWnd = CreateWindow(L"WindowClass", title_string_buffer,
|
||||
NAI_WIN_CREATE_STYLE, x, y,
|
||||
width, height, 0, 0, hInstance, nullptr);
|
||||
|
||||
if (!_hWnd)
|
||||
{
|
||||
dsv_info("ERROR: can't create naitive window");
|
||||
assert(false);
|
||||
}
|
||||
|
||||
SetWindowLongPtr(_hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
SetWindowPos(_hWnd, NULL, x, y, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
|
||||
WinNativeWidget::~WinNativeWidget()
|
||||
{
|
||||
if (_hWnd){
|
||||
Show(false);
|
||||
DestroyWindow(_hWnd);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::SetChildWidget(QWidget *w)
|
||||
{
|
||||
childWidget = w;
|
||||
_childWindow = NULL;
|
||||
|
||||
if (w != NULL){
|
||||
_childWindow = (HWND)w->winId();
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WinNativeWidget *self = reinterpret_cast<WinNativeWidget*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
||||
|
||||
if (self == NULL)
|
||||
{
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
if (wParam == SC_KEYMENU)
|
||||
{
|
||||
RECT winrect;
|
||||
GetWindowRect(hWnd, &winrect);
|
||||
TrackPopupMenu(GetSystemMenu(hWnd, false), TPM_TOPALIGN | TPM_LEFTALIGN, winrect.left + 5, winrect.top + 5, 0, hWnd, NULL);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case WM_CLOSE:
|
||||
{
|
||||
if (self->childWidget != NULL)
|
||||
{
|
||||
self->childWidget->close();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
{
|
||||
// PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (self->_childWindow != NULL){
|
||||
self->ResizeChild(false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void WinNativeWidget::ResizeChild(bool bManual)
|
||||
{
|
||||
if (_childWindow != NULL){
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(_hWnd, &rc);
|
||||
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
|
||||
k = childWidget->window()->devicePixelRatio();
|
||||
|
||||
int w = rc.right;
|
||||
int h = rc.bottom;
|
||||
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(_hWnd, &wp);
|
||||
|
||||
if (wp.showCmd == SW_MAXIMIZE) {
|
||||
w -= 8;
|
||||
h -= 8;
|
||||
}
|
||||
|
||||
childWidget->adjustSize();
|
||||
MoveWindow(_childWindow, 0, 0, w , h , 1 );
|
||||
|
||||
// dsv_info("resize child, w:%d, h:%d, k1:%d, k2:%d", w / k, h / k, k1, k2);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::setGeometry(const int x, const int y, const int width, const int height)
|
||||
{
|
||||
// dsv_info("set parent window, x:%d, y:%d, w:%d, h:%d", x, y, width, height);
|
||||
if (_hWnd != NULL){
|
||||
MoveWindow(_hWnd, x, y, width, height, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::Show(bool bShow)
|
||||
{
|
||||
if (_hWnd){
|
||||
ShowWindow(_hWnd, bShow ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::Move(int x, int y)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(_hWnd, &rc);
|
||||
MoveWindow(_hWnd, x, y, rc.right, rc.bottom, 0);
|
||||
}
|
||||
|
||||
void WinNativeWidget::ShowNormal()
|
||||
{
|
||||
if (_hWnd){
|
||||
SendMessage(_hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::ShowMax()
|
||||
{
|
||||
if (_hWnd){
|
||||
SendMessage(_hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::ShowMin()
|
||||
{
|
||||
if (_hWnd){
|
||||
SendMessage(_hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
69
DSView/pv/winnativewidget.h
Normal file
69
DSView/pv/winnativewidget.h
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
/*
|
||||
* This file is part of the DSView project.
|
||||
* DSView is based on PulseView.
|
||||
*
|
||||
* Copyright (C) 2024 DreamSourceLab <support@dreamsourcelab.com>
|
||||
*
|
||||
* 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 WINNATIVEWINDOW_H
|
||||
#define WINNATIVEWINDOW_H
|
||||
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Windowsx.h>
|
||||
#include <QWidget>
|
||||
|
||||
namespace pv {
|
||||
|
||||
class WinNativeWidget
|
||||
{
|
||||
public:
|
||||
|
||||
WinNativeWidget(const int x, const int y, const int width, const int height);
|
||||
~WinNativeWidget();
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void SetChildWidget(QWidget *w);
|
||||
|
||||
void setGeometry(const int x, const int y, const int width, const int height);
|
||||
|
||||
inline HWND Handle(){
|
||||
return _hWnd;
|
||||
}
|
||||
|
||||
void Show(bool bShow);
|
||||
void Move(int x, int y);
|
||||
|
||||
void ShowNormal();
|
||||
void ShowMax();
|
||||
void ShowMin();
|
||||
|
||||
void ResizeChild(bool bManul);
|
||||
|
||||
private:
|
||||
QWidget* childWidget;
|
||||
HWND _childWindow;
|
||||
HWND _hWnd;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // WINNATIVEWINDOW_H
|
Loading…
x
Reference in New Issue
Block a user