Allow fixed windows with custom title bar.
This commit is contained in:
parent
bc62f87f0e
commit
c0ce14bb68
11 changed files with 85 additions and 14 deletions
|
|
@ -20,7 +20,8 @@ public:
|
||||||
|
|
||||||
not_null<RpWidget*> body() override;
|
not_null<RpWidget*> body() override;
|
||||||
void setTitle(const QString &title) override;
|
void setTitle(const QString &title) override;
|
||||||
void setSizeMin(QSize size) override;
|
void setMinimumSize(QSize size) override;
|
||||||
|
void setFixedSize(QSize size) override;
|
||||||
void setGeometry(QRect rect) override;
|
void setGeometry(QRect rect) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -204,12 +204,18 @@ void WindowHelper::toggleCustomTitle(bool visible) {
|
||||||
_window->setWindowTitle(visible ? QString() : _title->text());
|
_window->setWindowTitle(visible ? QString() : _title->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowHelper::setSizeMin(QSize size) {
|
void WindowHelper::setMinimumSize(QSize size) {
|
||||||
_window->setMinimumSize(
|
_window->setMinimumSize(
|
||||||
size.width(),
|
size.width(),
|
||||||
(_title ? _title->height() : 0) + size.height());
|
(_title ? _title->height() : 0) + size.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowHelper::setFixedSize(QSize size) {
|
||||||
|
_window->setFixedSize(
|
||||||
|
size.width(),
|
||||||
|
(_title ? _title->height() : 0) + size.height());
|
||||||
|
}
|
||||||
|
|
||||||
void WindowHelper::setGeometry(QRect rect) {
|
void WindowHelper::setGeometry(QRect rect) {
|
||||||
_window->setGeometry(
|
_window->setGeometry(
|
||||||
rect.marginsAdded({ 0, (_title ? _title->height() : 0), 0, 0 }));
|
rect.marginsAdded({ 0, (_title ? _title->height() : 0), 0, 0 }));
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ class BasicWindowHelper {
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] virtual not_null<RpWidget*> body() = 0;
|
[[nodiscard]] virtual not_null<RpWidget*> body() = 0;
|
||||||
virtual void setTitle(const QString &title) = 0;
|
virtual void setTitle(const QString &title) = 0;
|
||||||
virtual void setSizeMin(QSize size) = 0;
|
virtual void setMinimumSize(QSize size) = 0;
|
||||||
|
virtual void setFixedSize(QSize size) = 0;
|
||||||
virtual void setGeometry(QRect rect) = 0;
|
virtual void setGeometry(QRect rect) = 0;
|
||||||
virtual ~BasicWindowHelper() = default;
|
virtual ~BasicWindowHelper() = default;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -514,6 +514,10 @@ void WindowShadow::updateWindow(int i, POINT *p, SIZE *s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowShadow::setResizeEnabled(bool enabled) {
|
||||||
|
_resizeEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WindowShadow::WindowCallback(
|
LRESULT CALLBACK WindowShadow::WindowCallback(
|
||||||
HWND hwnd,
|
HWND hwnd,
|
||||||
UINT msg,
|
UINT msg,
|
||||||
|
|
@ -540,6 +544,9 @@ LRESULT WindowShadow::windowCallback(
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case WM_NCHITTEST: {
|
case WM_NCHITTEST: {
|
||||||
|
if (!_resizeEnabled) {
|
||||||
|
return HTTRANSPARENT;
|
||||||
|
}
|
||||||
const auto xPos = GET_X_LPARAM(lParam);
|
const auto xPos = GET_X_LPARAM(lParam);
|
||||||
const auto yPos = GET_Y_LPARAM(lParam);
|
const auto yPos = GET_Y_LPARAM(lParam);
|
||||||
if (hwnd == _handles[0]) {
|
if (hwnd == _handles[0]) {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public:
|
||||||
void setColor(QColor color);
|
void setColor(QColor color);
|
||||||
void update(Changes changes, WINDOWPOS *pos = nullptr);
|
void update(Changes changes, WINDOWPOS *pos = nullptr);
|
||||||
void updateWindow(int i, POINT *p, SIZE *s = nullptr);
|
void updateWindow(int i, POINT *p, SIZE *s = nullptr);
|
||||||
|
void setResizeEnabled(bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Direction {
|
enum class Direction {
|
||||||
|
|
@ -90,6 +91,7 @@ private:
|
||||||
std::vector<BYTE> _colors;
|
std::vector<BYTE> _colors;
|
||||||
|
|
||||||
bool _hidden = true;
|
bool _hidden = true;
|
||||||
|
bool _resizeEnabled = true;
|
||||||
|
|
||||||
HWND _handles[4] = { nullptr };
|
HWND _handles[4] = { nullptr };
|
||||||
HDC _contexts[4] = { nullptr };
|
HDC _contexts[4] = { nullptr };
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,11 @@ not_null<RpWidget*> TitleWidget::window() const {
|
||||||
return static_cast<RpWidget*>(parentWidget());
|
return static_cast<RpWidget*>(parentWidget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TitleWidget::setResizeEnabled(bool enabled) {
|
||||||
|
_resizeEnabled = enabled;
|
||||||
|
updateControlsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
void TitleWidget::init() {
|
void TitleWidget::init() {
|
||||||
_minimize->setClickedCallback([=] {
|
_minimize->setClickedCallback([=] {
|
||||||
window()->setWindowState(Qt::WindowMinimized);
|
window()->setWindowState(Qt::WindowMinimized);
|
||||||
|
|
@ -85,7 +90,10 @@ void TitleWidget::paintEvent(QPaintEvent *e) {
|
||||||
void TitleWidget::updateControlsPosition() {
|
void TitleWidget::updateControlsPosition() {
|
||||||
auto right = 0;
|
auto right = 0;
|
||||||
_close->moveToRight(right, 0); right += _close->width();
|
_close->moveToRight(right, 0); right += _close->width();
|
||||||
_maximizeRestore->moveToRight(right, 0); right += _maximizeRestore->width();
|
_maximizeRestore->moveToRight(right, 0);
|
||||||
|
if (_resizeEnabled) {
|
||||||
|
right += _maximizeRestore->width();
|
||||||
|
}
|
||||||
_minimize->moveToRight(right, 0);
|
_minimize->moveToRight(right, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,6 +103,7 @@ void TitleWidget::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleWidget::updateControlsVisibility() {
|
void TitleWidget::updateControlsVisibility() {
|
||||||
|
_maximizeRestore->setVisible(_resizeEnabled);
|
||||||
updateControlsPosition();
|
updateControlsPosition();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ public:
|
||||||
explicit TitleWidget(not_null<RpWidget*> parent);
|
explicit TitleWidget(not_null<RpWidget*> parent);
|
||||||
|
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
HitTestResult hitTest(QPoint point) const;
|
[[nodiscard]] HitTestResult hitTest(QPoint point) const;
|
||||||
|
void setResizeEnabled(bool enabled);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
@ -61,6 +62,7 @@ private:
|
||||||
|
|
||||||
bool _maximizedState = false;
|
bool _maximizedState = false;
|
||||||
bool _activeState = false;
|
bool _activeState = false;
|
||||||
|
bool _resizeEnabled = true;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,10 +99,16 @@ void WindowHelper::setTitle(const QString &title) {
|
||||||
_window->setWindowTitle(title);
|
_window->setWindowTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowHelper::setSizeMin(QSize size) {
|
void WindowHelper::setMinimumSize(QSize size) {
|
||||||
_window->setMinimumSize(size.width(), _title->height() + size.height());
|
_window->setMinimumSize(size.width(), _title->height() + size.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowHelper::setFixedSize(QSize size) {
|
||||||
|
_window->setFixedSize(size.width(), _title->height() + size.height());
|
||||||
|
_title->setResizeEnabled(false);
|
||||||
|
_shadow.setResizeEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowHelper::setGeometry(QRect rect) {
|
void WindowHelper::setGeometry(QRect rect) {
|
||||||
_window->setGeometry(rect.marginsAdded({ 0, _title->height(), 0, 0 }));
|
_window->setGeometry(rect.marginsAdded({ 0, _title->height(), 0, 0 }));
|
||||||
}
|
}
|
||||||
|
|
@ -133,10 +139,20 @@ void WindowHelper::init() {
|
||||||
|
|
||||||
_menu = GetSystemMenu(_handle, FALSE);
|
_menu = GetSystemMenu(_handle, FALSE);
|
||||||
updateSystemMenu();
|
updateSystemMenu();
|
||||||
|
|
||||||
|
const auto handleStateChanged = [=](Qt::WindowState state) {
|
||||||
|
updateSystemMenu(state);
|
||||||
|
if (fixedSize() && (state & Qt::WindowMaximized)) {
|
||||||
|
crl::on_main(_window.get(), [=] {
|
||||||
|
_window->setWindowState(
|
||||||
|
_window->windowState() & ~Qt::WindowMaximized);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
Ui::Connect(
|
Ui::Connect(
|
||||||
_window->windowHandle(),
|
_window->windowHandle(),
|
||||||
&QWindow::windowStateChanged,
|
&QWindow::windowStateChanged,
|
||||||
[=](Qt::WindowState state) { updateSystemMenu(state); });
|
handleStateChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowHelper::handleNativeEvent(
|
bool WindowHelper::handleNativeEvent(
|
||||||
|
|
@ -189,6 +205,16 @@ bool WindowHelper::handleNativeEvent(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_NCLBUTTONDBLCLK:
|
||||||
|
case WM_NCMBUTTONDBLCLK:
|
||||||
|
case WM_NCRBUTTONDBLCLK:
|
||||||
|
case WM_NCXBUTTONDBLCLK: {
|
||||||
|
if (!fixedSize()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result) *result = 0;
|
||||||
|
} return true;
|
||||||
|
|
||||||
case WM_NCACTIVATE: {
|
case WM_NCACTIVATE: {
|
||||||
if (IsCompositionEnabled()) {
|
if (IsCompositionEnabled()) {
|
||||||
const auto res = DefWindowProc(_handle, msg, wParam, -1);
|
const auto res = DefWindowProc(_handle, msg, wParam, -1);
|
||||||
|
|
@ -288,7 +314,7 @@ bool WindowHelper::handleNativeEvent(
|
||||||
} return true;
|
} return true;
|
||||||
|
|
||||||
case WM_SYSCOMMAND: {
|
case WM_SYSCOMMAND: {
|
||||||
if (wParam == SC_MOUSEMENU) {
|
if (wParam == SC_MOUSEMENU && !fixedSize()) {
|
||||||
POINTS p = MAKEPOINTS(lParam);
|
POINTS p = MAKEPOINTS(lParam);
|
||||||
updateSystemMenu(_window->windowHandle()->windowState());
|
updateSystemMenu(_window->windowHandle()->windowState());
|
||||||
TrackPopupMenu(
|
TrackPopupMenu(
|
||||||
|
|
@ -313,7 +339,9 @@ bool WindowHelper::handleNativeEvent(
|
||||||
_window->setWindowState(Qt::WindowMinimized);
|
_window->setWindowState(Qt::WindowMinimized);
|
||||||
return true;
|
return true;
|
||||||
case SC_MAXIMIZE:
|
case SC_MAXIMIZE:
|
||||||
_window->setWindowState(Qt::WindowMaximized);
|
if (!fixedSize()) {
|
||||||
|
_window->setWindowState(Qt::WindowMaximized);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
case SC_RESTORE:
|
case SC_RESTORE:
|
||||||
_window->setWindowState(Qt::WindowNoState);
|
_window->setWindowState(Qt::WindowNoState);
|
||||||
|
|
@ -325,6 +353,10 @@ bool WindowHelper::handleNativeEvent(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WindowHelper::fixedSize() const {
|
||||||
|
return _window->minimumSize() == _window->maximumSize();
|
||||||
|
}
|
||||||
|
|
||||||
void WindowHelper::updateMargins() {
|
void WindowHelper::updateMargins() {
|
||||||
if (_updatingMargins) return;
|
if (_updatingMargins) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ public:
|
||||||
|
|
||||||
not_null<RpWidget*> body() override;
|
not_null<RpWidget*> body() override;
|
||||||
void setTitle(const QString &title) override;
|
void setTitle(const QString &title) override;
|
||||||
void setSizeMin(QSize size) override;
|
void setMinimumSize(QSize size) override;
|
||||||
|
void setFixedSize(QSize size) override;
|
||||||
void setGeometry(QRect rect) override;
|
void setGeometry(QRect rect) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -39,6 +40,7 @@ private:
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam,
|
LPARAM lParam,
|
||||||
LRESULT *result);
|
LRESULT *result);
|
||||||
|
[[nodiscard]] bool fixedSize() const;
|
||||||
|
|
||||||
static not_null<NativeFilter*> GetNativeFilter();
|
static not_null<NativeFilter*> GetNativeFilter();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,19 @@ void Window::setTitle(const QString &title) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setSizeMin(QSize size) {
|
void Window::setMinimumSize(QSize size) {
|
||||||
if (_helper) {
|
if (_helper) {
|
||||||
_helper->setSizeMin(size);
|
_helper->setMinimumSize(size);
|
||||||
} else {
|
} else {
|
||||||
setMinimumSize(size);
|
RpWidget::setMinimumSize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setFixedSize(QSize size) {
|
||||||
|
if (_helper) {
|
||||||
|
_helper->setFixedSize(size);
|
||||||
|
} else {
|
||||||
|
RpWidget::setFixedSize(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ public:
|
||||||
[[nodiscard]] not_null<const RpWidget*> body() const;
|
[[nodiscard]] not_null<const RpWidget*> body() const;
|
||||||
|
|
||||||
void setTitle(const QString &title);
|
void setTitle(const QString &title);
|
||||||
void setSizeMin(QSize size);
|
void setMinimumSize(QSize size);
|
||||||
|
void setFixedSize(QSize size);
|
||||||
void setGeometry(QRect rect);
|
void setGeometry(QRect rect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue