mirror of
https://github.com/DreamSourceLab/DSView.git
synced 2025-02-02 13:52:55 +08:00
Add the shadow layer on windows
This commit is contained in:
parent
abe9e8f17b
commit
3e8e7c7807
@ -116,7 +116,7 @@ public:
|
||||
};
|
||||
|
||||
enum ParentNativeEvent{
|
||||
EV_SCREEN_DPI_CHANGED = 0,
|
||||
PARENT_EVENT_DISPLAY_CHANGED = 0,
|
||||
};
|
||||
|
||||
class IParentNativeEventCallback
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QFont>
|
||||
#include <algorithm>
|
||||
#include <QWindow>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QDesktopWidget>
|
||||
@ -77,29 +78,41 @@ MainFrame::MainFrame()
|
||||
_is_native_title = false;
|
||||
_is_resize_ready = false;
|
||||
_parentNativeWidget = NULL;
|
||||
_mainWindow = NULL;
|
||||
_is_max_status = false;
|
||||
_move_start_screen = NULL;
|
||||
_mainWindow = NULL;
|
||||
_move_start_screen = NULL;
|
||||
|
||||
_left = NULL;
|
||||
_right = NULL;
|
||||
_top = NULL;
|
||||
_bottom = NULL;
|
||||
_top_left = NULL;
|
||||
_top_right = NULL;
|
||||
_bottom_left = NULL;
|
||||
_bottom_right = NULL;
|
||||
|
||||
AppControl::Instance()->SetTopWindow(this);
|
||||
|
||||
// Make this a borderless window which can't
|
||||
// be resized or moved via the window system
|
||||
bool isWin32 = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
|
||||
_is_native_title = true;
|
||||
_taskBtn = NULL;
|
||||
isWin32 = true;
|
||||
#else
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
_is_native_title = false;
|
||||
#endif
|
||||
|
||||
// setMinimumWidth(MainWindow::Min_Width);
|
||||
// setMinimumHeight(MainWindow::Min_Height);
|
||||
|
||||
setMinimumWidth(300);
|
||||
setMinimumHeight(400);
|
||||
#ifdef _WIN32
|
||||
if (!_is_native_title){
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
#endif
|
||||
|
||||
setMinimumWidth(MainWindow::Min_Width);
|
||||
setMinimumHeight(MainWindow::Min_Height);
|
||||
|
||||
// Set the window icon
|
||||
QIcon icon;
|
||||
@ -119,8 +132,9 @@ MainFrame::MainFrame()
|
||||
_layout = new QGridLayout(this);
|
||||
_layout->setSpacing(0);
|
||||
_layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
|
||||
if (true)
|
||||
if (!isWin32 || !_is_native_title)
|
||||
{
|
||||
_top_left = new widgets::Border (TopLeft, this);
|
||||
_top_left->setFixedSize(Margin, Margin);
|
||||
@ -159,6 +173,9 @@ MainFrame::MainFrame()
|
||||
_layout->addWidget(_bottom, 2, 1);
|
||||
_layout->addWidget(_bottom_right, 2, 2);
|
||||
}
|
||||
else{
|
||||
_layout->addLayout(vbox, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_taskBtn = new QWinTaskbarButton(this);
|
||||
@ -175,82 +192,9 @@ MainFrame::MainFrame()
|
||||
|
||||
connect(this, SIGNAL(sig_ParentNativeEvent(int)), this, SLOT(OnParentNaitveWindowEvent(int)));
|
||||
|
||||
//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();
|
||||
|
||||
int x = _initWndInfo.r.x;
|
||||
int y = _initWndInfo.r.y;
|
||||
int w = _initWndInfo.r.w;
|
||||
int h = _initWndInfo.r.h;
|
||||
|
||||
x *= k;
|
||||
y *= k;
|
||||
w *= k;
|
||||
h *= 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);
|
||||
_parentNativeWidget->SetNativeEventCallback(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();
|
||||
}
|
||||
_parentNativeWidget->ResizeChild();
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::MoveWindow(int x, int y)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -280,7 +224,7 @@ QPoint MainFrame::GetParentPos()
|
||||
|
||||
bool MainFrame::ParentIsMaxsized()
|
||||
{
|
||||
return _is_max_status;
|
||||
return IsMaxsized();
|
||||
}
|
||||
|
||||
void MainFrame::MoveBegin()
|
||||
@ -308,11 +252,13 @@ void MainFrame::MoveEnd()
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
auto scr = _parentNativeWidget->GetPointScreen();
|
||||
if (scr != _move_start_screen){
|
||||
_parentNativeWidget->UpdateChildDpi();
|
||||
if (scr != _move_start_screen){
|
||||
_parentNativeWidget->UpdateChildDpi();
|
||||
_parentNativeWidget->ResizeSelf();
|
||||
}
|
||||
|
||||
|
||||
_parentNativeWidget->ResizeChild();
|
||||
_parentNativeWidget->MoveShadow();
|
||||
_parentNativeWidget->SetMovingFlag(false);
|
||||
}
|
||||
#endif
|
||||
@ -327,17 +273,24 @@ void MainFrame::OnParentNaitveWindowEvent(int msg)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
if (msg == EV_SCREEN_DPI_CHANGED){
|
||||
if (msg == PARENT_EVENT_DISPLAY_CHANGED){
|
||||
QTimer::singleShot(100, this, [this](){
|
||||
_parentNativeWidget->UpdateChildDpi();
|
||||
_parentNativeWidget->ResizeChild();
|
||||
|
||||
PopupDlgList::TryCloseAllByScreenChanged();
|
||||
_parentNativeWidget->OnDisplayChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::OnMoveWinShadow()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
_parentNativeWidget->MoveShadow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
@ -347,14 +300,14 @@ void MainFrame::resizeEvent(QResizeEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_is_max_status) {
|
||||
if (IsMaxsized()) {
|
||||
hide_border();
|
||||
}
|
||||
else {
|
||||
else if(IsNormalsized()) {
|
||||
show_border();
|
||||
}
|
||||
|
||||
_titleBar->setRestoreButton(_is_max_status);
|
||||
_titleBar->setRestoreButton(IsMaxsized());
|
||||
_layout->update();
|
||||
}
|
||||
|
||||
@ -385,6 +338,9 @@ void MainFrame::unfreezing()
|
||||
|
||||
void MainFrame::hide_border()
|
||||
{
|
||||
if (_top_left == NULL)
|
||||
return;
|
||||
|
||||
_top_left->setVisible(false);
|
||||
_top_right->setVisible(false);
|
||||
_top->setVisible(false);
|
||||
@ -397,6 +353,9 @@ void MainFrame::hide_border()
|
||||
|
||||
void MainFrame::show_border()
|
||||
{
|
||||
if (_top_left == NULL)
|
||||
return;
|
||||
|
||||
_top_left->setVisible(true);
|
||||
_top_right->setVisible(true);
|
||||
_top->setVisible(true);
|
||||
@ -409,16 +368,11 @@ void MainFrame::show_border()
|
||||
|
||||
void MainFrame::showNormal()
|
||||
{
|
||||
show_border();
|
||||
|
||||
dsv_info("Show as normal.");
|
||||
|
||||
_is_max_status = false;
|
||||
show_border();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget){
|
||||
_parentNativeWidget->ShowNormal();
|
||||
|
||||
_parentNativeWidget->ShowNormal();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -429,11 +383,7 @@ void MainFrame::showNormal()
|
||||
void MainFrame::showMaximized()
|
||||
{
|
||||
hide_border();
|
||||
|
||||
dsv_info("Show as maxsize.");
|
||||
|
||||
_is_max_status = true;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget){
|
||||
_parentNativeWidget->ShowMax();
|
||||
@ -445,9 +395,7 @@ void MainFrame::showMaximized()
|
||||
}
|
||||
|
||||
void MainFrame::showMinimized()
|
||||
{
|
||||
dsv_info("Show as minsize.");
|
||||
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget){
|
||||
_parentNativeWidget->ShowMin();
|
||||
@ -471,23 +419,6 @@ void MainFrame::changeEvent(QEvent *event)
|
||||
QFrame::changeEvent(event);
|
||||
}
|
||||
|
||||
void MainFrame::moveToWinNaitiveNormal()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
|
||||
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)
|
||||
{
|
||||
const QEvent::Type type = event->type();
|
||||
@ -505,7 +436,7 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
}
|
||||
|
||||
//when window is maximized, or is moving, call return
|
||||
if (_is_max_status || _titleBar->IsMoving()){
|
||||
if (IsMaxsized() || IsMoving()){
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
|
||||
@ -545,17 +476,27 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
if (type == QEvent::MouseMove) {
|
||||
|
||||
QPoint pt;
|
||||
int k = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
pt.setX(p.x);
|
||||
pt.setY(p.y);
|
||||
|
||||
if (_parentNativeWidget != NULL){
|
||||
auto scr = _parentNativeWidget->GetPointScreen();
|
||||
assert(scr);
|
||||
k = scr->devicePixelRatio();
|
||||
}
|
||||
#else
|
||||
pt = mouse_event->globalPos();
|
||||
#endif
|
||||
int datX = pt.x() - _clickPos.x();
|
||||
int datY = pt.y() - _clickPos.y();
|
||||
datX /= k;
|
||||
datY /= k;
|
||||
|
||||
int l = _dragStartRegion.left();
|
||||
int t = _dragStartRegion.top();
|
||||
int r = _dragStartRegion.right();
|
||||
@ -673,7 +614,6 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
|
||||
@ -682,7 +622,7 @@ void MainFrame::saveNormalRegion()
|
||||
if (!_is_resize_ready){
|
||||
return;
|
||||
}
|
||||
if (_is_max_status){
|
||||
if (!IsNormalsized()){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -691,7 +631,9 @@ void MainFrame::saveNormalRegion()
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
RECT rc;
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
auto scr = _parentNativeWidget->GetPointScreen();
|
||||
assert(scr);
|
||||
int k = scr->devicePixelRatio();
|
||||
|
||||
GetWindowRect(_parentNativeWidget->Handle(), &rc);
|
||||
app.frameOptions.left = rc.left / k;
|
||||
@ -717,9 +659,9 @@ void MainFrame::saveNormalRegion()
|
||||
void MainFrame::writeSettings()
|
||||
{
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
app.frameOptions.isMax = _is_max_status;
|
||||
app.frameOptions.isMax = IsMaxsized();
|
||||
|
||||
if (_is_max_status == false && isVisible()){
|
||||
if (IsNormalsized() && isVisible()){
|
||||
saveNormalRegion();
|
||||
}
|
||||
app.SaveFrame();
|
||||
@ -752,23 +694,18 @@ void MainFrame::ShowFormInit()
|
||||
h++;
|
||||
}
|
||||
|
||||
dsv_info("Init form, x:%d, y:%d, w:%d, h:%d, k:%d",
|
||||
x, y, w, h, _initWndInfo.k);
|
||||
|
||||
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();
|
||||
}
|
||||
if (_initWndInfo.isMaxSize){
|
||||
move(x, y);
|
||||
showMaximized();
|
||||
}
|
||||
else{
|
||||
move(x, y);
|
||||
@ -776,12 +713,96 @@ void MainFrame::ShowFormInit()
|
||||
}
|
||||
|
||||
QFrame::show();
|
||||
|
||||
dsv_info("Init form, x:%d, y:%d, w:%d, h:%d", x, y, w, h);
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_is_native_title){
|
||||
AttachNativeWindow();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::AttachNativeWindow()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
assert(_parentNativeWidget == NULL);
|
||||
|
||||
int k = _initWndInfo.k;
|
||||
|
||||
int x = _normalRegion.x;
|
||||
int y = _normalRegion.y;
|
||||
int w = _normalRegion.w;
|
||||
int h = _normalRegion.h;
|
||||
|
||||
x *= k;
|
||||
y *= k;
|
||||
w *= k;
|
||||
h *= k;
|
||||
|
||||
WinNativeWidget *nativeWindow = new WinNativeWidget(x, y, w, h);
|
||||
nativeWindow->setGeometry(x, y, w, h);
|
||||
|
||||
if (nativeWindow->Handle() == NULL){
|
||||
dsv_info("ERROR: native window is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
//check the normal region
|
||||
QScreen *scr = nativeWindow->GetPointScreen();
|
||||
if (scr != NULL){
|
||||
QRect full_rc = scr->availableGeometry();
|
||||
|
||||
if (full_rc.width() - _normalRegion.w < 100 && !_initWndInfo.isMaxSize)
|
||||
{
|
||||
int w1 = full_rc.width() / 1.5;
|
||||
int h1 = full_rc.height() / 1.5;
|
||||
int x1 = full_rc.left() + (full_rc.width() - w1) / 2;
|
||||
int y1 = full_rc.top() + (full_rc.height() - h1) / 2;
|
||||
nativeWindow->setGeometry(x1 * k, y1 * k, w1 * k, h1 *k);
|
||||
|
||||
dsv_info("%s:Reset the normal region, x:%d, y:%d, w:%d, h:%d",
|
||||
scr->name().toStdString().c_str(),
|
||||
x1, y1, w1, h1);
|
||||
}
|
||||
}
|
||||
else{
|
||||
dsv_info("ERROR: get point screen error.");
|
||||
}
|
||||
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
setProperty("_q_embedded_native_parent_handle", (WId)nativeWindow->Handle());
|
||||
SetWindowLong((HWND)winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
|
||||
SetParent((HWND)winId(), nativeWindow->Handle());
|
||||
|
||||
QEvent e(QEvent::EmbeddingControl);
|
||||
QApplication::sendEvent(this, &e);
|
||||
|
||||
if (_initWndInfo.isMaxSize){
|
||||
nativeWindow->ShowMax();
|
||||
}
|
||||
else{
|
||||
nativeWindow->Show(true);
|
||||
}
|
||||
|
||||
nativeWindow->SetChildWidget(this);
|
||||
nativeWindow->SetNativeEventCallback(this);
|
||||
_parentNativeWidget = nativeWindow;
|
||||
|
||||
auto shandow = _parentNativeWidget->Shadow();
|
||||
if (shandow){
|
||||
shandow->SetFrame(this);
|
||||
connect(shandow, SIGNAL(showSignal()), this, SLOT(OnMoveWinShadow()));
|
||||
}
|
||||
|
||||
QTimer::singleShot(50, this, [this](){
|
||||
move(0,0);
|
||||
setVisible(true);
|
||||
_parentNativeWidget->UpdateChildDpi();
|
||||
_parentNativeWidget->ResizeChild();
|
||||
_parentNativeWidget->BeginShowShadow();
|
||||
});
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::SetFormRegion(int x, int y, int w, int h)
|
||||
@ -789,7 +810,9 @@ void MainFrame::SetFormRegion(int x, int y, int w, int h)
|
||||
#ifdef _WIN32
|
||||
|
||||
if (_parentNativeWidget != NULL){
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
auto scr = _parentNativeWidget->GetPointScreen();
|
||||
assert(scr);
|
||||
int k = scr->devicePixelRatio();
|
||||
|
||||
x *= k;
|
||||
y *= k;
|
||||
@ -812,7 +835,9 @@ QRect MainFrame::GetFormRegion()
|
||||
#ifdef _WIN32
|
||||
|
||||
if (_parentNativeWidget != NULL){
|
||||
int k = QApplication::desktop()->screen()->devicePixelRatio();
|
||||
auto scr = _parentNativeWidget->GetPointScreen();
|
||||
assert(scr);
|
||||
int k = scr->devicePixelRatio();
|
||||
RECT r;
|
||||
GetWindowRect(_parentNativeWidget->Handle(), &r);
|
||||
int x = r.left;
|
||||
@ -831,6 +856,49 @@ QRect MainFrame::GetFormRegion()
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool MainFrame::IsMaxsized()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
return _parentNativeWidget->IsMaxsized();
|
||||
}
|
||||
#endif
|
||||
|
||||
return QFrame::isMaximized();
|
||||
}
|
||||
|
||||
bool MainFrame::IsNormalsized()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
return _parentNativeWidget->IsNormalsized();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!QFrame::isMaximized() && !QFrame::isMinimized()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainFrame::IsMoving()
|
||||
{
|
||||
return _titleBar->IsMoving();
|
||||
}
|
||||
|
||||
int MainFrame::GetDevicePixelRatio()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_parentNativeWidget != NULL){
|
||||
auto scr = _parentNativeWidget->GetPointScreen();
|
||||
assert(scr);
|
||||
return scr->devicePixelRatio();
|
||||
}
|
||||
#endif
|
||||
|
||||
return windowHandle()->devicePixelRatio();
|
||||
}
|
||||
|
||||
void MainFrame::ReadSettings()
|
||||
{
|
||||
AppConfig &app = AppConfig::Instance();
|
||||
@ -851,8 +919,8 @@ void MainFrame::ReadSettings()
|
||||
y = top;
|
||||
}
|
||||
|
||||
dsv_info("Loaded region, x:%d, y:%d, w:%d, h:%d",
|
||||
x, y, right-left, bottom-top);
|
||||
dsv_info("Read region info, x:%d, y:%d, w:%d, h:%d, isMax:%d",
|
||||
x, y, right-left, bottom-top, app.frameOptions.isMax);
|
||||
|
||||
bool bReset = false;
|
||||
int scrIndex = -1;
|
||||
@ -888,6 +956,7 @@ void MainFrame::ReadSettings()
|
||||
_initWndInfo.r.w = 0;
|
||||
_initWndInfo.r.h = 0;
|
||||
_initWndInfo.isMaxSize = false;
|
||||
int k = 1;
|
||||
|
||||
if (app.frameOptions.isMax)
|
||||
{
|
||||
@ -897,10 +966,12 @@ void MainFrame::ReadSettings()
|
||||
if (scrIndex == -1){
|
||||
rc = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
scrName = QGuiApplication::primaryScreen()->name();
|
||||
k = QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||
}
|
||||
else{
|
||||
rc = QGuiApplication::screens().at(scrIndex)->availableGeometry();
|
||||
scrName = QGuiApplication::screens().at(scrIndex)->name();
|
||||
k = QGuiApplication::screens().at(scrIndex)->devicePixelRatio();
|
||||
}
|
||||
|
||||
_initWndInfo.r.x = rc.left();
|
||||
@ -931,10 +1002,12 @@ void MainFrame::ReadSettings()
|
||||
if (scrIndex == -1){
|
||||
rc = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
scrName = QGuiApplication::primaryScreen()->name();
|
||||
k = QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||
}
|
||||
else{
|
||||
rc = QGuiApplication::screens().at(scrIndex)->availableGeometry();
|
||||
scrName = QGuiApplication::screens().at(scrIndex)->name();
|
||||
k = QGuiApplication::screens().at(scrIndex)->devicePixelRatio();
|
||||
}
|
||||
|
||||
int w = rc.width() / 1.5;
|
||||
@ -971,6 +1044,7 @@ void MainFrame::ReadSettings()
|
||||
_normalRegion = _initWndInfo.r;
|
||||
QString scrName = QGuiApplication::screens().at(scrIndex)->name();
|
||||
QRect rc = QGuiApplication::screens().at(scrIndex)->availableGeometry();
|
||||
k = QGuiApplication::screens().at(scrIndex)->devicePixelRatio();
|
||||
|
||||
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());
|
||||
@ -982,6 +1056,7 @@ void MainFrame::ReadSettings()
|
||||
// restore dockwidgets
|
||||
_mainWindow->restore_dock();
|
||||
_titleBar->setRestoreButton(app.frameOptions.isMax);
|
||||
_initWndInfo.k = k;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -64,6 +64,7 @@ struct FormInitInfo
|
||||
{
|
||||
FormRegion r;
|
||||
bool isMaxSize;
|
||||
int k;
|
||||
};
|
||||
|
||||
class MainFrame :
|
||||
@ -93,20 +94,25 @@ public:
|
||||
|
||||
void ShowFormInit();
|
||||
void ShowHelpDocAsync();
|
||||
|
||||
void PrintRegionProc();
|
||||
void PrintRegion();
|
||||
|
||||
bool IsMaxsized();
|
||||
bool IsNormalsized();
|
||||
bool IsMoving();
|
||||
int GetDevicePixelRatio();
|
||||
void SetFormRegion(int x, int y, int w, int h);
|
||||
QRect GetFormRegion();
|
||||
void saveNormalRegion();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
#ifdef _WIN32
|
||||
void showEvent(QShowEvent *event);
|
||||
#endif
|
||||
|
||||
void changeEvent(QEvent *event) override;
|
||||
|
||||
|
||||
signals:
|
||||
void sig_ParentNativeEvent(int msg);
|
||||
|
||||
@ -117,15 +123,14 @@ public slots:
|
||||
|
||||
void showNormal();
|
||||
void showMaximized();
|
||||
void showMinimized();
|
||||
void moveToWinNaitiveNormal();
|
||||
void showMinimized();
|
||||
void OnParentNaitveWindowEvent(int msg);
|
||||
void OnMoveWinShadow();
|
||||
|
||||
private:
|
||||
void hide_border();
|
||||
void show_border();
|
||||
void writeSettings();
|
||||
void saveNormalRegion();
|
||||
|
||||
void ReadSettings();
|
||||
void AttachNativeWindow();
|
||||
@ -139,10 +144,8 @@ private:
|
||||
|
||||
//IParentNativeEventCallback
|
||||
void OnParentNativeEvent(ParentNativeEvent msg) override;
|
||||
|
||||
void SetFormRegion(int x, int y, int w, int h);
|
||||
QRect GetFormRegion();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
toolbars::TitleBar *_titleBar;
|
||||
MainWindow *_mainWindow;
|
||||
@ -168,12 +171,11 @@ private:
|
||||
#endif
|
||||
|
||||
bool _is_native_title;
|
||||
bool _is_resize_ready;
|
||||
bool _is_resize_ready;
|
||||
|
||||
WinNativeWidget *_parentNativeWidget;
|
||||
FormInitInfo _initWndInfo;
|
||||
FormRegion _normalRegion;
|
||||
bool _is_max_status;
|
||||
FormRegion _normalRegion;
|
||||
QPoint _clickPos;
|
||||
QRect _dragStartRegion;
|
||||
QScreen *_move_start_screen;
|
||||
|
@ -84,8 +84,8 @@ class MainWindow :
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static const int Min_Width = 800;
|
||||
static const int Min_Height = 520;
|
||||
static const int Min_Width = 350;
|
||||
static const int Min_Height = 300;
|
||||
static const int Base_Height = 150;
|
||||
static const int Per_Chan_Height = 35;
|
||||
|
||||
|
@ -30,13 +30,21 @@
|
||||
#include <dwmapi.h>
|
||||
#include <assert.h>
|
||||
#include <QString>
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
#include <qmath.h>
|
||||
|
||||
#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
|
||||
#define FIXED_WIDTH(widget) (widget->minimumWidth() >= widget->maximumWidth())
|
||||
#define FIXED_HEIGHT(widget) (widget->minimumHeight() >= widget->maximumHeight())
|
||||
#define FIXED_SIZE(widget) (FIXED_WIDTH(widget) && FIXED_HEIGHT(widget))
|
||||
|
||||
namespace pv {
|
||||
|
||||
|
||||
//-----------------------------WinNativeWidget
|
||||
WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, const int height)
|
||||
{
|
||||
_childWindow = nullptr;
|
||||
@ -44,6 +52,8 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, cons
|
||||
_hWnd = NULL;
|
||||
_event_callback = NULL;
|
||||
_is_moving = false;
|
||||
_shadow = NULL;
|
||||
_cur_screen = NULL;
|
||||
|
||||
HBRUSH windowBackground = CreateSolidBrush(RGB(0, 0, 0));
|
||||
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
||||
@ -55,7 +65,7 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, cons
|
||||
wcx.lpfnWndProc = WndProc;
|
||||
wcx.cbClsExtra = 0;
|
||||
wcx.cbWndExtra = 0;
|
||||
wcx.lpszClassName = L"WindowClass";
|
||||
wcx.lpszClassName = L"DSViewWindowClass";
|
||||
wcx.hbrBackground = windowBackground;
|
||||
wcx.hCursor = LoadCursor(hInstance, IDC_ARROW);
|
||||
|
||||
@ -66,15 +76,12 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, cons
|
||||
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);
|
||||
_hWnd = CreateWindow(L"DSViewWindowClass", L"DSView",
|
||||
// WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN,
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||
x, y, width, height,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
|
||||
if (!_hWnd)
|
||||
{
|
||||
@ -89,6 +96,11 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, cons
|
||||
WinNativeWidget::~WinNativeWidget()
|
||||
{
|
||||
if (_hWnd){
|
||||
if (_shadow){
|
||||
_shadow->hide();
|
||||
delete _shadow;
|
||||
_shadow = NULL;
|
||||
}
|
||||
Show(false);
|
||||
DestroyWindow(_hWnd);
|
||||
}
|
||||
@ -101,6 +113,8 @@ void WinNativeWidget::SetChildWidget(QWidget *w)
|
||||
|
||||
if (w != NULL){
|
||||
_childWindow = (HWND)w->winId();
|
||||
_shadow = new WinShadow(_hWnd, w);
|
||||
_shadow->createWinId();
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,6 +129,22 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case WA_ACTIVE:
|
||||
case WA_CLICKACTIVE:
|
||||
{
|
||||
self->BeginShowShadow();
|
||||
break;
|
||||
}
|
||||
case WA_INACTIVE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
if (wParam == SC_KEYMENU)
|
||||
@ -122,12 +152,12 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam
|
||||
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);
|
||||
}
|
||||
break;;
|
||||
}
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
@ -150,24 +180,76 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (self->_childWindow != NULL){
|
||||
self->ResizeChild();
|
||||
self->ResizeChild();
|
||||
|
||||
if (self->_shadow){
|
||||
if (self->IsNormalsized()){
|
||||
self->_shadow->tryToShow();
|
||||
}
|
||||
else{
|
||||
self->_shadow->hide();
|
||||
}
|
||||
}
|
||||
|
||||
self->MoveShadow();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_DPICHANGED:
|
||||
if (self->_is_moving == false){
|
||||
if (self->_event_callback != NULL){
|
||||
self->_event_callback->OnParentNativeEvent(EV_SCREEN_DPI_CHANGED);
|
||||
}
|
||||
else{
|
||||
self->UpdateChildDpi();
|
||||
self->ResizeChild();
|
||||
}
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
if (self->childWidget)
|
||||
{
|
||||
auto gw = self->childWidget;
|
||||
int k = gw->windowHandle()->devicePixelRatio();
|
||||
MINMAXINFO *mmi = reinterpret_cast<MINMAXINFO*>(lParam);
|
||||
|
||||
dsv_info("Dpi was changed.");
|
||||
int border_width = 0;
|
||||
QSize minimum = gw->minimumSize();
|
||||
QSize sizeHint = gw->minimumSizeHint();
|
||||
|
||||
mmi->ptMinTrackSize.x = qFloor(qMax(minimum.width(), sizeHint.width()) *
|
||||
k) + border_width * 2;
|
||||
mmi->ptMinTrackSize.y = qFloor(qMax(minimum.height(), sizeHint.height()) *
|
||||
k) + border_width;
|
||||
|
||||
QSize maximum = gw->maximumSize();
|
||||
|
||||
mmi->ptMaxTrackSize.x = qFloor(maximum.width() * k) + border_width * 2;
|
||||
mmi->ptMaxTrackSize.y = qFloor(maximum.height() * k) + border_width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
dsv_info("Display changed.");
|
||||
|
||||
if (self->_event_callback != NULL){
|
||||
self->_event_callback->OnParentNativeEvent(PARENT_EVENT_DISPLAY_CHANGED);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
{
|
||||
int st = 3;
|
||||
if (self->IsMaxsized())
|
||||
st = 1;
|
||||
else if (self->IsNormalsized())
|
||||
st = 2;
|
||||
|
||||
if (self->childWidget != NULL && self->_shadow){
|
||||
if (st == 2){
|
||||
if (self->childWidget->isVisible() && !self->_is_moving){
|
||||
self->_shadow->showLater();
|
||||
}
|
||||
}
|
||||
else {
|
||||
self->_shadow->hide();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
@ -177,27 +259,95 @@ void WinNativeWidget::ResizeChild()
|
||||
{
|
||||
if (_childWindow != NULL){
|
||||
RECT rc;
|
||||
GetClientRect(_hWnd, &rc);
|
||||
GetWindowRect(_hWnd, &rc);
|
||||
|
||||
int w = rc.right;
|
||||
int h = rc.bottom;
|
||||
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(_hWnd, &wp);
|
||||
|
||||
if (wp.showCmd == SW_MAXIMIZE) {
|
||||
int sp = 0;
|
||||
int x = sp;
|
||||
int y = sp;
|
||||
int w = rc.right - rc.left - sp * 2;
|
||||
int h = rc.bottom - rc.top - sp * 2;
|
||||
|
||||
if (IsMaxsized()) {
|
||||
w -= 8;
|
||||
h -= 8;
|
||||
}
|
||||
|
||||
//childWidget->adjustSize();
|
||||
MoveWindow(_childWindow, 0, 0, w - 1 , h - 1 , 1);
|
||||
MoveWindow(_childWindow, 0, 0, w , h , 1);
|
||||
childWidget->updateGeometry();
|
||||
|
||||
MoveWindow(_childWindow, x, y, w - 1 , h - 1 , 1);
|
||||
MoveWindow(_childWindow, x, y, w , h , 1);
|
||||
childWidget->updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::ResizeSelf()
|
||||
{
|
||||
if (_hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
GetWindowRect(_hWnd, &rc);
|
||||
|
||||
int x = rc.left;
|
||||
int y = rc.top;
|
||||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
|
||||
static int times = 0;
|
||||
times++;
|
||||
|
||||
if (times % 2 == 0){
|
||||
w += 2;
|
||||
h += 2;
|
||||
}
|
||||
else{
|
||||
w -= 2;
|
||||
h -= 2;
|
||||
}
|
||||
|
||||
MoveWindow(_hWnd, x, y, w , h , 1);
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::MoveShadow()
|
||||
{
|
||||
if (!_shadow || !childWidget){
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsNormalsized())
|
||||
{
|
||||
|
||||
RECT rc;
|
||||
GetWindowRect(_hWnd, &rc);
|
||||
|
||||
int bw = SHADOW_BORDER_WIDTH;
|
||||
|
||||
// bw = 20;
|
||||
|
||||
int x = rc.left;
|
||||
int y = rc.top;
|
||||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
|
||||
x -= bw;
|
||||
y -= bw;
|
||||
w += bw * 2;
|
||||
h += bw * 2;
|
||||
|
||||
MoveWindow((HWND)_shadow->winId(), x, y, w , h , 1);
|
||||
_shadow->setActive(isActiveWindow());
|
||||
}
|
||||
else{
|
||||
_shadow->hide();
|
||||
_shadow->setActive(false);
|
||||
_shadow->update();
|
||||
}
|
||||
}
|
||||
|
||||
bool WinNativeWidget::isActiveWindow()
|
||||
{
|
||||
const HWND active_window = GetActiveWindow();
|
||||
return ((active_window == _hWnd) || IsChild(_hWnd, active_window));
|
||||
}
|
||||
|
||||
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);
|
||||
@ -210,6 +360,10 @@ void WinNativeWidget::Show(bool bShow)
|
||||
{
|
||||
if (_hWnd){
|
||||
ShowWindow(_hWnd, bShow ? SW_SHOW : SW_HIDE);
|
||||
|
||||
if (!bShow && _shadow){
|
||||
_shadow->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +371,20 @@ void WinNativeWidget::Show(bool bShow)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(_hWnd, &rc);
|
||||
MoveWindow(_hWnd, x, y, rc.right, rc.bottom, 0);
|
||||
int w = rc.right;
|
||||
int h = rc.bottom;
|
||||
MoveWindow(_hWnd, x, y, w, h, 1);
|
||||
|
||||
if (_shadow != NULL){
|
||||
auto scr = GetPointScreen();
|
||||
|
||||
if (_cur_screen && scr && scr != _cur_screen){
|
||||
_shadow->windowHandle()->setScreen(scr);
|
||||
}
|
||||
_cur_screen = scr;
|
||||
|
||||
MoveShadow();
|
||||
}
|
||||
}
|
||||
|
||||
void WinNativeWidget::ShowNormal()
|
||||
@ -246,6 +413,12 @@ void WinNativeWidget::UpdateChildDpi()
|
||||
QScreen *scr = screenFromWindow(_hWnd);
|
||||
if (scr != NULL && childWidget != NULL){
|
||||
childWidget->windowHandle()->setScreen(scr);
|
||||
if (_shadow){
|
||||
_shadow->windowHandle()->setScreen(scr);
|
||||
}
|
||||
}
|
||||
else{
|
||||
dsv_info("ERROR: failed to update child's screen.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,4 +455,48 @@ QScreen* WinNativeWidget::GetPointScreen()
|
||||
return screenFromWindow(_hWnd);
|
||||
}
|
||||
|
||||
void WinNativeWidget::OnDisplayChanged()
|
||||
{
|
||||
UpdateChildDpi();
|
||||
ResizeChild();
|
||||
|
||||
RECT rc;
|
||||
GetWindowRect(_hWnd, &rc);
|
||||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
MoveWindow(_hWnd, rc.left, rc.top, w + 1, h + 1, 1);
|
||||
}
|
||||
|
||||
bool WinNativeWidget::IsMaxsized()
|
||||
{
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(_hWnd, &wp);
|
||||
return wp.showCmd == SW_MAXIMIZE;
|
||||
}
|
||||
|
||||
bool WinNativeWidget::IsMinsized()
|
||||
{
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(_hWnd, &wp);
|
||||
return wp.showCmd == SW_MINIMIZE;
|
||||
}
|
||||
|
||||
bool WinNativeWidget::IsNormalsized()
|
||||
{
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(_hWnd, &wp);
|
||||
return wp.showCmd == SW_SHOWNORMAL;
|
||||
}
|
||||
|
||||
void WinNativeWidget::BeginShowShadow()
|
||||
{
|
||||
if (_shadow){
|
||||
_shadow->show();
|
||||
_shadow->showLater();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,19 +28,23 @@
|
||||
#include <Windows.h>
|
||||
#include <Windowsx.h>
|
||||
#include <QWidget>
|
||||
#include <QByteArray>
|
||||
|
||||
#include "interface/icallbacks.h"
|
||||
#include "winshadow.h"
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif
|
||||
|
||||
namespace pv {
|
||||
|
||||
|
||||
class WinNativeWidget
|
||||
{
|
||||
public:
|
||||
|
||||
WinNativeWidget(const int x, const int y, const int width, const int height);
|
||||
WinNativeWidget(const int x, const int y, const int width, const int heigh);
|
||||
~WinNativeWidget();
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
@ -62,9 +66,11 @@ public:
|
||||
|
||||
void UpdateChildDpi();
|
||||
void ResizeChild();
|
||||
void ResizeSelf();
|
||||
|
||||
inline void SetMovingFlag(bool bMoving){
|
||||
_is_moving = bMoving;
|
||||
_cur_screen = NULL;
|
||||
}
|
||||
|
||||
QScreen* GetPointScreen();
|
||||
@ -73,15 +79,32 @@ public:
|
||||
_event_callback = callback;
|
||||
}
|
||||
|
||||
void OnDisplayChanged();
|
||||
bool IsMaxsized();
|
||||
bool IsMinsized();
|
||||
bool IsNormalsized();
|
||||
|
||||
void MoveShadow();
|
||||
|
||||
inline WinShadow* Shadow(){
|
||||
return _shadow;
|
||||
}
|
||||
|
||||
bool isActiveWindow();
|
||||
|
||||
void BeginShowShadow();
|
||||
|
||||
private:
|
||||
QScreen* screenFromWindow(HWND hwnd);
|
||||
|
||||
|
||||
private:
|
||||
QWidget* childWidget;
|
||||
HWND _childWindow;
|
||||
HWND _hWnd;
|
||||
IParentNativeEventCallback *_event_callback;
|
||||
bool _is_moving;
|
||||
WinShadow *_shadow;
|
||||
QScreen *_cur_screen;
|
||||
};
|
||||
|
||||
}
|
||||
|
426
DSView/pv/winshadow.cpp
Normal file
426
DSView/pv/winshadow.cpp
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* 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 "winshadow.h"
|
||||
#include "log.h"
|
||||
#include "config/appconfig.h"
|
||||
#include "mainframe.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
|
||||
namespace pv {
|
||||
|
||||
namespace
|
||||
{
|
||||
const QColor dark_border0 = QColor(80, 80, 80, 255);
|
||||
const QColor dark_border1 = QColor(48, 47, 47, 200);
|
||||
const QColor dark_border2 = QColor(48, 47, 47, 150);
|
||||
const QColor dark_border3 = QColor(48, 47, 47, 100);
|
||||
const QColor dark_border4 = QColor(48, 47, 47, 10);
|
||||
|
||||
const QColor light_border0 = QColor(100, 100, 100, 255);
|
||||
const QColor light_border1 = QColor(150, 150, 150, 150);
|
||||
const QColor light_border2 = QColor(150, 150, 150, 100);
|
||||
const QColor light_border3 = QColor(150, 150, 150, 50);
|
||||
const QColor light_border4 = QColor(150, 150, 150, 0);
|
||||
|
||||
const int Margin = 4;
|
||||
}
|
||||
|
||||
WinShadow::WinShadow(HWND hwnd, QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_hwnd = HWND(hwnd);
|
||||
m_active = true;
|
||||
m_timer = NULL;
|
||||
m_bClean = false;
|
||||
_frame = NULL;
|
||||
_hit_border = None;
|
||||
_bDraging = false;
|
||||
_freezing = false;
|
||||
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
m_timer = new QTimer(this);
|
||||
connect(m_timer, &QTimer::timeout, this, &WinShadow::show);
|
||||
|
||||
m_timer->setInterval(500);
|
||||
m_timer->setSingleShot(true);
|
||||
|
||||
_layout = new QGridLayout(this);
|
||||
_layout->setSpacing(0);
|
||||
_layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
setLayout(_layout);
|
||||
|
||||
if (true)
|
||||
{
|
||||
_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->addWidget(_top_left, 0, 0);
|
||||
_layout->addWidget(_top, 0, 1);
|
||||
_layout->addWidget(_top_right, 0, 2);
|
||||
_layout->addWidget(_left, 1, 0);
|
||||
|
||||
_layout->addWidget(_right, 1, 2);
|
||||
_layout->addWidget(_bottom_left, 2, 0);
|
||||
_layout->addWidget(_bottom, 2, 1);
|
||||
_layout->addWidget(_bottom_right, 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
int WinShadow::shadowWidth()
|
||||
{
|
||||
return SHADOW_BORDER_WIDTH;
|
||||
}
|
||||
|
||||
void WinShadow::showLater()
|
||||
{
|
||||
m_timer->stop();
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
void WinShadow::show()
|
||||
{
|
||||
m_bClean = false;
|
||||
|
||||
if (m_timer->isActive())
|
||||
return;
|
||||
|
||||
if (!IsWindowEnabled(m_hwnd))
|
||||
return;
|
||||
|
||||
if (GetForegroundWindow() != m_hwnd)
|
||||
return;
|
||||
|
||||
Q_EMIT showSignal();
|
||||
|
||||
QWidget::show();
|
||||
QWidget::raise();
|
||||
|
||||
SetWindowPos(m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
|
||||
}
|
||||
|
||||
bool WinShadow::tryToShow()
|
||||
{
|
||||
if (!isVisible()){
|
||||
show();
|
||||
|
||||
if (!m_timer->isActive()){
|
||||
showLater();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WinShadow::SetClean(bool bClean)
|
||||
{
|
||||
m_bClean = bClean;
|
||||
if (isVisible()){
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void WinShadow::hide()
|
||||
{
|
||||
SetClean(true);
|
||||
m_timer->stop();
|
||||
|
||||
if (!isVisible())
|
||||
return;
|
||||
|
||||
QWidget::hide();
|
||||
}
|
||||
|
||||
void WinShadow::setActive(bool active)
|
||||
{
|
||||
m_active = active;
|
||||
repaint();
|
||||
}
|
||||
|
||||
bool WinShadow::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
{
|
||||
MSG *msg = static_cast<MSG*>(message);
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
switch (msg->wParam)
|
||||
{
|
||||
case WA_ACTIVE:
|
||||
case WA_CLICKACTIVE:
|
||||
{
|
||||
SetForegroundWindow(m_hwnd);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEACTIVATE:
|
||||
{
|
||||
SetForegroundWindow(m_hwnd);
|
||||
*result = MA_NOACTIVATE;
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
case WM_NCMOUSEMOVE:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCLBUTTONUP:
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
*result = long(SendMessageW(m_hwnd, msg->message, msg->wParam, msg->lParam));
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QWidget::nativeEvent(eventType, message, result);
|
||||
}
|
||||
|
||||
bool WinShadow::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
const QEvent::Type type = event->type();
|
||||
const QMouseEvent *const mouse_event = (QMouseEvent*)event;
|
||||
int newWidth = 0;
|
||||
int newHeight = 0;
|
||||
int newLeft = 0;
|
||||
int newTop = 0;
|
||||
|
||||
if (_frame == NULL){
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
if (type != QEvent::MouseMove
|
||||
&& type != QEvent::MouseButtonPress
|
||||
&& type != QEvent::MouseButtonRelease
|
||||
&& type != QEvent::Leave){
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
//when window is maximized, or is moving, call return
|
||||
if (_frame->IsMaxsized() || _frame->IsMoving()){
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
if (!_bDraging && type == QEvent::MouseMove && (!(mouse_event->buttons() | Qt::NoButton))){
|
||||
if (object == _top_left) {
|
||||
_hit_border = TopLeft;
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
} else if (object == _bottom_right) {
|
||||
_hit_border = BottomRight;
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
} else if (object == _top_right) {
|
||||
_hit_border = TopRight;
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (object == _bottom_left) {
|
||||
_hit_border = BottomLeft;
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (object == _left) {
|
||||
_hit_border = Left;
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
} else if (object == _right) {
|
||||
_hit_border = Right;
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
} else if (object == _bottom) {
|
||||
_hit_border = Bottom;
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
} else if (object == _top) {
|
||||
_hit_border = Top;
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
} else {
|
||||
_hit_border = None;
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
if (type == QEvent::MouseMove) {
|
||||
|
||||
QPoint pt;
|
||||
int k = _frame->GetDevicePixelRatio();
|
||||
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
pt.setX(p.x);
|
||||
pt.setY(p.y);
|
||||
|
||||
|
||||
int datX = pt.x() - _clickPos.x();
|
||||
int datY = pt.y() - _clickPos.y();
|
||||
datX /= k;
|
||||
datY /= k;
|
||||
|
||||
int l = _dragStartRegion.left();
|
||||
int t = _dragStartRegion.top();
|
||||
int r = _dragStartRegion.right();
|
||||
int b = _dragStartRegion.bottom();
|
||||
|
||||
if(mouse_event->buttons().testFlag(Qt::LeftButton)) {
|
||||
|
||||
// Do nothing this time.
|
||||
if (_freezing){
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
int minW = MainWindow::Min_Width;
|
||||
int minH = MainWindow::Min_Height;
|
||||
|
||||
switch (_hit_border) {
|
||||
case TopLeft:
|
||||
l += datX;
|
||||
t += datY;
|
||||
if (r - l < minW)
|
||||
l = r - minW;
|
||||
if (b - t < minH)
|
||||
t = b - minH;
|
||||
break;
|
||||
|
||||
case BottomLeft:
|
||||
l += datX;
|
||||
b += datY;
|
||||
if (r - l < minW)
|
||||
l = r - minW;
|
||||
if (b - t < minH)
|
||||
b = t + minH;
|
||||
break;
|
||||
|
||||
case TopRight:
|
||||
r += datX;
|
||||
t += datY;
|
||||
if (r - l < minW)
|
||||
r = l + minW;
|
||||
if (b - t < minH)
|
||||
t = b - minH;
|
||||
break;
|
||||
|
||||
case BottomRight:
|
||||
r += datX;
|
||||
b += datY;
|
||||
if (r - l < minW)
|
||||
r = l + minW;
|
||||
if (b - t < minH)
|
||||
b = t + minH;
|
||||
break;
|
||||
|
||||
case Left:
|
||||
l += datX;
|
||||
if (r - l < minW)
|
||||
l = r - minW;
|
||||
break;
|
||||
|
||||
case Right:
|
||||
r += datX;
|
||||
if (r - l < minW)
|
||||
r = l + minW;
|
||||
break;
|
||||
|
||||
case Top:
|
||||
t += datY;
|
||||
if (b - t < minH)
|
||||
t = b - minH;
|
||||
break;
|
||||
|
||||
case Bottom:
|
||||
b += datY;
|
||||
if (b - t < minH)
|
||||
b = t + minH;
|
||||
break;
|
||||
|
||||
default:
|
||||
r = l;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r != l){
|
||||
_frame->SetFormRegion(l, t, r-l, b-t);
|
||||
_frame->saveNormalRegion();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (type == QEvent::MouseButtonPress) {
|
||||
if (mouse_event->button() == Qt::LeftButton)
|
||||
if (_hit_border != None)
|
||||
_bDraging = true;
|
||||
_timer.start(50);
|
||||
|
||||
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
_clickPos.setX(p.x);
|
||||
_clickPos.setY(p.y);
|
||||
|
||||
|
||||
_dragStartRegion = _frame->GetFormRegion();
|
||||
}
|
||||
else if (type == QEvent::MouseButtonRelease) {
|
||||
if (mouse_event->button() == Qt::LeftButton) {
|
||||
_bDraging = false;
|
||||
_timer.stop();
|
||||
}
|
||||
}
|
||||
else if (!_bDraging && type == QEvent::Leave) {
|
||||
_hit_border = None;
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
}
|
114
DSView/pv/winshadow.h
Normal file
114
DSView/pv/winshadow.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 WINSHADOW_H
|
||||
#define WINSHADOW_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
#include <windows.h>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "widgets/border.h"
|
||||
|
||||
|
||||
#define SHADOW_BORDER_WIDTH 4
|
||||
|
||||
namespace pv {
|
||||
|
||||
class MainFrame;
|
||||
|
||||
class WinShadow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum borderTypes{
|
||||
None,
|
||||
TopLeft,
|
||||
Left,
|
||||
BottomLeft,
|
||||
Bottom,
|
||||
BottomRight,
|
||||
Right,
|
||||
TopRight,
|
||||
Top
|
||||
}borderTypes;
|
||||
|
||||
public:
|
||||
explicit WinShadow(HWND hwnd, QWidget *parent);
|
||||
|
||||
bool tryToShow();
|
||||
|
||||
void SetClean(bool bClean);
|
||||
|
||||
inline void SetFrame(MainFrame *frame){
|
||||
_frame = frame;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void showSignal();
|
||||
|
||||
public Q_SLOTS:
|
||||
void showLater();
|
||||
void show();
|
||||
void hide();
|
||||
void setActive(bool active);
|
||||
int shadowWidth();
|
||||
|
||||
private:
|
||||
//Functions
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
QTimer *m_timer;
|
||||
HWND m_hwnd;
|
||||
bool m_active;
|
||||
bool m_bClean;
|
||||
|
||||
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;
|
||||
|
||||
MainFrame *_frame;
|
||||
|
||||
int _hit_border;
|
||||
bool _bDraging;
|
||||
QTimer _timer;
|
||||
bool _freezing;
|
||||
QPoint _clickPos;
|
||||
QRect _dragStartRegion;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SHADOW_H
|
Loading…
x
Reference in New Issue
Block a user