Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (7)
......@@ -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 \
......
......@@ -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
......
......@@ -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();
......
......@@ -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
{
......
......@@ -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", "");
......
/*****************************************************************************
* Copyright (C) 2022 the VideoLAN team
*
* Authors: Prince Gupta <guptaprince8832@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();
}
/*****************************************************************************
* Copyright (C) 2022 the VideoLAN team
*
* Authors: Prince Gupta <guptaprince8832@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
......@@ -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()
}
}
}
}
......@@ -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 {
......
......@@ -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
}
}
}
}