[vlc-commits] [Git][videolan/vlc][master] 3 commits: macosx: Redesign Home buttons

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Thu Oct 15 07:30:48 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
8e03a7af by Claudio Cambra at 2026-10-15T09:15:58+02:00
macosx: Redesign Home buttons

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
fbe19bc3 by Claudio Cambra at 2026-10-15T09:15:58+02:00
macosx: Redesign the Home actions view as a drop area

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
ff10c6cf by Claudio Cambra at 2026-10-15T09:15:58+02:00
macosx: Fix home view actions view XIB build on monterey

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -


10 changed files:

- modules/gui/macosx/UI/VLCLibraryHomeViewActionsView.xib
- modules/gui/macosx/extensions/NSColor+VLCAdditions.h
- modules/gui/macosx/extensions/NSColor+VLCAdditions.m
- modules/gui/macosx/extensions/NSFont+VLCAdditions.h
- modules/gui/macosx/extensions/NSFont+VLCAdditions.m
- modules/gui/macosx/library/home-library/VLCLibraryHomeViewActionButtonCell.m
- modules/gui/macosx/library/home-library/VLCLibraryHomeViewActionsView.h
- modules/gui/macosx/library/home-library/VLCLibraryHomeViewActionsView.m
- modules/gui/macosx/views/VLCUIUnits.h
- modules/gui/macosx/views/VLCUIUnits.m


Changes:

=====================================
modules/gui/macosx/UI/VLCLibraryHomeViewActionsView.xib
=====================================
@@ -1,113 +1,204 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
-        <capability name="Image references" minToolsVersion="12.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504" />
+        <capability name="Image references" minToolsVersion="12.0" />
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0" />
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner"/>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <stackView distribution="fillEqually" orientation="horizontal" alignment="centerY" spacing="8" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="250" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3qj-hs-qA9" customClass="VLCLibraryHomeViewActionsView">
-            <userDefinedRuntimeAttributes>
-                <userDefinedRuntimeAttribute type="number" keyPath="spacingToken">
-                    <integer value="2"/>
-                </userDefinedRuntimeAttribute>
-            </userDefinedRuntimeAttributes>
-            <rect key="frame" x="0.0" y="0.0" width="801" height="128"/>
+        <customObject id="-2" userLabel="File's Owner" />
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder" />
+        <customObject id="-3" userLabel="Application" customClass="NSObject" />
+        <customView translatesAutoresizingMaskIntoConstraints="NO" id="3qj-hs-qA9" customClass="VLCLibraryHomeViewActionsView">
+            <rect key="frame" x="0" y="0" width="900" height="152" />
             <subviews>
-                <button verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="z8M-pF-aNN">
-                    <rect key="frame" x="0.0" y="0.0" width="152" height="128"/>
-                    <buttonCell key="cell" type="inline" title="Open file" bezelStyle="inline" image="internaldrive.fill" catalog="system" imagePosition="above" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="BaI-vV-jQU" customClass="VLCLibraryHomeViewActionButtonCell">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="smallSystemBold"/>
-                    </buttonCell>
+                <stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="16" horizontalStackHuggingPriority="249" verticalStackHuggingPriority="750" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="int-ro-001" customClass="VLCStackView">
+                    <rect key="frame" x="24" y="30" width="384" height="92" />
+                    <subviews>
+                        <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="log-ov-001" customClass="VLCDropDisabledImageView">
+                            <rect key="frame" x="0" y="14" width="64" height="64" />
+                            <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" id="log-oc-001" />
+                            <constraints>
+                                <constraint id="log-os-001" firstAttribute="height" secondItem="log-ov-001" secondAttribute="width" />
+                            </constraints>
+                        </imageView>
+                        <stackView distribution="fill" orientation="vertical" alignment="leading" spacing="4" horizontalStackHuggingPriority="249" verticalStackHuggingPriority="750" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="txt-st-001" customClass="VLCStackView">
+                            <rect key="frame" x="80" y="0" width="304" height="92" />
+                            <subviews>
+                                <textField focusRingType="none" horizontalHuggingPriority="249" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="txt-ti-001">
+                                    <rect key="frame" x="0" y="64" width="304" height="28" />
+                                    <textFieldCell key="cell" lineBreakMode="wordWrapping" title="Drop anything here" id="txt-ti-cel">
+                                        <font key="font" metaFont="systemBold" />
+                                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog" />
+                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog" />
+                                    </textFieldCell>
+                                </textField>
+                                <textField focusRingType="none" horizontalHuggingPriority="249" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="txt-de-001">
+                                    <rect key="frame" x="0" y="40" width="304" height="20" />
+                                    <textFieldCell key="cell" lineBreakMode="wordWrapping" title="Files, folders, discs and links." id="txt-de-cel">
+                                        <font key="font" metaFont="system" />
+                                        <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog" />
+                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog" />
+                                    </textFieldCell>
+                                </textField>
+                                <textField focusRingType="none" horizontalHuggingPriority="249" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="txt-hi-001">
+                                    <rect key="frame" x="0" y="16" width="304" height="20" />
+                                    <textFieldCell key="cell" lineBreakMode="wordWrapping" title="Any format, any codec, no questions asked." id="txt-hi-cel">
+                                        <font key="font" metaFont="system" />
+                                        <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog" />
+                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog" />
+                                    </textFieldCell>
+                                </textField>
+                            </subviews>
+                            <constraints>
+                                <constraint firstItem="txt-ti-001" firstAttribute="top" secondItem="txt-st-001" secondAttribute="top" id="txt-tp-001" />
+                                <constraint firstAttribute="bottom" secondItem="txt-hi-001" secondAttribute="bottom" id="txt-bt-001" />
+                                <constraint id="txt-wd-000" firstItem="txt-ti-001" firstAttribute="width" secondItem="txt-st-001" secondAttribute="width" />
+                                <constraint id="txt-wd-001" firstItem="txt-de-001" firstAttribute="width" secondItem="txt-st-001" secondAttribute="width" />
+                                <constraint id="txt-wd-002" firstItem="txt-hi-001" firstAttribute="width" secondItem="txt-st-001" secondAttribute="width" />
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="spacingToken">
+                                    <integer key="value" value="1" />
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <visibilityPriorities>
+                                <integer value="1000" />
+                                <integer value="1000" />
+                                <integer value="1000" />
+                            </visibilityPriorities>
+                            <customSpacing>
+                                <real value="3.4028234663852886e+38" />
+                                <real value="3.4028234663852886e+38" />
+                                <real value="3.4028234663852886e+38" />
+                            </customSpacing>
+                        </stackView>
+                    </subviews>
                     <constraints>
-                        <constraint firstAttribute="height" constant="128" id="8rS-SD-guH"/>
+                        </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="spacingToken">
+                            <integer key="value" value="3" />
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <visibilityPriorities>
+                        <integer value="1000" />
+                        <integer value="1000" />
+                    </visibilityPriorities>
+                    <customSpacing>
+                        <real value="3.4028234663852886e+38" />
+                        <real value="3.4028234663852886e+38" />
+                    </customSpacing>
+                </stackView>
+                <stackView distribution="fillEqually" orientation="vertical" alignment="leading" spacing="8" horizontalStackHuggingPriority="249" verticalStackHuggingPriority="750" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="act-gr-001" customClass="VLCStackView">
+                    <rect key="frame" x="432" y="16" width="444" height="120" />
+                    <subviews>
+                        <stackView distribution="fillEqually" orientation="horizontal" alignment="centerY" spacing="0" horizontalStackHuggingPriority="249" verticalStackHuggingPriority="750" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="act-ro-001">
+                            <rect key="frame" x="0" y="64" width="444" height="56" />
+                            <subviews>
+                                <button verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="z8M-pF-aNN" verticalCompressionResistancePriority="1000">
+                                    <rect key="frame" x="0" y="0" width="216" height="56" />
+                                    <buttonCell key="cell" type="inline" title="Open file" bezelStyle="inline" image="doc" catalog="system" imagePosition="leading" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="BaI-vV-jQU" customClass="VLCLibraryHomeViewActionButtonCell">
+                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" />
+                                        <font key="font" metaFont="smallSystemBold" />
+                                    </buttonCell>
+                                    <connections>
+                                        <action selector="openFileAction:" target="3qj-hs-qA9" id="WNK-Gq-vbI" />
+                                    </connections>
+                                </button>
+                                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cJy-ck-xd6" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000">
+                                    <rect key="frame" x="228" y="0" width="216" height="56" />
+                                    <buttonCell key="cell" type="inline" title="Open disc" bezelStyle="inline" imagePosition="leading" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="92c-b8-kwg" customClass="VLCLibraryHomeViewActionButtonCell">
+                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" />
+                                        <font key="font" metaFont="smallSystemBold" />
+                                        <imageReference key="image" image="opticaldisc" catalog="system" symbolScale="default" />
+                                    </buttonCell>
+                                    <connections>
+                                        <action selector="openDiscAction:" target="3qj-hs-qA9" id="J6M-0U-hKB" />
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <visibilityPriorities>
+                                <integer value="1000" />
+                                <integer value="1000" />
+                            </visibilityPriorities>
+                            <customSpacing>
+                                <real value="3.4028234663852886e+38" />
+                                <real value="3.4028234663852886e+38" />
+                            </customSpacing>
+                        </stackView>
+                        <stackView distribution="fillEqually" orientation="horizontal" alignment="centerY" spacing="0" horizontalStackHuggingPriority="249" verticalStackHuggingPriority="750" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="act-ro-002">
+                            <rect key="frame" x="0" y="0" width="444" height="56" />
+                            <subviews>
+                                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="j8l-xq-Zuw" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000">
+                                    <rect key="frame" x="0" y="0" width="216" height="56" />
+                                    <buttonCell key="cell" type="inline" title="Open Stream" bezelStyle="inline" image="network" catalog="system" imagePosition="leading" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="2Vn-hv-Uao" customClass="VLCLibraryHomeViewActionButtonCell">
+                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" />
+                                        <font key="font" metaFont="smallSystemBold" />
+                                    </buttonCell>
+                                    <connections>
+                                        <action selector="openUrlAction:" target="3qj-hs-qA9" id="hON-OU-Kvy" />
+                                    </connections>
+                                </button>
+                                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="y5B-QJ-eG5" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="1000">
+                                    <rect key="frame" x="228" y="0" width="216" height="56" />
+                                    <buttonCell key="cell" type="inline" title="Open capture device" bezelStyle="inline" image="camera.fill" catalog="system" imagePosition="leading" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="6uQ-ex-ony" customClass="VLCLibraryHomeViewActionButtonCell">
+                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" />
+                                        <font key="font" metaFont="smallSystemBold" />
+                                    </buttonCell>
+                                    <connections>
+                                        <action selector="openCaptureDeviceAction:" target="3qj-hs-qA9" id="wNJ-8K-1tJ" />
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <visibilityPriorities>
+                                <integer value="1000" />
+                                <integer value="1000" />
+                            </visibilityPriorities>
+                            <customSpacing>
+                                <real value="3.4028234663852886e+38" />
+                                <real value="3.4028234663852886e+38" />
+                            </customSpacing>
+                        </stackView>
+                    </subviews>
+                    <constraints>
+                        <constraint id="act-rw-001" firstItem="act-ro-001" firstAttribute="width" secondItem="act-gr-001" secondAttribute="width" />
+                        <constraint id="act-rw-002" firstItem="act-ro-002" firstAttribute="width" secondItem="act-gr-001" secondAttribute="width" />
                     </constraints>
-                    <connections>
-                        <action selector="openFileAction:" target="3qj-hs-qA9" id="WNK-Gq-vbI"/>
-                    </connections>
-                </button>
-                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cJy-ck-xd6">
-                    <rect key="frame" x="162" y="0.0" width="152" height="128"/>
-                    <buttonCell key="cell" type="inline" title="Open disc" bezelStyle="inline" imagePosition="above" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="92c-b8-kwg" customClass="VLCLibraryHomeViewActionButtonCell">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="smallSystemBold"/>
-                        <imageReference key="image" image="opticaldisc.fill" catalog="system" symbolScale="default"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="openDiscAction:" target="3qj-hs-qA9" id="J6M-0U-hKB"/>
-                    </connections>
-                </button>
-                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="j8l-xq-Zuw">
-                    <rect key="frame" x="324" y="0.0" width="153" height="128"/>
-                    <buttonCell key="cell" type="inline" title="Open Stream" bezelStyle="inline" image="network" catalog="system" imagePosition="above" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="2Vn-hv-Uao" customClass="VLCLibraryHomeViewActionButtonCell">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="smallSystemBold"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="openUrlAction:" target="3qj-hs-qA9" id="hON-OU-Kvy"/>
-                    </connections>
-                </button>
-                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="y5B-QJ-eG5">
-                    <rect key="frame" x="487" y="0.0" width="152" height="128"/>
-                    <buttonCell key="cell" type="inline" title="Open capture device" bezelStyle="inline" image="camera.fill" catalog="system" imagePosition="above" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="6uQ-ex-ony" customClass="VLCLibraryHomeViewActionButtonCell">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="smallSystemBold"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="openCaptureDeviceAction:" target="3qj-hs-qA9" id="wNJ-8K-1tJ"/>
-                    </connections>
-                </button>
-                <button verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="g9j-oN-Lyd">
-                    <rect key="frame" x="649" y="0.0" width="152" height="128"/>
-                    <buttonCell key="cell" type="inline" title="Browse" bezelStyle="inline" image="folder.fill" catalog="system" imagePosition="above" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="0K4-If-7Qb" customClass="VLCLibraryHomeViewActionButtonCell">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="smallSystem"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="openBrowseAction:" target="3qj-hs-qA9" id="T8n-Bm-2ni"/>
-                    </connections>
-                </button>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="spacingToken">
+                            <integer key="value" value="2" />
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <visibilityPriorities>
+                        <integer value="1000" />
+                        <integer value="1000" />
+                    </visibilityPriorities>
+                    <customSpacing>
+                        <real value="3.4028234663852886e+38" />
+                        <real value="3.4028234663852886e+38" />
+                    </customSpacing>
+                </stackView>
             </subviews>
-            <constraints>
-                <constraint firstItem="cJy-ck-xd6" firstAttribute="height" secondItem="z8M-pF-aNN" secondAttribute="height" id="Aji-3k-gXf"/>
-                <constraint firstItem="g9j-oN-Lyd" firstAttribute="height" secondItem="z8M-pF-aNN" secondAttribute="height" id="CzX-vh-F4u"/>
-                <constraint firstItem="y5B-QJ-eG5" firstAttribute="height" secondItem="z8M-pF-aNN" secondAttribute="height" id="HAT-ug-Hw2"/>
-                <constraint firstItem="j8l-xq-Zuw" firstAttribute="height" secondItem="z8M-pF-aNN" secondAttribute="height" id="LhC-o6-IfS"/>
-                <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="q8R-0R-ebR"/>
-            </constraints>
-            <visibilityPriorities>
-                <integer value="1000"/>
-                <integer value="1000"/>
-                <integer value="1000"/>
-                <integer value="1000"/>
-                <integer value="1000"/>
-            </visibilityPriorities>
-            <customSpacing>
-                <real value="3.4028234663852886e+38"/>
-                <real value="3.4028234663852886e+38"/>
-                <real value="3.4028234663852886e+38"/>
-                <real value="3.4028234663852886e+38"/>
-                <real value="3.4028234663852886e+38"/>
-            </customSpacing>
             <connections>
-                <outlet property="openBrowseButton" destination="g9j-oN-Lyd" id="hRd-gf-7ar"/>
-                <outlet property="openCaptureDeviceButton" destination="y5B-QJ-eG5" id="sYh-WY-Hr0"/>
-                <outlet property="openDiscButton" destination="cJy-ck-xd6" id="5Kg-qb-mAA"/>
-                <outlet property="openFileButton" destination="z8M-pF-aNN" id="B3d-7J-NQ3"/>
-                <outlet property="openUrlButton" destination="j8l-xq-Zuw" id="Hw0-VI-0vH"/>
+                <outlet property="logoImageView" destination="log-ov-001" id="out-co-000" />
+                <outlet property="dropTitleTextField" destination="txt-ti-001" id="out-co-001" />
+                <outlet property="dropDetailTextField" destination="txt-de-001" id="out-co-002" />
+                <outlet property="dropHintTextField" destination="txt-hi-001" id="out-co-003" />
+                <outlet property="openFileButton" destination="z8M-pF-aNN" id="out-co-004" />
+                <outlet property="openDiscButton" destination="cJy-ck-xd6" id="out-co-005" />
+                <outlet property="openUrlButton" destination="j8l-xq-Zuw" id="out-co-006" />
+                <outlet property="openCaptureDeviceButton" destination="y5B-QJ-eG5" id="out-co-007" />
+                <outlet property="introductionStackView" destination="int-ro-001" id="out-st-001" />
+                <outlet property="actionGridStackView" destination="act-gr-001" id="out-st-002" />
             </connections>
-            <point key="canvasLocation" x="28.5" y="-120"/>
-        </stackView>
+            <point key="canvasLocation" x="28.5" y="-120" />
+        </customView>
     </objects>
     <resources>
-        <image name="camera.fill" catalog="system" width="19" height="15"/>
-        <image name="folder.fill" catalog="system" width="18" height="14"/>
-        <image name="internaldrive.fill" catalog="system" width="18" height="13"/>
-        <image name="network" catalog="system" width="15" height="15"/>
-        <image name="opticaldisc.fill" catalog="system" width="15" height="15"/>
+        <image name="camera.fill" catalog="system" width="19" height="15" />
+        <image name="network" catalog="system" width="15" height="15" />
+        <image name="doc" catalog="system" width="14" height="17" />
+        <image name="opticaldisc" catalog="system" width="15" height="15" />
     </resources>
 </document>


=====================================
modules/gui/macosx/extensions/NSColor+VLCAdditions.h
=====================================
@@ -41,6 +41,13 @@ NS_ASSUME_NONNULL_BEGIN
 @property (class, readonly) NSColor *VLCDarkSubtleBorderColor;
 @property (class, readonly) NSColor *VLCSubtleBorderColor;
 
+ at property (class, readonly) NSColor *VLCActionButtonBackgroundColor;
+ at property (class, readonly) NSColor *VLCActionButtonPressedBackgroundColor;
+ at property (class, readonly) NSColor *VLCActionButtonPressedBorderColor;
+ at property (class, readonly) NSColor *VLCDropTargetBackgroundColor;
+ at property (class, readonly) NSColor *VLCDropTargetHighlightColor;
+ at property (class, readonly) NSColor *VLCDropTargetBorderColor;
+
 @end
 
 NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/extensions/NSColor+VLCAdditions.m
=====================================
@@ -103,4 +103,34 @@
     return [NSColor colorNamed:@"VLCSubtleBorderColor"];
 }
 
++ (NSColor *)VLCActionButtonBackgroundColor
+{
+    return [NSColor.VLCAccentColor colorWithAlphaComponent:0.04];
+}
+
++ (NSColor *)VLCActionButtonPressedBackgroundColor
+{
+    return [NSColor.VLCAccentColor colorWithAlphaComponent:0.16];
+}
+
++ (NSColor *)VLCActionButtonPressedBorderColor
+{
+    return [NSColor.VLCAccentColor colorWithAlphaComponent:0.55];
+}
+
++ (NSColor *)VLCDropTargetBackgroundColor
+{
+    return [NSColor.controlBackgroundColor colorWithAlphaComponent:0.5];
+}
+
++ (NSColor *)VLCDropTargetHighlightColor
+{
+    return [NSColor.VLCAccentColor colorWithAlphaComponent:0.08];
+}
+
++ (NSColor *)VLCDropTargetBorderColor
+{
+    return [NSColor.secondaryLabelColor colorWithAlphaComponent:0.5];
+}
+
 @end


=====================================
modules/gui/macosx/extensions/NSFont+VLCAdditions.h
=====================================
@@ -29,6 +29,9 @@ NS_ASSUME_NONNULL_BEGIN
 @property (class, readonly) NSFont *VLClibrarySectionHeaderFont;
 @property (class, readonly) NSFont *VLCLibrarySubsectionHeaderFont;
 @property (class, readonly) NSFont *VLCLibrarySubsectionSubheaderFont;
+ at property (class, readonly) NSFont *VLCLibraryCompactSectionHeaderFont;
+ at property (class, readonly) NSFont *VLCLibraryCompactSubsectionSubheaderFont;
+ at property (class, readonly) NSFont *VLCLibrarySmallSubsectionSubheaderFont;
 @property (class, readonly) NSFont *VLCLibraryItemAnnotationFont;
 
 @end


=====================================
modules/gui/macosx/extensions/NSFont+VLCAdditions.m
=====================================
@@ -47,4 +47,19 @@
     return [NSFont systemFontOfSize:10 weight:NSFontWeightRegular];
 }
 
++ (NSFont *)VLCLibraryCompactSectionHeaderFont
+{
+    return [NSFont systemFontOfSize:18. weight:NSFontWeightBold];
+}
+
++ (NSFont *)VLCLibraryCompactSubsectionSubheaderFont
+{
+    return [NSFont systemFontOfSize:NSFont.systemFontSize weight:NSFontWeightMedium];
+}
+
++ (NSFont *)VLCLibrarySmallSubsectionSubheaderFont
+{
+    return [NSFont systemFontOfSize:12. weight:NSFontWeightMedium];
+}
+
 @end


=====================================
modules/gui/macosx/library/home-library/VLCLibraryHomeViewActionButtonCell.m
=====================================
@@ -27,136 +27,158 @@
 
 #import "views/VLCUIUnits.h"
 
- at interface VLCLibraryHomeViewActionButtonCell ()
-
- at property NSImage *cachedImage;
- at property BOOL prevIsHighlighted;
- at property NSRect prevFrame;
-
- at property (readonly) NSDictionary<NSAttributedStringKey, id> *cachedTitleAttributes;
- at property (readonly) CGFloat cachedTitleHeight;
-
- at end
-
 @implementation VLCLibraryHomeViewActionButtonCell
 
-- (NSRect)titleRectForBounds:(NSRect)bounds
+- (CGFloat)contentPaddingForBounds:(NSRect)bounds
 {
-    return bounds;
+    return NSWidth(bounds) < VLCUIUnits.actionButtonNarrowWidthThreshold
+        ? VLCUIUnits.mediumSpacing
+        : VLCUIUnits.mediumSpacing + VLCUIUnits.smallSpacing;
 }
 
 - (NSRect)imageRectForBounds:(NSRect)bounds
 {
-    return bounds;
+    return [self imageRectForBounds:bounds flipped:self.controlView.isFlipped];
 }
 
-- (NSDictionary<NSAttributedStringKey, id> *)titleAttributes
+- (NSRect)imageRectForBounds:(NSRect)bounds flipped:(BOOL)flipped
 {
-    if (_cachedTitleAttributes) {
-        return _cachedTitleAttributes;
+    if (NSWidth(bounds) < VLCUIUnits.actionButtonCompactWidthThreshold) {
+        const CGFloat side = MIN(VLCUIUnits.smallIconSize,
+                                 MAX(0., NSHeight(bounds) - VLCUIUnits.mediumSpacing));
+        const CGFloat originY = flipped
+            ? NSMinY(bounds) + VLCUIUnits.smallSpacing
+            : NSMaxY(bounds) - VLCUIUnits.smallSpacing - side;
+        return NSMakeRect(NSMidX(bounds) - side / 2., originY, side, side);
     }
-    NSMutableParagraphStyle * const titleParagraphStyle = [[NSMutableParagraphStyle alloc] init];
-    titleParagraphStyle.alignment = NSTextAlignmentCenter;
-    _cachedTitleAttributes = @{
-        NSForegroundColorAttributeName: NSColor.controlTextColor,
-        NSFontAttributeName: NSFont.VLCLibrarySubsectionSubheaderFont,
-        NSParagraphStyleAttributeName: titleParagraphStyle
-    };
-    return _cachedTitleAttributes;
+
+    const CGFloat padding = [self contentPaddingForBounds:bounds];
+    const CGFloat preferredSide = NSWidth(bounds) < VLCUIUnits.actionButtonNarrowWidthThreshold
+        ? VLCUIUnits.mediumIconSize
+        : VLCUIUnits.largeIconSize;
+    const CGFloat side = MIN(preferredSide, MAX(0., NSHeight(bounds) - 2. * padding));
+    const BOOL rightToLeft = self.userInterfaceLayoutDirection == NSUserInterfaceLayoutDirectionRightToLeft;
+    const CGFloat originX = rightToLeft ? NSMaxX(bounds) - padding - side : NSMinX(bounds) + padding;
+    return NSMakeRect(originX, NSMidY(bounds) - side / 2., side, side);
+}
+
+- (NSRect)titleRectForBounds:(NSRect)bounds
+{
+    return [self titleRectForBounds:bounds flipped:self.controlView.isFlipped];
 }
 
-- (CGFloat)titleHeightWithAttributes:(NSDictionary<NSAttributedStringKey, id> *)attributes
+- (NSRect)titleRectForBounds:(NSRect)bounds flipped:(BOOL)flipped
 {
-    if (_cachedTitleHeight) {
-        return _cachedTitleHeight;
+    if (NSWidth(bounds) < VLCUIUnits.actionButtonCompactWidthThreshold) {
+        const NSRect imageRect = [self imageRectForBounds:bounds flipped:flipped];
+        const CGFloat originY = flipped
+            ? NSMaxY(imageRect) + VLCUIUnits.smallSpacing / 2.
+            : NSMinY(bounds) + VLCUIUnits.smallSpacing;
+        return NSMakeRect(NSMinX(bounds) + VLCUIUnits.compactControlPadding, originY,
+                          MAX(0., NSWidth(bounds) - VLCUIUnits.compactControlPadding * 2.),
+                          MAX(0., NSHeight(bounds) - NSHeight(imageRect) - 2. * VLCUIUnits.smallSpacing - VLCUIUnits.smallSpacing / 2.));
     }
-    const NSSize titleSize = [self.title sizeWithAttributes:attributes];
-    _cachedTitleHeight = titleSize.height + VLCUIUnits.smallSpacing;
-    return _cachedTitleHeight;
+
+    const CGFloat padding = [self contentPaddingForBounds:bounds];
+    const CGFloat gap = VLCUIUnits.mediumSpacing;
+    const NSRect imageRect = [self imageRectForBounds:bounds flipped:flipped];
+    const BOOL rightToLeft = self.userInterfaceLayoutDirection == NSUserInterfaceLayoutDirectionRightToLeft;
+    const CGFloat originX = rightToLeft ? NSMinX(bounds) + padding : NSMaxX(imageRect) + gap;
+    const CGFloat width = MAX(0., NSWidth(bounds) - 2. * padding - NSWidth(imageRect) - gap);
+    return NSMakeRect(originX, NSMinY(bounds) + VLCUIUnits.mediumSpacing,
+                      width, MAX(0., NSHeight(bounds) - 2. * VLCUIUnits.mediumSpacing));
 }
 
 - (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView
 {
-    const CGSize cellSize = frame.size;
-    const CGFloat cellWidth = cellSize.width;
-    const CGFloat cellHeight = cellSize.height;
-    const CGFloat titleHeight = [self titleHeightWithAttributes:[self titleAttributes]];
-
-    const CGSize imageSize = self.image.size;
-
-    if (self.cachedImage != self.image ||
-        self.prevIsHighlighted != self.isHighlighted ||
-        !NSEqualRects(self.prevFrame, frame)) {
-
-        self.cachedImage = [NSImage imageWithSize:imageSize
-                                          flipped:NO
-                                   drawingHandler:^BOOL(NSRect __unused dstRect) {
-            if (self.isHighlighted) {
-                [NSColor.VLCSubtleBorderColor set];
-            } else {
-                [NSColor.VLCSubtlerAccentColor set];
-            }
-            const NSRect imageRect = {NSZeroPoint, imageSize};
-            [self.image drawInRect:imageRect];
-            NSRectFillUsingOperation(imageRect, NSCompositingOperationSourceIn);
-            return YES;
-        }];
-
-        self.prevIsHighlighted = self.isHighlighted;
-        self.prevFrame = frame;
-    } 
-
-    const CGFloat originalImageAspectRatio = imageSize.width / imageSize.height;
-    const CGFloat imageAvailableVerticalSpace =
-        cellHeight - titleHeight - VLCUIUnits.largeSpacing * 2;
-    CGFloat imageWidth, imageHeight;
-
-    // Try to scale focusing on width first, if this yields a height that is too large, switch
-    if (cellWidth / originalImageAspectRatio > imageAvailableVerticalSpace) {
-        imageHeight = imageAvailableVerticalSpace;
-        imageWidth = imageHeight * originalImageAspectRatio;
-    } else {
-        imageWidth = cellWidth;
-        imageHeight = imageWidth / originalImageAspectRatio;
+    if (image.size.width <= 0. || image.size.height <= 0. || NSIsEmptyRect(frame)) {
+        return;
     }
 
-    const CGPoint cellOrigin = frame.origin;
-    const NSRect imageRect = NSMakeRect(cellOrigin.x + (cellWidth - imageWidth) / 2,
-                                        cellOrigin.y + (cellHeight - imageHeight) / 2,
-                                        imageWidth,
-                                        imageHeight);
-    [self.cachedImage drawInRect:imageRect];
+    NSColor * const tint = self.isEnabled ? NSColor.VLCSubtlerAccentColor : NSColor.disabledControlTextColor;
+    NSImage * const tintedImage = [NSImage imageWithSize:image.size
+                                                 flipped:NO
+                                          drawingHandler:^BOOL(NSRect destinationRect) {
+        [image drawInRect:destinationRect];
+        [tint setFill];
+        NSRectFillUsingOperation(destinationRect, NSCompositingOperationSourceIn);
+        return YES;
+    }];
+
+    const CGFloat scale = MIN(NSWidth(frame) / image.size.width, NSHeight(frame) / image.size.height);
+    const NSSize scaledSize = NSMakeSize(image.size.width * scale, image.size.height * scale);
+    const NSRect imageRect = NSMakeRect(NSMidX(frame) - scaledSize.width / 2.,
+                                        NSMidY(frame) - scaledSize.height / 2.,
+                                        scaledSize.width,
+                                        scaledSize.height);
+    [tintedImage drawInRect:imageRect
+                   fromRect:NSZeroRect
+                  operation:NSCompositingOperationSourceOver
+                   fraction:1.
+             respectFlipped:YES
+                      hints:nil];
 }
 
-- (NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)cellFrame inView:(NSView *)controlView
+- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
 {
-    const CGFloat cellMinX = NSMinX(cellFrame);
-    const CGFloat cellMaxY = NSMaxY(cellFrame);
-    const CGSize cellSize = cellFrame.size;
-    const CGFloat cellWidth = cellSize.width;
-
-    NSDictionary<NSAttributedStringKey, id> * const titleAttributes = [self titleAttributes];
-    const CGFloat titleHeight = [self titleHeightWithAttributes:titleAttributes];
-    const NSRect titleRect = CGRectMake(cellMinX + VLCUIUnits.smallSpacing,
-                                      cellMaxY - titleHeight,
-                                      cellWidth - VLCUIUnits.smallSpacing * 2,
-                                      titleHeight);
-    [self.title drawInRect:titleRect withAttributes:titleAttributes];
-    return titleRect;
+    [self drawImage:self.image
+          withFrame:[self imageRectForBounds:cellFrame flipped:controlView.isFlipped]
+             inView:controlView];
+
+    const NSRect textRect = [self titleRectForBounds:cellFrame flipped:controlView.isFlipped];
+    if (NSIsEmptyRect(textRect)) {
+        return;
+    }
+
+    const BOOL compact = NSWidth(cellFrame) < VLCUIUnits.actionButtonCompactWidthThreshold;
+    const BOOL rightToLeft = self.userInterfaceLayoutDirection == NSUserInterfaceLayoutDirectionRightToLeft;
+    NSMutableParagraphStyle * const paragraphStyle = [[NSMutableParagraphStyle alloc] init];
+    paragraphStyle.alignment = compact ? NSTextAlignmentCenter : rightToLeft ? NSTextAlignmentRight : NSTextAlignmentLeft;
+    paragraphStyle.baseWritingDirection = rightToLeft ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
+    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
+    NSFont * const titleFont = NSWidth(cellFrame) < VLCUIUnits.actionButtonNarrowWidthThreshold
+        ? (compact ? NSFont.VLCLibrarySmallSubsectionSubheaderFont
+                   : NSFont.VLCLibraryCompactSubsectionSubheaderFont)
+        : NSFont.VLCLibrarySubsectionSubheaderFont;
+    NSColor * const titleColor = self.isEnabled ? NSColor.controlTextColor : NSColor.disabledControlTextColor;
+    NSDictionary<NSAttributedStringKey, id> * const titleAttributes = @{
+        NSFontAttributeName: titleFont,
+        NSForegroundColorAttributeName: titleColor,
+        NSParagraphStyleAttributeName: paragraphStyle
+    };
+
+    const NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine;
+    const NSSize measurementSize = NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX);
+    const CGFloat titleLineHeight = ceil(NSHeight([@" " boundingRectWithSize:measurementSize
+                                                                     options:NSStringDrawingUsesLineFragmentOrigin
+                                                                  attributes:titleAttributes]));
+    const CGFloat maximumTitleHeight = MIN(titleLineHeight * VLCUIUnits.actionButtonMaximumTitleLines, NSHeight(textRect));
+    const NSRect measuredTitleRect = [self.title boundingRectWithSize:NSMakeSize(NSWidth(textRect), maximumTitleHeight)
+                                                              options:options
+                                                           attributes:titleAttributes];
+    const CGFloat titleHeight = MIN(ceil(NSHeight(measuredTitleRect)), maximumTitleHeight);
+    const CGFloat titleMinY = NSMidY(textRect) - titleHeight / 2.;
+    const NSRect titleRect = NSMakeRect(NSMinX(textRect), titleMinY, NSWidth(textRect), titleHeight);
+    [self.title drawWithRect:titleRect options:options attributes:titleAttributes];
 }
 
 - (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView
 {
-    [NSColor.VLCSubtleBorderColor setStroke];
-    [NSColor.windowBackgroundColor setFill];
-
-    NSBezierPath * const separatorPath =
-        [NSBezierPath bezierPathWithRoundedRect:frame
-                                        xRadius:VLCUIUnits.cornerRadius
-                                        yRadius:VLCUIUnits.cornerRadius];
-    separatorPath.lineWidth = VLCUIUnits.borderThickness;
-    [separatorPath stroke];
-    [separatorPath fill];
+    const BOOL pressed = self.isEnabled && self.isHighlighted;
+    const CGFloat halfBorder = VLCUIUnits.borderThickness / 2.;
+    NSBezierPath * const bezelPath =
+        [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, halfBorder, halfBorder)
+                                        xRadius:VLCUIUnits.mediumSpacing
+                                        yRadius:VLCUIUnits.mediumSpacing];
+    bezelPath.lineWidth = VLCUIUnits.borderThickness;
+    [NSColor.controlBackgroundColor setFill];
+    [bezelPath fill];
+    [(pressed ? NSColor.VLCActionButtonPressedBackgroundColor
+              : NSColor.VLCActionButtonBackgroundColor) setFill];
+    [bezelPath fill];
+    [(pressed ? NSColor.VLCActionButtonPressedBorderColor
+              : NSColor.VLCSubtleBorderColor) setStroke];
+    [bezelPath stroke];
 }
 
 @end


=====================================
modules/gui/macosx/library/home-library/VLCLibraryHomeViewActionsView.h
=====================================
@@ -20,23 +20,26 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#import "views/VLCStackView.h"
+#import "views/VLCFileDragRecognisingView.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
- at interface VLCLibraryHomeViewActionsView : VLCStackView
+ at interface VLCLibraryHomeViewActionsView : VLCFileDragRecognisingView <VLCDragDropTarget>
+
+ at property (readwrite, weak) IBOutlet NSImageView *logoImageView;
+ at property (readwrite, weak) IBOutlet NSTextField *dropTitleTextField;
+ at property (readwrite, weak) IBOutlet NSTextField *dropDetailTextField;
+ at property (readwrite, weak) IBOutlet NSTextField *dropHintTextField;
 
 @property (readwrite, weak) IBOutlet NSButton *openFileButton;
 @property (readwrite, weak) IBOutlet NSButton *openDiscButton;
 @property (readwrite, weak) IBOutlet NSButton *openUrlButton;
 @property (readwrite, weak) IBOutlet NSButton *openCaptureDeviceButton;
- at property (readwrite, weak) IBOutlet NSButton *openBrowseButton;
 
 - (IBAction)openFileAction:(id)sender;
 - (IBAction)openDiscAction:(id)sender;
 - (IBAction)openUrlAction:(id)sender;
 - (IBAction)openCaptureDeviceAction:(id)sender;
-- (IBAction)openBrowseAction:(id)sender;
 
 @end
 


=====================================
modules/gui/macosx/library/home-library/VLCLibraryHomeViewActionsView.m
=====================================
@@ -22,23 +22,213 @@
 
 #import "VLCLibraryHomeViewActionsView.h"
 
+#import "extensions/NSColor+VLCAdditions.h"
+#import "extensions/NSFont+VLCAdditions.h"
+#import "extensions/NSImage+VLCAdditions.h"
 #import "extensions/NSString+Helpers.h"
-#import "extensions/NSView+VLCAdditions.h"
-#import "library/VLCLibraryWindow.h"
 #import "main/VLCMain.h"
 #import "menus/VLCMainMenu.h"
+#import "views/VLCUIUnits.h"
+
+ at interface VLCLibraryHomeViewActionsView ()
+
+ at property (nonatomic) BOOL dragHighlighted;
+ at property (nonatomic, weak) IBOutlet NSStackView *introductionStackView;
+ at property (nonatomic, weak) IBOutlet NSStackView *actionGridStackView;
+
+ at end
 
 @implementation VLCLibraryHomeViewActionsView
 
+- (void)dealloc
+{
+    [NSNotificationCenter.defaultCenter removeObserver:self];
+}
+
 - (void)awakeFromNib
 {
     [super awakeFromNib];
 
+    [self setupLayout];
+
+    self.dropTarget = self;
+    self.logoImageView.image = NSImage.VLCAppIconImage;
+    self.dropTitleTextField.stringValue = _NS("Drop anything here");
+    [self updateDropTitleFont];
+    self.dropDetailTextField.stringValue = _NS("Files, folders, discs and links.");
+    self.dropHintTextField.stringValue = _NS("Your content will be added to the play queue.");
+    self.dropDetailTextField.font = [NSFont systemFontOfSize:NSFont.systemFontSize];
+    self.dropHintTextField.font = [NSFont systemFontOfSize:NSFont.systemFontSize];
+    self.dropDetailTextField.textColor = NSColor.secondaryLabelColor;
+    self.dropHintTextField.textColor = NSColor.secondaryLabelColor;
+    for (NSTextField * const textField in @[self.dropTitleTextField,
+                                           self.dropDetailTextField,
+                                           self.dropHintTextField]) {
+        textField.maximumNumberOfLines = 0;
+        textField.postsFrameChangedNotifications = YES;
+        [NSNotificationCenter.defaultCenter addObserver:self
+                                               selector:@selector(dropTextFieldFrameChanged:)
+                                                   name:NSViewFrameDidChangeNotification
+                                                 object:textField];
+    }
+
     self.openFileButton.title = _NS("Open file");
     self.openDiscButton.title = _NS("Open disc");
     self.openUrlButton.title = _NS("Open stream");
     self.openCaptureDeviceButton.title = _NS("Open capture device");
-    self.openBrowseButton.title = _NS("Browse");
+    for (NSButton * const button in @[self.openFileButton,
+                                      self.openDiscButton,
+                                      self.openUrlButton,
+                                      self.openCaptureDeviceButton]) {
+        button.accessibilityLabel = button.title;
+        button.toolTip = button.title;
+    }
+
+    self.accessibilityLabel = self.dropTitleTextField.stringValue;
+    self.accessibilityHelp = self.dropDetailTextField.stringValue;
+}
+
+- (void)setupLayout
+{
+    const CGFloat horizontalInset = VLCUIUnits.extraLargeSpacing;
+    const CGFloat verticalInset = VLCUIUnits.largeSpacing;
+    const CGFloat minimumHeight = VLCUIUnits.libraryHomeActionsMinimumHeight;
+    NSLayoutConstraint * const preferredHeight = [self.heightAnchor constraintEqualToConstant:minimumHeight];
+    preferredHeight.priority = NSLayoutPriorityDefaultLow;
+    NSLayoutConstraint * const logoWidth =
+        [self.logoImageView.widthAnchor constraintEqualToConstant:VLCUIUnits.largeIllustrationSize];
+    logoWidth.priority = NSLayoutPriorityDefaultHigh;
+
+    [NSLayoutConstraint activateConstraints:@[
+        [self.heightAnchor constraintGreaterThanOrEqualToConstant:minimumHeight],
+        preferredHeight,
+        logoWidth,
+        [self.logoImageView.widthAnchor constraintLessThanOrEqualToAnchor:self.introductionStackView.widthAnchor
+                                                               multiplier:VLCUIUnits.libraryHomeActionsLogoWidthMultiplier],
+        [self.introductionStackView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:horizontalInset],
+        [self.actionGridStackView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:-horizontalInset],
+        [self.actionGridStackView.leadingAnchor constraintEqualToAnchor:self.introductionStackView.trailingAnchor
+                                                               constant:horizontalInset],
+        [self.actionGridStackView.widthAnchor constraintEqualToAnchor:self.widthAnchor
+                                                           multiplier:VLCUIUnits.libraryHomeActionsGridWidthMultiplier
+                                                             constant:-horizontalInset],
+    ]];
+
+    for (NSStackView * const stackView in @[self.introductionStackView, self.actionGridStackView]) {
+        [NSLayoutConstraint activateConstraints:@[
+            [stackView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
+            [stackView.topAnchor constraintGreaterThanOrEqualToAnchor:self.topAnchor constant:verticalInset],
+            [stackView.bottomAnchor constraintLessThanOrEqualToAnchor:self.bottomAnchor constant:-verticalInset],
+        ]];
+    }
+    for (NSStackView * const row in self.actionGridStackView.arrangedSubviews) {
+        row.spacing = VLCUIUnits.mediumSpacing + VLCUIUnits.smallSpacing;
+        for (NSView * const button in row.arrangedSubviews) {
+            [button.heightAnchor constraintEqualToConstant:VLCUIUnits.largeActionButtonHeight].active = YES;
+        }
+    }
+}
+
+- (void)updateDropTitleFont
+{
+    NSFont * const titleFont = NSWidth(self.bounds) < VLCUIUnits.libraryHomeActionsNarrowWidthThreshold
+        ? NSFont.VLCLibraryCompactSectionHeaderFont
+        : NSFont.VLClibrarySectionHeaderFont;
+    if (![self.dropTitleTextField.font isEqual:titleFont]) {
+        self.dropTitleTextField.font = titleFont;
+    }
+}
+
+- (void)dropTextFieldFrameChanged:(NSNotification *)notification
+{
+    [self updateDropTitleFont];
+
+    // Ancestor stack layout can resize labels without laying out this view again.
+    NSTextField * const textField = notification.object;
+    const CGFloat width = NSWidth(textField.bounds);
+    if (width > 0 && textField.preferredMaxLayoutWidth != width) {
+        textField.preferredMaxLayoutWidth = width;
+        [textField invalidateIntrinsicContentSize];
+    }
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+    [super drawRect:dirtyRect];
+
+    NSBezierPath * const border =
+        [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(self.bounds, VLCUIUnits.borderThickness,
+                                                                        VLCUIUnits.borderThickness)
+                                        xRadius:VLCUIUnits.largeSpacing
+                                        yRadius:VLCUIUnits.largeSpacing];
+    NSColor * const fillColor = self.dragHighlighted
+        ? NSColor.VLCDropTargetHighlightColor
+        : NSColor.VLCDropTargetBackgroundColor;
+    [fillColor setFill];
+    [border fill];
+
+    NSColor * const borderColor = self.dragHighlighted
+        ? NSColor.VLCAccentColor
+        : NSColor.VLCDropTargetBorderColor;
+    [borderColor setStroke];
+    border.lineWidth = self.dragHighlighted ? VLCUIUnits.borderThickness * 2. : VLCUIUnits.borderThickness;
+    const CGFloat dashPattern[] = {VLCUIUnits.dashedBorderDashLength,
+                                   VLCUIUnits.dashedBorderDashSpacing};
+    [border setLineDash:dashPattern count:sizeof(dashPattern) / sizeof(dashPattern[0]) phase:0.];
+    [border stroke];
+}
+
+- (void)setDragHighlighted:(BOOL)dragHighlighted
+{
+    if (_dragHighlighted == dragHighlighted) {
+        return;
+    }
+    _dragHighlighted = dragHighlighted;
+    self.needsDisplay = YES;
+}
+
+- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
+{
+    const NSDragOperation operation = [super draggingEntered:sender];
+    self.dragHighlighted = operation != NSDragOperationNone;
+    return operation;
+}
+
+- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
+{
+    return [self draggingEntered:sender];
+}
+
+- (void)draggingExited:(id<NSDraggingInfo>)sender
+{
+    self.dragHighlighted = NO;
+}
+
+- (void)draggingEnded:(id<NSDraggingInfo>)sender
+{
+    self.dragHighlighted = NO;
+}
+
+- (void)concludeDragOperation:(id<NSDraggingInfo>)sender
+{
+    self.dragHighlighted = NO;
+}
+
+- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
+{
+    self.dragHighlighted = NO;
+    return [super performDragOperation:sender];
+}
+
+- (BOOL)handlePasteBoardFromDragSession:(NSPasteboard *)pasteboard
+{
+    return [VLCFileDragRecognisingView handlePasteboardFromDragSessionAsPlayQueueItems:pasteboard];
+}
+
+- (void)viewDidChangeEffectiveAppearance
+{
+    [super viewDidChangeEffectiveAppearance];
+    self.needsDisplay = YES;
 }
 
 - (IBAction)openFileAction:(id)sender
@@ -61,9 +251,4 @@
     [VLCMain.sharedInstance.mainMenu intfOpenCapture:self];
 }
 
-- (IBAction)openBrowseAction:(id)sender
-{
-    [VLCMain.sharedInstance.libraryWindow goToBrowseSection:self];
-}
-
 @end


=====================================
modules/gui/macosx/views/VLCUIUnits.h
=====================================
@@ -55,10 +55,24 @@ extern NSString * const VLCLibraryCollectionViewItemAdjustmentKey;
 @property (class, readonly) const CGFloat largeSpacing;
 @property (class, readonly) const CGFloat mediumSpacing;
 @property (class, readonly) const CGFloat smallSpacing;
+ at property (class, readonly) const CGFloat extraLargeSpacing;
+ at property (class, readonly) const CGFloat compactControlPadding;
 
 @property (class, readonly) const CGFloat cornerRadius;
 
 @property (class, readonly) const CGFloat borderThickness;
+ at property (class, readonly) const CGFloat dashedBorderDashLength;
+ at property (class, readonly) const CGFloat dashedBorderDashSpacing;
+
+// Common icon, illustration and action-button sizes.
+ at property (class, readonly) const CGFloat smallIconSize;
+ at property (class, readonly) const CGFloat mediumIconSize;
+ at property (class, readonly) const CGFloat largeIconSize;
+ at property (class, readonly) const CGFloat largeIllustrationSize;
+ at property (class, readonly) const CGFloat largeActionButtonHeight;
+ at property (class, readonly) const CGFloat actionButtonCompactWidthThreshold;
+ at property (class, readonly) const CGFloat actionButtonNarrowWidthThreshold;
+ at property (class, readonly) const NSUInteger actionButtonMaximumTitleLines;
 
 @property (class, readonly) const CGFloat scrollBarSmallSideSize;
 
@@ -89,6 +103,12 @@ extern NSString * const VLCLibraryCollectionViewItemAdjustmentKey;
 @property (class, readonly) const CGFloat carouselViewVideoItemViewWidth;
 @property (class, readonly) const CGFloat carouselViewItemViewHeight;
 
+// Home drop-area layout.
+ at property (class, readonly) const CGFloat libraryHomeActionsMinimumHeight;
+ at property (class, readonly) const CGFloat libraryHomeActionsNarrowWidthThreshold;
+ at property (class, readonly) const CGFloat libraryHomeActionsGridWidthMultiplier;
+ at property (class, readonly) const CGFloat libraryHomeActionsLogoWidthMultiplier;
+
 @property (class, readonly) const NSEdgeInsets libraryViewScrollViewContentInsets;
 @property (class, readonly) const NSEdgeInsets libraryViewScrollViewDetailListContentInsets;
 @property (class, readonly) const NSEdgeInsets libraryViewScrollViewDetailGridContentInsets;


=====================================
modules/gui/macosx/views/VLCUIUnits.m
=====================================
@@ -66,6 +66,66 @@ NSString * const VLCLibraryCollectionViewItemAdjustmentKey = @"VLCLibraryCollect
     return 1.;
 }
 
++ (const CGFloat)extraLargeSpacing
+{
+    return self.largeSpacing + self.mediumSpacing;
+}
+
++ (const CGFloat)compactControlPadding
+{
+    return self.smallSpacing + self.smallSpacing / 2.;
+}
+
++ (const CGFloat)dashedBorderDashLength
+{
+    return self.smallSpacing + self.smallSpacing / 2.;
+}
+
++ (const CGFloat)dashedBorderDashSpacing
+{
+    return self.smallSpacing + self.borderThickness;
+}
+
++ (const CGFloat)smallIconSize
+{
+    return self.largeSpacing;
+}
+
++ (const CGFloat)mediumIconSize
+{
+    return self.largeSpacing + self.smallSpacing;
+}
+
++ (const CGFloat)largeIconSize
+{
+    return 26.;
+}
+
++ (const CGFloat)largeIllustrationSize
+{
+    return self.largeSpacing * 4.;
+}
+
++ (const CGFloat)largeActionButtonHeight
+{
+    return 56.;
+}
+
++ (const CGFloat)actionButtonCompactWidthThreshold
+{
+    return 130.;
+}
+
++ (const CGFloat)actionButtonNarrowWidthThreshold
+{
+    return 160.;
+}
+
++ (const NSUInteger)actionButtonMaximumTitleLines
+{
+    return 2;
+}
+
 + (const CGFloat)scrollBarSmallSideSize
 {
     return 16;
@@ -175,6 +235,26 @@ NSString * const VLCLibraryCollectionViewItemAdjustmentKey = @"VLCLibraryCollect
     return NSEdgeInsetsMake(inset, inset, inset, inset);
 }
 
++ (const CGFloat)libraryHomeActionsMinimumHeight
+{
+    return self.largeActionButtonHeight * 2. + self.mediumSpacing + self.largeSpacing * 2.;
+}
+
++ (const CGFloat)libraryHomeActionsNarrowWidthThreshold
+{
+    return 600.;
+}
+
++ (const CGFloat)libraryHomeActionsGridWidthMultiplier
+{
+    return 0.52;
+}
+
++ (const CGFloat)libraryHomeActionsLogoWidthMultiplier
+{
+    return 0.22;
+}
+
 + (const NSSize)adjustedCollectionViewItemSizeForCollectionView:(NSCollectionView *)collectionView
                                                      withLayout:(VLCLibraryCollectionViewFlowLayout *)collectionViewLayout
                                            withItemsAspectRatio:(VLCLibraryCollectionViewItemAspectRatio)itemsAspectRatio



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/be9e477571f36873c2a5f1733e940a31c0dd089e...ff10c6cf720d73cba5ac89efda22e03c2aa610bf

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/be9e477571f36873c2a5f1733e940a31c0dd089e...ff10c6cf720d73cba5ac89efda22e03c2aa610bf
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list