mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-09 04:07:12 +00:00
NEW: Support for basic CPVisualEffectView
This patch contains a very naive implementation of the NSVisualEffectView. This will only work on very recent unreleased version of Safari, but should be supported by all at some point. This allow to use the Yosemite/iOS blurry effect. Not all options are supported (especially the `CPVisualEffectBlendingModeBehindWindow` mode…). But hey! it’s a start :) Tests in Manual/CPVisualEffectViewTest
This commit is contained in:
@@ -107,6 +107,7 @@
|
||||
@import "CPView.j"
|
||||
@import "CPViewAnimation.j"
|
||||
@import "CPViewController.j"
|
||||
@import "CPVisualEffectView.j"
|
||||
@import "CPWebView.j"
|
||||
@import "CPWindow.j"
|
||||
@import "CPWindowController.j"
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* CPVisualEffectView.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Antoine Mercadal.
|
||||
* Copyright 2015, 280 Cappuccino Project.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@import "CPAppearance.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@typedef CPVisualEffectMaterial
|
||||
CPVisualEffectMaterialAppearanceBased = 0;
|
||||
CPVisualEffectMaterialLight = 1;
|
||||
CPVisualEffectMaterialDark = 2;
|
||||
CPVisualEffectMaterialTitlebar = 3;
|
||||
|
||||
@typedef CPVisualEffectBlendingMode
|
||||
CPVisualEffectBlendingModeBehindWindow = 0;
|
||||
CPVisualEffectBlendingModeWithinWindow = 1;
|
||||
|
||||
@typedef CPVisualEffectState
|
||||
CPVisualEffectStateFollowsWindowActiveState = 0;
|
||||
CPVisualEffectStateActive = 1;
|
||||
CPVisualEffectStateInactive = 2;
|
||||
|
||||
|
||||
/*! @ingroup appkit
|
||||
|
||||
Very naive implementation of CPVisualEffectView. This view allows
|
||||
to use vibrancy effect. This is only working with Safari 9+ and the
|
||||
support in Chrome/ium should come quite soon.
|
||||
Using this class with a browser that doesn't support backdrop-filter
|
||||
While still work, but you will not get the blurry effect.
|
||||
*/
|
||||
@implementation CPVisualEffectView : CPView
|
||||
{
|
||||
CPImage _maskImage @accessors(property=maskImage);
|
||||
CPVisualEffectBlendingMode _blendingMode @accessors(property=blendingMode);
|
||||
CPVisualEffectMaterial _material @accessors(property=material);
|
||||
CPVisualEffectState _state @accessors(property=state);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Initialization
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
if (self = [super initWithFrame:aFrame])
|
||||
{
|
||||
_material = CPVisualEffectMaterialAppearanceBased;
|
||||
_blendingMode = CPVisualEffectBlendingModeWithinWindow;
|
||||
_state = CPVisualEffectStateFollowsWindowActiveState;
|
||||
_appearance = [CPAppearance appearanceNamed:CPAppearanceNameVibrantDark];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CPVisualEffectView API
|
||||
|
||||
/*! Sets the appearance of the CPVisualEffectView.
|
||||
|
||||
Only CPAppearance named CPAppearanceNameVibrantDark or CPAppearanceNameVibrantLight are valid
|
||||
|
||||
@param anAppearance the CPAppearance.
|
||||
*/
|
||||
- (void)setAppearance:(CPAppearance)anAppearance
|
||||
{
|
||||
if (![self _validAppearance:anAppearance])
|
||||
[CPException raise:CPInvalidArgumentException reason:"Appearance can only be CPAppearanceNameVibrantDark or CPAppearanceNameVibrantLight in CPVisualEffectView, but is " + anAppearance];
|
||||
|
||||
[super setAppearance:anAppearance];
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
/*! Sets the received effect state.
|
||||
Possible values:
|
||||
<pre>
|
||||
CPVisualEffectStateFollowsWindowActiveState (default)
|
||||
CPVisualEffectStateActive
|
||||
CPVisualEffectStateInactive
|
||||
</pre>
|
||||
*/
|
||||
- (void)setState:(CPVisualEffectState)aState
|
||||
{
|
||||
if (_state == aState)
|
||||
return;
|
||||
|
||||
[self willChangeValueForKey:"state"];
|
||||
_state = aState;
|
||||
[self didChangeValueForKey:"state"];
|
||||
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Utilities
|
||||
|
||||
- (void)_setEffectEnabled:(BOOL)shouldEnable
|
||||
{
|
||||
var prop = CPBrowserStyleProperty("backdrop-filter"),
|
||||
dark = [[self appearance] isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]],
|
||||
darkColor = [CPColor colorWithHexString:@"1e1e1e"],
|
||||
lightColor = [CPColor whiteColor];
|
||||
|
||||
if (shouldEnable)
|
||||
{
|
||||
if (prop)
|
||||
self._DOMElement.style[prop] = "blur(30px)";
|
||||
[self setBackgroundColor:[(dark ? darkColor : lightColor) colorWithAlphaComponent:0.6]];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prop)
|
||||
self._DOMElement.style[prop] = nil;
|
||||
|
||||
[self setBackgroundColor:(dark ? darkColor : lightColor)];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_applyVibrancyState
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case CPVisualEffectStateFollowsWindowActiveState:
|
||||
[self _setEffectEnabled:[self hasThemeState:CPThemeStateKeyWindow]];
|
||||
break;
|
||||
|
||||
case CPVisualEffectStateActive:
|
||||
[self _setEffectEnabled:YES];
|
||||
break;
|
||||
|
||||
case CPVisualEffectStateInactive:
|
||||
[self _setEffectEnabled:NO];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_validAppearance:(CPAppearance)anAppearance
|
||||
{
|
||||
return [anAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]] || [anAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Overrides
|
||||
|
||||
- (BOOL)setThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var ret = [super setThemeState:aState];
|
||||
|
||||
[self _applyVibrancyState];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var ret = [super unsetThemeState:aState];
|
||||
|
||||
[self _applyVibrancyState];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToSuperview
|
||||
{
|
||||
[super viewDidMoveToSuperview];
|
||||
|
||||
if (_superview)
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[super viewDidMoveToWindow];
|
||||
|
||||
if (_window)
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CPCoding
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (self = [super initWithCoder:aCoder])
|
||||
{
|
||||
_blendingMode = [aCoder decodeIntForKey:@"_blendingMode"] || CPVisualEffectBlendingModeWithinWindow;
|
||||
_maskImage = [aCoder decodeObjectForKey:@"_maskImage"];
|
||||
_material = [aCoder decodeIntForKey:@"_material"] || CPVisualEffectMaterialAppearanceBased;
|
||||
_state = [aCoder decodeIntForKey:@"_state"] || CPVisualEffectStateFollowsWindowActiveState;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
[aCoder encodeObject:_maskImage forKey:@"_maskImage"];
|
||||
[aCoder encodeInt:_blendingMode forKey:@"_blendingMode"];
|
||||
[aCoder encodeInt:_material forKey:@"_material"];
|
||||
[aCoder encodeInt:_state forKey:@"_state"];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* AppController.j
|
||||
* CPVisualEffectViewTest
|
||||
*
|
||||
* Created by You on August 13, 2015.
|
||||
* Copyright 2015, Your Company All rights reserved.
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
@implementation AppController : CPObject
|
||||
// everything in the xib
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPVisualEffectViewTest</string>
|
||||
<key>CPBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CPHumanReadableCopyright</key>
|
||||
<string>Copyright © 2015, Your Company All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Jakefile
|
||||
* CPVisualEffectViewTest
|
||||
*
|
||||
* Created by You on August 13, 2015.
|
||||
* Copyright 2015, Your Company All rights reserved.
|
||||
*/
|
||||
|
||||
var ENV = require("system").env,
|
||||
FILE = require("file"),
|
||||
JAKE = require("jake"),
|
||||
task = JAKE.task,
|
||||
FileList = JAKE.FileList,
|
||||
app = require("cappuccino/jake").app,
|
||||
configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug",
|
||||
OS = require("os"),
|
||||
projectName = "CPVisualEffectViewTest";
|
||||
|
||||
app (projectName, function(task)
|
||||
{
|
||||
ENV["OBJJ_INCLUDE_PATHS"] = "Frameworks";
|
||||
|
||||
if (configuration === "Debug")
|
||||
ENV["OBJJ_INCLUDE_PATHS"] = FILE.join(ENV["OBJJ_INCLUDE_PATHS"], configuration);
|
||||
|
||||
task.setBuildIntermediatesPath(FILE.join("Build", "CPVisualEffectViewTest.build", configuration));
|
||||
task.setBuildPath(FILE.join("Build", configuration));
|
||||
|
||||
task.setProductName("CPVisualEffectViewTest");
|
||||
task.setIdentifier("com.yourcompany.CPVisualEffectViewTest");
|
||||
task.setVersion("1.0");
|
||||
task.setAuthor("Your Company");
|
||||
task.setEmail("feedback @nospam@ yourcompany.com");
|
||||
task.setSummary("CPVisualEffectViewTest");
|
||||
task.setSources(new FileList("**/*.j").exclude(FILE.join("Build", "**")).exclude(FILE.join("Frameworks", "Source", "**")));
|
||||
task.setResources(new FileList("Resources/**"));
|
||||
task.setIndexFilePath("index.html");
|
||||
task.setInfoPlistPath("Info.plist");
|
||||
|
||||
if (configuration === "Debug")
|
||||
task.setCompilerFlags("-DDEBUG -g");
|
||||
else
|
||||
task.setCompilerFlags("-O");
|
||||
});
|
||||
|
||||
task ("default", [projectName], function()
|
||||
{
|
||||
printResults(configuration);
|
||||
});
|
||||
|
||||
task ("build", ["default"], function()
|
||||
{
|
||||
updateApplicationSize();
|
||||
});
|
||||
|
||||
task ("debug", function()
|
||||
{
|
||||
configuration = ENV["CONFIGURATION"] = "Debug";
|
||||
JAKE.subjake(["."], "build", ENV);
|
||||
});
|
||||
|
||||
task ("release", function()
|
||||
{
|
||||
configuration = ENV["CONFIGURATION"] = "Release";
|
||||
JAKE.subjake(["."], "build", ENV);
|
||||
});
|
||||
|
||||
task ("run", ["debug"], function()
|
||||
{
|
||||
OS.system(["open", FILE.join("Build", "Debug", projectName, "index.html")]);
|
||||
});
|
||||
|
||||
task ("run-release", ["release"], function()
|
||||
{
|
||||
OS.system(["open", FILE.join("Build", "Release", projectName, "index.html")]);
|
||||
});
|
||||
|
||||
task ("deploy", ["release"], function()
|
||||
{
|
||||
FILE.mkdirs(FILE.join("Build", "Deployment", projectName));
|
||||
OS.system(["press", "-f", FILE.join("Build", "Release", projectName), FILE.join("Build", "Deployment", projectName)]);
|
||||
printResults("Deployment")
|
||||
});
|
||||
|
||||
task ("desktop", ["release"], function()
|
||||
{
|
||||
FILE.mkdirs(FILE.join("Build", "Desktop", projectName));
|
||||
require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", projectName), FILE.join("Build", "Desktop", projectName, "CPVisualEffectViewTest.app"));
|
||||
printResults("Desktop")
|
||||
});
|
||||
|
||||
task ("run-desktop", ["desktop"], function()
|
||||
{
|
||||
OS.system([FILE.join("Build", "Desktop", projectName, "CPVisualEffectViewTest.app", "Contents", "MacOS", "NativeHost"), "-i"]);
|
||||
});
|
||||
|
||||
function printResults(configuration)
|
||||
{
|
||||
print("----------------------------");
|
||||
print(configuration+" app built at path: "+FILE.join("Build", configuration, projectName));
|
||||
print("----------------------------");
|
||||
}
|
||||
|
||||
function updateApplicationSize()
|
||||
{
|
||||
print("Calculating application file sizes...");
|
||||
|
||||
var contents = FILE.read(FILE.join("Build", configuration, projectName, "Info.plist"), { charset:"UTF-8" }),
|
||||
format = CFPropertyList.sniffedFormatOfString(contents),
|
||||
plist = CFPropertyList.propertyListFromString(contents),
|
||||
totalBytes = {executable:0, data:0, mhtml:0};
|
||||
|
||||
// Get the size of all framework executables and sprite data
|
||||
var frameworksDir = "Frameworks";
|
||||
|
||||
if (configuration === "Debug")
|
||||
frameworksDir = FILE.join(frameworksDir, "Debug");
|
||||
|
||||
var frameworks = FILE.list(frameworksDir);
|
||||
|
||||
frameworks.forEach(function(framework)
|
||||
{
|
||||
if (framework !== "Source")
|
||||
addBundleFileSizes(FILE.join(frameworksDir, framework), totalBytes);
|
||||
});
|
||||
|
||||
// Read in the default theme name, and attempt to get its size
|
||||
var themeName = plist.valueForKey("CPDefaultTheme") || "Aristo2",
|
||||
themePath = nil;
|
||||
|
||||
if (themeName === "Aristo" || themeName === "Aristo2")
|
||||
themePath = FILE.join(frameworksDir, "AppKit", "Resources", themeName + ".blend");
|
||||
else
|
||||
themePath = FILE.join("Frameworks", "Resources", themeName + ".blend");
|
||||
|
||||
if (FILE.isDirectory(themePath))
|
||||
addBundleFileSizes(themePath, totalBytes);
|
||||
|
||||
// Add sizes for the app
|
||||
addBundleFileSizes(FILE.join("Build", configuration, projectName), totalBytes);
|
||||
|
||||
print("Executables: " + totalBytes.executable + ", sprite data: " + totalBytes.data + ", total: " + (totalBytes.executable + totalBytes.data));
|
||||
|
||||
var dict = new CFMutableDictionary();
|
||||
|
||||
dict.setValueForKey("executable", totalBytes.executable);
|
||||
dict.setValueForKey("data", totalBytes.data);
|
||||
dict.setValueForKey("mhtml", totalBytes.mhtml);
|
||||
|
||||
plist.setValueForKey("CPApplicationSize", dict);
|
||||
|
||||
FILE.write(FILE.join("Build", configuration, projectName, "Info.plist"), CFPropertyList.stringFromPropertyList(plist, format), { charset:"UTF-8" });
|
||||
}
|
||||
|
||||
function addBundleFileSizes(bundlePath, totalBytes)
|
||||
{
|
||||
var bundleName = FILE.basename(bundlePath),
|
||||
environment = bundleName === "Foundation" ? "Objj" : "Browser",
|
||||
bundlePath = FILE.join(bundlePath, environment + ".environment");
|
||||
|
||||
if (FILE.isDirectory(bundlePath))
|
||||
{
|
||||
var filename = bundleName + ".sj",
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, filename));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.executable += filePath.size();
|
||||
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, "dataURLs.txt"));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.data += filePath.size();
|
||||
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, "MHTMLData.txt"));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.mhtml += filePath.size();
|
||||
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, "MHTMLPaths.txt"));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.mhtml += filePath.size();
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="8173.3" systemVersion="15A244d" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="8173.3"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="450" id="451"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="450" customClass="AppController"/>
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" frameAutosaveName="" animationBehavior="default" id="Knp-iN-1Ch">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="100" y="722" width="181" height="67"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="KQ2-1g-9W7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="181" height="67"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="d7y-fN-bjP">
|
||||
<rect key="frame" x="18" y="25" width="145" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Click me to loose focus" id="eKf-xB-TJp">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</view>
|
||||
<point key="canvasLocation" x="146.5" y="111.5"/>
|
||||
</window>
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="335" y="178" width="834" height="545"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="834" height="545"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="WJS-cx-TuA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="834" height="545"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<animations/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="background" id="asL-vN-HqR"/>
|
||||
</imageView>
|
||||
<visualEffectView appearanceType="vibrantLight" blendingMode="behindWindow" state="followsWindowActiveState" id="ESw-Mt-ZuS">
|
||||
<rect key="frame" x="87" y="276" width="215" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="drG-ES-sje">
|
||||
<rect key="frame" x="18" y="110" width="179" height="34"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="f01-C4-Fhw">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<string key="title">Vibrant Light
|
||||
Follows Key Window</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</visualEffectView>
|
||||
<visualEffectView appearanceType="vibrantDark" blendingMode="behindWindow" state="followsWindowActiveState" id="xEz-ym-SoC">
|
||||
<rect key="frame" x="87" y="14" width="215" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="oRu-hV-Fpl">
|
||||
<rect key="frame" x="18" y="110" width="179" height="34"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="ff0-As-8T5">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<string key="title">Vibrant Dark
|
||||
Follows Key Window</string>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="0.84999999999999998" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</visualEffectView>
|
||||
<visualEffectView appearanceType="vibrantLight" blendingMode="behindWindow" state="active" id="ofy-S7-rCf">
|
||||
<rect key="frame" x="310" y="276" width="215" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="YjR-CK-WeJ">
|
||||
<rect key="frame" x="18" y="110" width="179" height="34"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="0ce-BE-k8L">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<string key="title">Vibrant Light
|
||||
Active</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</visualEffectView>
|
||||
<visualEffectView appearanceType="vibrantDark" blendingMode="behindWindow" state="active" id="X1I-rR-BOD">
|
||||
<rect key="frame" x="310" y="14" width="215" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="eA4-la-pyn">
|
||||
<rect key="frame" x="18" y="110" width="179" height="34"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="16n-7u-pbb">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<string key="title">Vibrant Dark
|
||||
Active</string>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="0.84999999999999998" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</visualEffectView>
|
||||
<visualEffectView appearanceType="vibrantLight" blendingMode="behindWindow" state="inactive" id="GcT-Xr-eCB">
|
||||
<rect key="frame" x="533" y="276" width="215" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="V0w-c6-mp4">
|
||||
<rect key="frame" x="18" y="110" width="179" height="34"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="Apx-Ho-9sT">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<string key="title">Vibrant Light
|
||||
Inactive</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</visualEffectView>
|
||||
<visualEffectView appearanceType="vibrantDark" blendingMode="behindWindow" state="inactive" id="kpQ-qE-hkl">
|
||||
<rect key="frame" x="533" y="14" width="215" height="254"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="x9a-RT-bcS">
|
||||
<rect key="frame" x="18" y="110" width="179" height="34"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="b25-G9-HOg">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<string key="title">Vibrant Dark
|
||||
Inactive</string>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="0.84999999999999998" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</visualEffectView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</view>
|
||||
<point key="canvasLocation" x="713" y="374.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="background" width="614.4000244140625" height="401"/>
|
||||
</resources>
|
||||
</document>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
index-debug.html
|
||||
CPVisualEffectViewTest
|
||||
|
||||
Created by You on August 13, 2015.
|
||||
Copyright 2015, Your Company All rights reserved.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1">
|
||||
<![endif]-->
|
||||
<!--[if gte IE 9]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
||||
<![endif]-->
|
||||
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
|
||||
<link rel="apple-touch-icon" href="Resources/icon.png">
|
||||
<link rel="apple-touch-startup-image" href="Resources/default.png">
|
||||
|
||||
<title>CPVisualEffectViewTest</title>
|
||||
|
||||
<!-- Custom javascript goes here -->
|
||||
<!-- End custom javascript -->
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks"];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
OBJJ_PROGRESS_CALLBACK = function(percent, appSize, path)
|
||||
{
|
||||
percent = percent * 100;
|
||||
|
||||
if (!progressBar)
|
||||
progressBar = document.getElementById("progress-bar");
|
||||
|
||||
if (progressBar)
|
||||
progressBar.style.width = Math.min(percent, 100) + "%";
|
||||
}
|
||||
|
||||
var loadingHTML =
|
||||
'<div id="loading">' +
|
||||
' <div id="loading-text">Loading...</div>' +
|
||||
' <div id="progress-indicator">' +
|
||||
' <span id="progress-bar" style="width:0%"></span>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js" charset="UTF-8"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
objj_msgSend_reset();
|
||||
|
||||
// DEBUG OPTIONS:
|
||||
|
||||
// Uncomment to enable printing of backtraces on exceptions:
|
||||
//objj_msgSend_decorate(objj_backtrace_decorator);
|
||||
|
||||
// Uncomment to supress exceptions that take place inside a message
|
||||
//objj_msgSend_decorate(objj_supress_exceptions_decorator)
|
||||
|
||||
// Uncomment to enable runtime type checking:
|
||||
//objj_msgSend_decorate(objj_typecheck_decorator);
|
||||
|
||||
// Uncomment (along with both above) to print backtraces on type check errors:
|
||||
//objj_typecheck_prints_backtrace = true;
|
||||
|
||||
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
|
||||
//CPLogUnregister(CPLogDefault);
|
||||
|
||||
// Uncomment to enable a specific logger:
|
||||
//CPLogRegister(CPLogConsole);
|
||||
//CPLogRegister(CPLogPopup);
|
||||
|
||||
// Tag view DOM elements with a "data-cappuccino-view" attribute that contains
|
||||
// the class name of the view that created them. Comment this or set to false to disable.
|
||||
appkit_tag_dom_elements = true;
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
html, body, h1, p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* We need a body wrapper because Cappuccino is unhappy if we change the body element */
|
||||
#cappuccino-body {
|
||||
/* Position it absolutely so it will fill the height without content */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
/* Put it at the bottom of the stack so it doesn't interfere with UI */
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#cappuccino-body .container {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#cappuccino-body .content {
|
||||
display: table-cell;
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
}
|
||||
|
||||
#loading-text {
|
||||
height: 1.5em;
|
||||
color: #555;
|
||||
font: normal bold 36px/36px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#progress-indicator {
|
||||
padding: 0px;
|
||||
height: 16px;
|
||||
border: 5px solid #555;
|
||||
border-radius: 18px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
display: block;
|
||||
height: 18px;
|
||||
|
||||
/* Compensate for moving the bar left 1px to overlap the indicator border */
|
||||
border-right: 1px solid #555;
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
#noscript {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
padding: 1em 1.5em;
|
||||
border: 5px solid #555;
|
||||
border-radius: 16px;
|
||||
background-color: white;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font: bold 24px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#noscript a {
|
||||
color: #98c0ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="cappuccino-body">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<script type="text/javascript">
|
||||
document.write(loadingHTML);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<noscript style="position:absolute; top:0; left:0; width:100%; height:100%">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div id="noscript">
|
||||
<p style="font-size:120%; margin-bottom:.75em">JavaScript is required for this site.</p>
|
||||
<p><a href="http://www.enable-javascript.com" target="_blank">Enable JavaScript</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,161 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
index.html
|
||||
CPVisualEffectViewTest
|
||||
|
||||
Created by You on August 13, 2015.
|
||||
Copyright 2015, Your Company All rights reserved.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1">
|
||||
<![endif]-->
|
||||
<!--[if gte IE 9]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
||||
<![endif]-->
|
||||
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
|
||||
<link rel="apple-touch-icon" href="Resources/icon.png">
|
||||
<link rel="apple-touch-startup-image" href="Resources/default.png">
|
||||
|
||||
<title>CPVisualEffectViewTest</title>
|
||||
|
||||
<!-- Custom javascript goes here -->
|
||||
<!-- End custom javascript -->
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
OBJJ_PROGRESS_CALLBACK = function(percent, appSize, path)
|
||||
{
|
||||
percent = percent * 100;
|
||||
|
||||
if (!progressBar)
|
||||
progressBar = document.getElementById("progress-bar");
|
||||
|
||||
if (progressBar)
|
||||
progressBar.style.width = Math.min(percent, 100) + "%";
|
||||
}
|
||||
|
||||
var loadingHTML =
|
||||
'<div id="loading">' +
|
||||
' <div id="loading-text">Loading...</div>' +
|
||||
' <div id="progress-indicator">' +
|
||||
' <span id="progress-bar" style="width:0%"></span>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
|
||||
|
||||
<style type="text/css">
|
||||
html, body, h1, p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* We need a body wrapper because Cappuccino is unhappy if we change the body element */
|
||||
#cappuccino-body {
|
||||
/* Position it absolutely so it will fill the height without content */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
/* Put it at the bottom of the stack so it doesn't interfere with UI */
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#cappuccino-body .container {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#cappuccino-body .content {
|
||||
display: table-cell;
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
}
|
||||
|
||||
#loading-text {
|
||||
height: 1.5em;
|
||||
color: #555;
|
||||
font: normal bold 36px/36px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#progress-indicator {
|
||||
padding: 0px;
|
||||
height: 16px;
|
||||
border: 5px solid #555;
|
||||
border-radius: 18px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
display: block;
|
||||
height: 18px;
|
||||
|
||||
/* Compensate for moving the bar left 1px to overlap the indicator border */
|
||||
border-right: 1px solid #555;
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
#noscript {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
padding: 1em 1.5em;
|
||||
border: 5px solid #555;
|
||||
border-radius: 16px;
|
||||
background-color: white;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font: bold 24px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#noscript a {
|
||||
color: #98c0ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="cappuccino-body">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<script type="text/javascript">
|
||||
document.write(loadingHTML);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<noscript style="position:absolute; top:0; left:0; width:100%; height:100%">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div id="noscript">
|
||||
<p style="font-size:120%; margin-bottom:.75em">JavaScript is required for this site.</p>
|
||||
<p><a href="http://www.enable-javascript.com" target="_blank">Enable JavaScript</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* AppController.j
|
||||
* CPVisualEffectViewTest
|
||||
*
|
||||
* Created by You on August 13, 2015.
|
||||
* Copyright 2015, Your Company All rights reserved.
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
@import "AppController.j"
|
||||
|
||||
|
||||
function main(args, namedArgs)
|
||||
{
|
||||
CPApplicationMain(args, namedArgs);
|
||||
}
|
||||
@@ -89,6 +89,7 @@
|
||||
@import "NSPopover.j"
|
||||
@import "NSProgressIndicator.j"
|
||||
@import "NSAppearance.j"
|
||||
@import "NSVisualEffectView.j"
|
||||
|
||||
|
||||
function CP_NSMapClassName(aClassName)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* NSVisualEffectView.j
|
||||
* nib2cib
|
||||
*
|
||||
* Created by Antoine Mercadal.
|
||||
* Copyright 2015, Cappuccino Project
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <AppKit/CPVisualEffectView.j>
|
||||
|
||||
|
||||
@implementation CPVisualEffectView (NSCoding)
|
||||
|
||||
- (id)NS_initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (self = [super NS_initWithCoder:aCoder])
|
||||
{
|
||||
_material = [aCoder decodeObjectForKey:@"NSVisualEffectViewMaterial"];
|
||||
_state = [aCoder decodeObjectForKey:@"NSVisualEffectViewState"];
|
||||
|
||||
// this is not supported
|
||||
// _blendingMode = [aCoder decodeObjectForKey:@"NSVisualEffectViewBlendingMode"];
|
||||
_blendingMode = CPVisualEffectBlendingModeWithinWindow;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSVisualEffectView : CPVisualEffectView
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
return [self NS_initWithCoder:aCoder];
|
||||
}
|
||||
|
||||
- (Class)classForKeyedArchiver
|
||||
{
|
||||
return [CPVisualEffectView class];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -605,5 +605,6 @@ var NSClasses = {
|
||||
"NSWindowController" : YES,
|
||||
"NSWorkspace" : YES,
|
||||
"NSPopover": YES,
|
||||
"NSAppearance" : YES
|
||||
"NSAppearance" : YES,
|
||||
"NSVisualEffectView" : YES,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user