[vlc-commits] [Git][videolan/vlc][master] 7 commits: qt: use negative margin for extending frame
François Cartegnie (@fcartegnie)
gitlab at videolan.org
Fri Dec 23 15:14:58 UTC 2022
François Cartegnie pushed to branch master at VideoLAN / VLC
Commits:
57a7bf51 by Prince Gupta at 2022-12-23T14:59:14+00:00
qt: use negative margin for extending frame
- - - - -
99ee50c5 by Prince Gupta at 2022-12-23T14:59:14+00:00
qt: implement CSDButtonModel
- - - - -
68a57d6f by Prince Gupta at 2022-12-23T14:59:14+00:00
qml: refactor CSDButtonSets to use CSDButtonModel
- - - - -
682158f3 by Prince Gupta at 2022-12-23T14:59:14+00:00
qml: add option to show CSD buttons hovered externally
- - - - -
dac28e76 by Prince Gupta at 2022-12-23T14:59:14+00:00
qml: handle CSDButton.showHovered in Window Button set
- - - - -
92588cdc by Prince Gupta at 2022-12-23T14:59:14+00:00
qml: send rect changes for window csd button set
- - - - -
a0e968bb by Prince Gupta at 2022-12-23T14:59:14+00:00
qt: show snap layouts menu on windows 11 with CSD
- - - - -
10 changed files:
- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainctx.cpp
- modules/gui/qt/maininterface/mainctx.hpp
- modules/gui/qt/maininterface/mainctx_win32.cpp
- modules/gui/qt/maininterface/mainui.cpp
- + modules/gui/qt/util/csdbuttonmodel.cpp
- + modules/gui/qt/util/csdbuttonmodel.hpp
- modules/gui/qt/widgets/qml/CSDThemeButtonSet.qml
- modules/gui/qt/widgets/qml/CSDWindowButton.qml
- modules/gui/qt/widgets/qml/CSDWindowButtonSet.qml
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -277,6 +277,7 @@ libqt_plugin_la_SOURCES = \
gui/qt/util/covergenerator.cpp \
gui/qt/util/covergenerator.hpp \
gui/qt/util/imageluminanceextractor.cpp gui/qt/util/imageluminanceextractor.hpp \
+ gui/qt/util/csdbuttonmodel.cpp gui/qt/util/csdbuttonmodel.hpp \
gui/qt/util/imagehelper.cpp gui/qt/util/imagehelper.hpp \
gui/qt/util/i18n.cpp gui/qt/util/i18n.hpp \
gui/qt/util/keyhelper.cpp gui/qt/util/keyhelper.hpp \
@@ -477,6 +478,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/util/color_scheme_model.moc.cpp \
gui/qt/util/color_svg_image_provider.moc.cpp \
gui/qt/util/imageluminanceextractor.moc.cpp \
+ gui/qt/util/csdbuttonmodel.moc.cpp \
gui/qt/util/i18n.moc.cpp \
gui/qt/util/keyhelper.moc.cpp \
gui/qt/util/navigation_history.moc.cpp \
=====================================
modules/gui/qt/maininterface/mainctx.cpp
=====================================
@@ -31,6 +31,7 @@
#include "maininterface/mainctx.hpp"
#include "compositor.hpp"
#include "util/renderer_manager.hpp"
+#include "util/csdbuttonmodel.hpp"
#include "widgets/native/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget
#include "util/qt_dirs.hpp" // toNativeSeparators
@@ -47,6 +48,7 @@
#include "dialogs/toolbar/controlbar_profile_model.hpp"
+
#include <QKeyEvent>
#include <QUrl>
@@ -104,6 +106,7 @@ bool loadVLCOption<bool>(vlc_object_t *obj, const char *name)
MainCtx::MainCtx(qt_intf_t *_p_intf)
: p_intf(_p_intf)
+ , m_csdButtonModel {std::make_unique<CSDButtonModel>(this, this)}
{
/**
* Configuration and settings
=====================================
modules/gui/qt/maininterface/mainctx.hpp
=====================================
@@ -42,6 +42,7 @@
#include <atomic>
+class CSDButtonModel;
class QSettings;
class QCloseEvent;
class QKeyEvent;
@@ -142,6 +143,7 @@ public:
};
+
class MainCtx : public QObject
{
Q_OBJECT
@@ -176,6 +178,8 @@ class MainCtx : public QObject
Q_PROPERTY(bool useGlobalShortcuts READ getUseGlobalShortcuts WRITE setUseGlobalShortcuts NOTIFY useGlobalShortcutsChanged FINAL)
Q_PROPERTY(int maxVolume READ maxVolume NOTIFY maxVolumeChanged FINAL)
+ Q_PROPERTY(CSDButtonModel *csdButtonModel READ csdButtonModel CONSTANT FINAL)
+
// This Property only works if hasAcrylicSurface is set
Q_PROPERTY(bool acrylicActive READ acrylicActive WRITE setAcrylicActive NOTIFY acrylicActiveChanged FINAL)
@@ -290,6 +294,8 @@ public:
Q_INVOKABLE static void setAttachedToolTip(QObject* toolTip);
+ CSDButtonModel *csdButtonModel() { return m_csdButtonModel.get(); }
+
protected:
/* Systray */
void createSystray();
@@ -360,6 +366,8 @@ protected:
int m_maxVolume = 125;
+ std::unique_ptr<CSDButtonModel> m_csdButtonModel;
+
public slots:
void toggleUpdateSystrayMenu();
void showUpdateSystrayMenu();
=====================================
modules/gui/qt/maininterface/mainctx_win32.cpp
=====================================
@@ -32,6 +32,7 @@
#include "playlist/playlist_controller.hpp"
#include "dialogs/dialogs_provider.hpp"
#include "widgets/native/interface_widgets.hpp"
+#include "util/csdbuttonmodel.hpp"
#include <QBitmap>
@@ -83,6 +84,13 @@
#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam))
#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam)
+
+// XXX: Cygwin (at least) doesn't define these macros. Too bad...
+#ifndef GET_X_LPARAM
+ #define GET_X_LPARAM(a) ((int16_t)(a))
+ #define GET_Y_LPARAM(a) ((int16_t)((a)>>16))
+#endif
+
using namespace vlc::playlist;
#ifndef WM_NCUAHDRAWCAPTION
@@ -109,10 +117,11 @@ HWND WinId( QWindow *windowHandle )
class CSDWin32EventHandler : public QObject, public QAbstractNativeEventFilter
{
public:
- CSDWin32EventHandler(const bool useClientSideDecoration, const bool isWin7Compositor, QWindow *window, QObject *parent)
+ CSDWin32EventHandler(const bool useClientSideDecoration, const bool isWin7Compositor, QWindow *window, CSDButtonModel *buttonmodel, QObject *parent)
: QObject {parent}
, m_useClientSideDecoration {useClientSideDecoration}
, m_window {window}
+ , m_buttonmodel {buttonmodel}
, m_isWin7Compositor {isWin7Compositor}
{
QApplication::instance()->installNativeEventFilter(this);
@@ -194,6 +203,90 @@ public:
return true;
}
+ // send to determine on what part of UI is mouse ON
+ // handle it to relay if mouse is on the CSD buttons
+ // required for snap layouts menu (WINDOWS 11)
+ if ( msg->message == WM_NCHITTEST )
+ {
+ setAllUnhovered();
+
+ // Get the point in screen coordinates.
+ POINT point = { GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam) };
+
+ // Map the point to client coordinates.
+ ::MapWindowPoints(nullptr, msg->hwnd, &point, 1);
+
+ const QPoint qtPoint {point.x, point.y};
+ auto button = overlappingButton(qtPoint);
+ if (!button)
+ return false;
+
+ switch (button->type())
+ {
+ case CSDButton::Close:
+ *result = HTCLOSE;
+ return true;
+ case CSDButton::Minimize:
+ *result = HTMINBUTTON;
+ return true;
+ case CSDButton::MaximizeRestore:
+ *result = HTMAXBUTTON;
+ return true;
+ default:
+ vlc_assert_unreachable();
+ return false;
+ }
+ }
+
+ if ( msg->message == WM_NCMOUSEMOVE )
+ {
+
+ // when we handle WM_NCHITTEST, that makes the OS to capture the mouse events
+ // and WM_NCMOUSEMOVE is sent in this case, manually handle them here and relay
+ // to UI to draw correct button state
+ switch ( msg->wParam )
+ {
+ case HTCLOSE:
+ setHovered(CSDButton::Close);
+ break;
+ case HTMINBUTTON:
+ setHovered(CSDButton::Minimize);
+ break;
+ case HTMAXBUTTON:
+ setHovered(CSDButton::MaximizeRestore);
+ break;
+ }
+
+ // If we haven't previously asked for mouse tracking, request mouse
+ // tracking. We need to do this so we can get the WM_NCMOUSELEAVE
+ // message when the mouse leave the titlebar. Otherwise, we won't always
+ // get that message (especially if the user moves the mouse _real
+ // fast_).
+ const bool onSystemButton = (msg->wParam == HTCLOSE || msg->wParam == HTMINBUTTON || msg->wParam == HTMAXBUTTON);
+ if (!m_trackingMouse && onSystemButton)
+ {
+ TRACKMOUSEEVENT ev{};
+ ev.cbSize = sizeof(TRACKMOUSEEVENT);
+ // TME_NONCLIENT is absolutely critical here. In my experimentation,
+ // we'd get WM_MOUSELEAVE messages after just a HOVER_DEFAULT
+ // timeout even though we're not requesting TME_HOVER, which kinda
+ // ruined the whole point of this.
+ ev.dwFlags = TME_LEAVE | TME_NONCLIENT;
+ ev.hwndTrack = msg->hwnd;
+ ev.dwHoverTime = HOVER_DEFAULT; // we don't _really_ care about this.
+ TrackMouseEvent(&ev); // TODO check return?
+ m_trackingMouse = true;
+ }
+ }
+
+ if ( msg->message == WM_NCMOUSELEAVE || msg->message == WM_MOUSELEAVE )
+ {
+ m_trackingMouse = false;
+
+ // release all buttons we may have captured
+ setAllUnhovered();
+ }
+
return false;
}
@@ -228,7 +321,9 @@ private:
}
// add back shadows
- const MARGINS m {0, 0, (m_useClientSideDecoration ? 1 : 0) /* top margin */ , 0};
+ // with positive margins, snap layouts menu (windows 11) won't appear
+ const int margin = (m_useClientSideDecoration ? - 1 : 0);
+ const MARGINS m {margin, margin, margin, margin};
DwmExtendFrameIntoClientArea(winId, &m);
SetWindowPos(winId, NULL, 0, 0, 0, 0,
@@ -237,9 +332,41 @@ private:
SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
}
+ CSDButton *overlappingButton(const QPoint point)
+ {
+ for (auto button : m_buttonmodel->windowCSDButtons())
+ {
+ if (button->rect().contains(point))
+ return button;
+ }
+ return nullptr;
+ }
+
+ void setHovered(CSDButton::ButtonType type)
+ {
+ for (auto button : m_buttonmodel->windowCSDButtons()) {
+ if (button->type() == type) {
+ button->setShowHovered(true);
+ return ;
+ }
+ }
+
+ vlc_assert_unreachable();
+ }
+
+ void setAllUnhovered()
+ {
+ for (auto button : m_buttonmodel->windowCSDButtons())
+ {
+ button->setShowHovered(false);
+ }
+ }
+
DWORD m_nonCSDGwlStyle = 0;
bool m_useClientSideDecoration;
QWindow *m_window;
+ CSDButtonModel *m_buttonmodel;
+ bool m_trackingMouse = false;
const bool m_isWin7Compositor;
};
@@ -511,7 +638,7 @@ InterfaceWindowHandlerWin32::InterfaceWindowHandlerWin32(qt_intf_t *_p_intf, Mai
#if QT_CLIENT_SIDE_DECORATION_AVAILABLE
, m_CSDWindowEventHandler(new CSDWin32EventHandler(mainCtx->useClientSideDecoration(),
_p_intf->p_compositor->type() == vlc::Compositor::Win7Compositor,
- window, window))
+ window, mainCtx->csdButtonModel(), window))
#endif
{
=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -44,6 +44,7 @@
#include "util/flickable_scroll_handler.hpp"
#include "util/color_svg_image_provider.hpp"
#include "util/effects_image_provider.hpp"
+#include "util/csdbuttonmodel.hpp"
#include "dialogs/help/aboutmodel.hpp"
#include "dialogs/dialogs_provider.hpp"
@@ -225,6 +226,7 @@ void MainUI::registerQMLTypes()
const int versionMinor = 1;
qmlRegisterSingletonType<MainCtx>(uri, versionMajor, versionMinor, "MainCtx", SingletonRegisterHelper<MainCtx>::callback);
+
qmlRegisterSingletonType<NavigationHistory>(uri, versionMajor, versionMinor, "History", SingletonRegisterHelper<NavigationHistory>::callback);
qmlRegisterSingletonType<PlayerController>(uri, versionMajor, versionMinor, "Player", SingletonRegisterHelper<PlayerController>::callback);
qmlRegisterSingletonType<I18n>(uri, versionMajor, versionMinor, "I18n", SingletonRegisterHelper<I18n>::callback);
@@ -265,6 +267,9 @@ void MainUI::registerQMLTypes()
qmlRegisterUncreatableType<ProgramListModel>(uri, versionMajor, versionMinor, "ProgramListModel", "available programs of a media" );
qmlRegisterUncreatableType<VLCVarChoiceModel>(uri, versionMajor, versionMinor, "VLCVarChoiceModel", "generic variable with choice model" );
+ qmlRegisterUncreatableType<CSDButton>(uri, versionMajor, versionMinor, "CSDButton", "");
+ qmlRegisterUncreatableType<CSDButtonModel>(uri, versionMajor, versionMinor, "CSDButtonModel", "has CSD buttons and provides for communicating CSD events between UI and backend");
+
qRegisterMetaType<PlaylistPtr>();
qRegisterMetaType<PlaylistItem>();
qmlRegisterUncreatableType<PlaylistItem>(uri, versionMajor, versionMinor, "PlaylistItem", "");
=====================================
modules/gui/qt/util/csdbuttonmodel.cpp
=====================================
@@ -0,0 +1,108 @@
+/*****************************************************************************
+ * Copyright (C) 2022 the VideoLAN team
+ *
+ * Authors: Prince Gupta <guptaprince8832 at gmail.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 Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+
+#include "csdbuttonmodel.hpp"
+
+#include "maininterface/mainctx.hpp"
+
+#include <QWindow>
+
+CSDButton::CSDButton(ButtonType type, QObject *parent)
+ : QObject {parent}
+ , m_type {type}
+{
+}
+
+bool CSDButton::showHovered() const
+{
+ return m_showHovered;
+}
+
+void CSDButton::setShowHovered(bool newShowHovered)
+{
+ if (m_showHovered == newShowHovered)
+ return;
+ m_showHovered = newShowHovered;
+ emit showHoveredChanged();
+}
+
+CSDButton::ButtonType CSDButton::type() const
+{
+ return m_type;
+}
+
+const QRect &CSDButton::rect() const
+{
+ return m_rect;
+}
+
+void CSDButton::setRect(const QRect &newRect)
+{
+ if (m_rect == newRect)
+ return;
+ m_rect = newRect;
+ emit rectChanged();
+}
+
+void CSDButton::click()
+{
+ emit clicked();
+}
+
+CSDButtonModel::CSDButtonModel(MainCtx *mainCtx, QObject *parent)
+ : QObject {parent}
+ , m_mainCtx {mainCtx}
+{
+ auto newButton = [this](CSDButton::ButtonType type, void (CSDButtonModel::* onClick)())
+ {
+ auto button = new CSDButton(type, this);
+ connect(button, &CSDButton::clicked, this, onClick);
+ m_windowCSDButtons.append(button);
+ };
+
+ newButton(CSDButton::Minimize, &CSDButtonModel::minimizeButtonClicked);
+ newButton(CSDButton::MaximizeRestore, &CSDButtonModel::maximizeRestoreButtonClicked);
+ newButton(CSDButton::Close, &CSDButtonModel::closeButtonClicked);
+}
+
+QList<CSDButton *> CSDButtonModel::windowCSDButtons() const
+{
+ return m_windowCSDButtons;
+}
+
+void CSDButtonModel::minimizeButtonClicked()
+{
+ emit m_mainCtx->requestInterfaceMinimized();
+}
+
+void CSDButtonModel::maximizeRestoreButtonClicked()
+{
+ const auto visibility = m_mainCtx->intfMainWindow()->visibility();
+ if (visibility == QWindow::Maximized)
+ emit m_mainCtx->requestInterfaceNormal();
+ else
+ emit m_mainCtx->requestInterfaceMaximized();
+}
+
+void CSDButtonModel::closeButtonClicked()
+{
+ m_mainCtx->intfMainWindow()->close();
+}
=====================================
modules/gui/qt/util/csdbuttonmodel.hpp
=====================================
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * Copyright (C) 2022 the VideoLAN team
+ *
+ * Authors: Prince Gupta <guptaprince8832 at gmail.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 Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef CSDBUTTONCONTROLLER_HPP
+#define CSDBUTTONCONTROLLER_HPP
+
+#include <QObject>
+#include <QRect>
+
+class CSDButton : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(ButtonType type READ type CONSTANT)
+ Q_PROPERTY(bool showHovered READ showHovered WRITE setShowHovered NOTIFY showHoveredChanged)
+ Q_PROPERTY(QRect rect READ rect WRITE setRect NOTIFY rectChanged)
+
+public:
+ enum ButtonType
+ {
+ Minimize,
+ MaximizeRestore,
+ Close,
+
+ TypeCount
+ };
+
+ Q_ENUM(ButtonType);
+
+ CSDButton(ButtonType type, QObject *parent);
+
+ ButtonType type() const;
+
+ // 'showHovered' is hint for UI to the show this
+ // button as in 'hovered' state
+ // used by implmentation incase custom event handling is required for CSD
+ bool showHovered() const;
+ void setShowHovered(bool newShowHovered);
+
+ // 'rect' is location of the button in the UI
+ // may be used by implementation to relay the information
+ // to OS such as to show snaplay out menu on Windows 11
+ const QRect &rect() const;
+ void setRect(const QRect &newRect);
+
+public slots:
+ // signals to perfrom action associated with button
+ void click();
+
+signals:
+ void showHoveredChanged();
+ void rectChanged();
+ void clicked();
+
+private:
+ const ButtonType m_type;
+ bool m_showHovered = false;
+ QRect m_rect;
+};
+
+
+class MainCtx;
+
+class CSDButtonModel : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QList<CSDButton *> windowCSDButtons READ windowCSDButtons CONSTANT)
+
+public:
+ CSDButtonModel(MainCtx *mainCtx, QObject *parent = nullptr);
+
+ QList<CSDButton *> windowCSDButtons() const;
+
+private slots:
+ void minimizeButtonClicked();
+ void maximizeRestoreButtonClicked();
+ void closeButtonClicked();
+
+private:
+ MainCtx *m_mainCtx;
+ QList<CSDButton *> m_windowCSDButtons;
+};
+
+
+Q_DECLARE_METATYPE(CSDButton *)
+
+#endif // CSDBUTTONCONTROLLER_HPP
=====================================
modules/gui/qt/widgets/qml/CSDThemeButtonSet.qml
=====================================
@@ -46,47 +46,34 @@ Rectangle {
spacing: root._interNavButtonSpacing
- CSDThemeButton {
- id: minimizeButton
+ Repeater {
+ model: MainCtx.csdButtonModel.windowCSDButtons
- anchors.verticalCenter: parent.verticalCenter
+ CSDThemeButton {
- bannerHeight: root.height
+ anchors.verticalCenter: parent.verticalCenter
- buttonType: CSDThemeImage.MINIMIZE
+ bannerHeight: root.height
- onClicked: MainCtx.requestInterfaceMinimized()
- }
-
- CSDThemeButton {
- id: maximizeButton
-
- anchors.verticalCenter: parent.verticalCenter
+ buttonType: {
+ switch (modelData.type) {
+ case CSDButton.Minimize:
+ return CSDThemeImage.MINIMIZE
- bannerHeight: root.height
+ case CSDButton.MaximizeRestore:
+ return (MainCtx.intfMainWindow.visibility === Window.Maximized)
+ ? CSDThemeImage.RESTORE
+ : CSDThemeImage.MAXIMIZE
- buttonType: (MainCtx.intfMainWindow.visibility === Window.Maximized) ? CSDThemeImage.RESTORE : CSDThemeImage.MAXIMIZE
+ case CSDButton.Close:
+ return CSDThemeButton.CLOSE
+ }
- onClicked: {
- if (MainCtx.intfMainWindow.visibility === Window.Maximized) {
- MainCtx.requestInterfaceNormal()
- } else {
- MainCtx.requestInterfaceMaximized()
+ console.assert(false, "unreachable")
}
- }
- }
-
- CSDThemeButton {
- id: closeButton
- anchors.verticalCenter: parent.verticalCenter
-
- bannerHeight: root.height
-
- buttonType: CSDThemeImage.CLOSE
-
- onClicked: MainCtx.intfMainWindow.close()
+ onClicked: modelData.click()
+ }
}
}
-
}
=====================================
modules/gui/qt/widgets/qml/CSDWindowButton.qml
=====================================
@@ -29,6 +29,9 @@ T.Button {
property color color: VLCStyle.colors.text
property color hoverColor: VLCStyle.colors.windowCSDButtonBg
property string iconTxt: ""
+ property bool showHovered: false
+
+ readonly property bool _paintHovered: control.hovered || showHovered
padding: 0
width: VLCStyle.dp(40, VLCStyle.scale)
@@ -39,11 +42,16 @@ T.Button {
background: Rectangle {
height: control.height
width: control.width
- color: !control.hovered ? "transparent"
- : control.pressed ? (VLCStyle.colors.isThemeDark ? Qt.lighter(control.hoverColor, 1.2)
- : Qt.darker(control.hoverColor, 1.2)
- )
- : control.hoverColor
+ color: {
+ if (control._paintHovered)
+ return control.hoverColor
+
+ if (control.pressed)
+ return VLCStyle.colors.isThemeDark ? Qt.lighter(control.hoverColor, 1.2)
+ : Qt.darker(control.hoverColor, 1.2)
+
+ return "transparent"
+ }
}
contentItem: Item {
=====================================
modules/gui/qt/widgets/qml/CSDWindowButtonSet.qml
=====================================
@@ -33,38 +33,69 @@ Row {
property color color: VLCStyle.colors.text
property color hoverColor: VLCStyle.colors.windowCSDButtonBg
- property bool hovered: minimizeButton.hovered || maximizeButton.hovered || closeButton.hovered
-
- CSDWindowButton {
- id: minimizeButton
- iconTxt: VLCIcons.window_minimize
- onClicked: MainCtx.requestInterfaceMinimized()
- height: windowButtonGroup.height
- color: windowButtonGroup.color
- hoverColor: windowButtonGroup.hoverColor
+ readonly property bool hovered: {
+ var h = false
+ for (var i = 0; i < repeater.count; ++i) {
+ var button = repeater.itemAt(i)
+ h = h || button.hovered || button.showHovered
+ }
+
+ return h
}
- CSDWindowButton {
- id: maximizeButton
- iconTxt: (MainCtx.intfMainWindow.visibility === Window.Maximized) ? VLCIcons.window_restore :VLCIcons.window_maximize
- onClicked: {
- if (MainCtx.intfMainWindow.visibility === Window.Maximized) {
- MainCtx.requestInterfaceNormal()
- } else {
- MainCtx.requestInterfaceMaximized()
+ Repeater {
+ id: repeater
+
+ model: MainCtx.csdButtonModel.windowCSDButtons
+
+ CSDWindowButton {
+ height: windowButtonGroup.height
+
+ showHovered: modelData.showHovered
+
+ color: (modelData.type === CSDButton.Close && (hovered || modelData.showHovered))
+ ? "white"
+ : windowButtonGroup.color
+
+ hoverColor: (modelData.type === CSDButton.Close) ? "red" : windowButtonGroup.hoverColor
+
+ iconTxt: {
+ switch (modelData.type) {
+ case CSDButton.Minimize:
+ return VLCIcons.window_minimize
+
+ case CSDButton.MaximizeRestore:
+ return (MainCtx.intfMainWindow.visibility === Window.Maximized)
+ ? VLCIcons.window_restore
+ : VLCIcons.window_maximize
+
+ case CSDButton.Close:
+ return VLCIcons.window_close
+ }
+
+ console.assert(false, "unreachable")
}
- }
- height: windowButtonGroup.height
- color: windowButtonGroup.color
- hoverColor: windowButtonGroup.hoverColor
- }
- CSDWindowButton {
- id: closeButton
- iconTxt: VLCIcons.window_close
- onClicked: MainCtx.intfMainWindow.close()
- height: windowButtonGroup.height
- color: closeButton.hovered ? "white" : windowButtonGroup.color
- hoverColor: "red"
+ onClicked: modelData.click()
+
+ // handles VLCStyle.scale changes
+ onWidthChanged: Qt.callLater(updateRect)
+ onHeightChanged: Qt.callLater(updateRect)
+
+ Connections {
+ target: VLCStyle.self
+
+ // handle window resize
+ onAppWidthChanged: Qt.callLater(updateRect)
+ onAppHeightChanged: Qt.callLater(updateRect)
+ }
+
+ function updateRect() {
+ var point = mapToItem(null, 0, 0)
+ var rect = Qt.rect(point.x, point.y, width, height)
+
+ modelData.rect = rect
+ }
+ }
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/16e913456ee1075b2b819d7951892b1e3f3f980b...a0e968bb8918df985ed45ddfde84c58c1bd68a33
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/16e913456ee1075b2b819d7951892b1e3f3f980b...a0e968bb8918df985ed45ddfde84c58c1bd68a33
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list