Initial-Release
This commit is contained in:
141
plugins/cordova-plugin-statusbar/src/android/StatusBar.java
Normal file
141
plugins/cordova-plugin-statusbar/src/android/StatusBar.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
package org.apache.cordova.statusbar;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.apache.cordova.CordovaArgs;
|
||||
import org.apache.cordova.CordovaInterface;
|
||||
import org.apache.cordova.CordovaPlugin;
|
||||
import org.apache.cordova.CordovaWebView;
|
||||
import org.apache.cordova.PluginResult;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class StatusBar extends CordovaPlugin {
|
||||
private static final String TAG = "StatusBar";
|
||||
|
||||
/**
|
||||
* Sets the context of the Command. This can then be used to do things like
|
||||
* get file paths associated with the Activity.
|
||||
*
|
||||
* @param cordova The context of the main Activity.
|
||||
* @param webView The CordovaWebView Cordova is running in.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(final CordovaInterface cordova, CordovaWebView webView) {
|
||||
Log.v(TAG, "StatusBar: initialization");
|
||||
super.initialize(cordova, webView);
|
||||
|
||||
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Clear flag FLAG_FORCE_NOT_FULLSCREEN which is set initially
|
||||
// by the Cordova.
|
||||
Window window = cordova.getActivity().getWindow();
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
|
||||
// Read 'StatusBarBackgroundColor' from config.xml, default is #000000.
|
||||
setStatusBarBackgroundColor(preferences.getString("StatusBarBackgroundColor", "#000000"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the request and returns PluginResult.
|
||||
*
|
||||
* @param action The action to execute.
|
||||
* @param args JSONArry of arguments for the plugin.
|
||||
* @param callbackContext The callback id used when calling back into JavaScript.
|
||||
* @return True if the action was valid, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(final String action, final CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
||||
Log.v(TAG, "Executing action: " + action);
|
||||
final Activity activity = this.cordova.getActivity();
|
||||
final Window window = activity.getWindow();
|
||||
if ("_ready".equals(action)) {
|
||||
boolean statusBarVisible = (window.getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0;
|
||||
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, statusBarVisible));
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("show".equals(action)) {
|
||||
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("hide".equals(action)) {
|
||||
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("backgroundColorByHexString".equals(action)) {
|
||||
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setStatusBarBackgroundColor(args.getString(0));
|
||||
} catch (JSONException ignore) {
|
||||
Log.e(TAG, "Invalid hexString argument, use f.i. '#777777'");
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setStatusBarBackgroundColor(final String colorPref) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (colorPref != null && !colorPref.isEmpty()) {
|
||||
final Window window = cordova.getActivity().getWindow();
|
||||
// Method and constants not available on all SDKs but we want to be able to compile this code with any SDK
|
||||
window.clearFlags(0x04000000); // SDK 19: WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
window.addFlags(0x80000000); // SDK 21: WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
try {
|
||||
// Using reflection makes sure any 5.0+ device will work without having to compile with SDK level 21
|
||||
window.getClass().getDeclaredMethod("setStatusBarColor", int.class).invoke(window, Color.parseColor(colorPref));
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
Log.e(TAG, "Invalid hexString argument, use f.i. '#999999'");
|
||||
} catch (Exception ignore) {
|
||||
// this should not happen, only in case Android removes this method in a version > 21
|
||||
Log.w(TAG, "Method window.setStatusBarColor not found for SDK level " + Build.VERSION.SDK_INT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
plugins/cordova-plugin-statusbar/src/browser/statusbar.js
vendored
Normal file
45
plugins/cordova-plugin-statusbar/src/browser/statusbar.js
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var cordova = require('cordova');
|
||||
|
||||
function notSupported() {
|
||||
console.log('StatusBar is not supported');
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isVisible: false,
|
||||
styleBlackTranslucent:notSupported,
|
||||
styleDefault:notSupported,
|
||||
styleLightContent:notSupported,
|
||||
styleBlackOpaque:notSupported,
|
||||
overlaysWebView:notSupported,
|
||||
overlaysWebView: notSupported,
|
||||
styleDefault: notSupported,
|
||||
styleLightContect: notSupported,
|
||||
styleBlackTranslucent: notSupported,
|
||||
styleBlackOpaque: notSupported,
|
||||
backgroundColorByName: notSupported,
|
||||
backgroundColorByHexString: notSupported,
|
||||
hide: notSupported,
|
||||
show: notSupported
|
||||
};
|
||||
|
||||
49
plugins/cordova-plugin-statusbar/src/ios/CDVStatusBar.h
Normal file
49
plugins/cordova-plugin-statusbar/src/ios/CDVStatusBar.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
#import <Cordova/CDVInvokedUrlCommand.h>
|
||||
|
||||
@interface CDVStatusBar : CDVPlugin {
|
||||
@protected
|
||||
BOOL _statusBarOverlaysWebView;
|
||||
UIView* _statusBarBackgroundView;
|
||||
BOOL _uiviewControllerBasedStatusBarAppearance;
|
||||
UIColor* _statusBarBackgroundColor;
|
||||
NSString* _eventsCallbackId;
|
||||
}
|
||||
|
||||
@property (atomic, assign) BOOL statusBarOverlaysWebView;
|
||||
|
||||
- (void) overlaysWebView:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
- (void) styleDefault:(CDVInvokedUrlCommand*)command;
|
||||
- (void) styleLightContent:(CDVInvokedUrlCommand*)command;
|
||||
- (void) styleBlackTranslucent:(CDVInvokedUrlCommand*)command;
|
||||
- (void) styleBlackOpaque:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
- (void) backgroundColorByName:(CDVInvokedUrlCommand*)command;
|
||||
- (void) backgroundColorByHexString:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
- (void) hide:(CDVInvokedUrlCommand*)command;
|
||||
- (void) show:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
- (void) _ready:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
@end
|
||||
473
plugins/cordova-plugin-statusbar/src/ios/CDVStatusBar.m
Normal file
473
plugins/cordova-plugin-statusbar/src/ios/CDVStatusBar.m
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
NOTE: plugman/cordova cli should have already installed this,
|
||||
but you need the value UIViewControllerBasedStatusBarAppearance
|
||||
in your Info.plist as well to set the styles in iOS 7
|
||||
*/
|
||||
|
||||
#import "CDVStatusBar.h"
|
||||
#import <objc/runtime.h>
|
||||
#import <Cordova/CDVViewController.h>
|
||||
|
||||
static const void *kHideStatusBar = &kHideStatusBar;
|
||||
static const void *kStatusBarStyle = &kStatusBarStyle;
|
||||
|
||||
@interface CDVViewController (StatusBar)
|
||||
|
||||
@property (nonatomic, retain) id sb_hideStatusBar;
|
||||
@property (nonatomic, retain) id sb_statusBarStyle;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CDVViewController (StatusBar)
|
||||
|
||||
@dynamic sb_hideStatusBar;
|
||||
@dynamic sb_statusBarStyle;
|
||||
|
||||
- (id)sb_hideStatusBar {
|
||||
return objc_getAssociatedObject(self, kHideStatusBar);
|
||||
}
|
||||
|
||||
- (void)setSb_hideStatusBar:(id)newHideStatusBar {
|
||||
objc_setAssociatedObject(self, kHideStatusBar, newHideStatusBar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (id)sb_statusBarStyle {
|
||||
return objc_getAssociatedObject(self, kStatusBarStyle);
|
||||
}
|
||||
|
||||
- (void)setSb_statusBarStyle:(id)newStatusBarStyle {
|
||||
objc_setAssociatedObject(self, kStatusBarStyle, newStatusBarStyle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (BOOL) prefersStatusBarHidden {
|
||||
return [self.sb_hideStatusBar boolValue];
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return (UIStatusBarStyle)[self.sb_statusBarStyle intValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface CDVStatusBar () <UIScrollViewDelegate>
|
||||
- (void)fireTappedEvent;
|
||||
- (void)updateIsVisible:(BOOL)visible;
|
||||
@end
|
||||
|
||||
@implementation CDVStatusBar
|
||||
|
||||
- (id)settingForKey:(NSString*)key
|
||||
{
|
||||
return [self.commandDelegate.settings objectForKey:[key lowercaseString]];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
|
||||
{
|
||||
if ([keyPath isEqual:@"statusBarHidden"]) {
|
||||
NSNumber* newValue = [change objectForKey:NSKeyValueChangeNewKey];
|
||||
[self updateIsVisible:![newValue boolValue]];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)statusBarDidChangeFrame:(NSNotification*)notification
|
||||
{
|
||||
//add a small delay for iOS 7 ( 0.1 seconds )
|
||||
__weak CDVStatusBar* weakSelf = self;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
[weakSelf resizeWebView];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)pluginInitialize
|
||||
{
|
||||
BOOL isiOS7 = (IsAtLeastiOSVersion(@"7.0"));
|
||||
|
||||
// init
|
||||
NSNumber* uiviewControllerBasedStatusBarAppearance = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"];
|
||||
_uiviewControllerBasedStatusBarAppearance = (uiviewControllerBasedStatusBarAppearance == nil || [uiviewControllerBasedStatusBarAppearance boolValue]) && isiOS7;
|
||||
|
||||
// observe the statusBarHidden property
|
||||
[[UIApplication sharedApplication] addObserver:self forKeyPath:@"statusBarHidden" options:NSKeyValueObservingOptionNew context:NULL];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarDidChangeFrame:) name: UIApplicationDidChangeStatusBarFrameNotification object:nil];
|
||||
|
||||
_statusBarOverlaysWebView = YES; // default
|
||||
|
||||
[self initializeStatusBarBackgroundView];
|
||||
|
||||
self.viewController.view.autoresizesSubviews = YES;
|
||||
|
||||
NSString* setting;
|
||||
|
||||
setting = @"StatusBarBackgroundColor";
|
||||
if ([self settingForKey:setting]) {
|
||||
[self _backgroundColorByHexString:[self settingForKey:setting]];
|
||||
}
|
||||
|
||||
setting = @"StatusBarStyle";
|
||||
if ([self settingForKey:setting]) {
|
||||
[self setStatusBarStyle:[self settingForKey:setting]];
|
||||
}
|
||||
|
||||
// blank scroll view to intercept status bar taps
|
||||
self.webView.scrollView.scrollsToTop = NO;
|
||||
UIScrollView *fakeScrollView = [[UIScrollView alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
||||
fakeScrollView.delegate = self;
|
||||
fakeScrollView.scrollsToTop = YES;
|
||||
[self.viewController.view addSubview:fakeScrollView]; // Add scrollview to the view heirarchy so that it will begin accepting status bar taps
|
||||
[self.viewController.view sendSubviewToBack:fakeScrollView]; // Send it to the very back of the view heirarchy
|
||||
fakeScrollView.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height * 2.0f); // Make the scroll view longer than the screen itself
|
||||
fakeScrollView.contentOffset = CGPointMake(0.0f, UIScreen.mainScreen.bounds.size.height); // Scroll down so a tap will take scroll view back to the top
|
||||
}
|
||||
|
||||
- (void)onReset {
|
||||
_eventsCallbackId = nil;
|
||||
}
|
||||
|
||||
- (void)fireTappedEvent {
|
||||
if (_eventsCallbackId == nil) {
|
||||
return;
|
||||
}
|
||||
NSDictionary* payload = @{@"type": @"tap"};
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:payload];
|
||||
[result setKeepCallbackAsBool:YES];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId];
|
||||
}
|
||||
|
||||
- (void)updateIsVisible:(BOOL)visible {
|
||||
if (_eventsCallbackId == nil) {
|
||||
return;
|
||||
}
|
||||
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:visible];
|
||||
[result setKeepCallbackAsBool:YES];
|
||||
[self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId];
|
||||
}
|
||||
|
||||
- (void) _ready:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
_eventsCallbackId = command.callbackId;
|
||||
[self updateIsVisible:![UIApplication sharedApplication].statusBarHidden];
|
||||
NSString* setting = @"StatusBarOverlaysWebView";
|
||||
if ([self settingForKey:setting]) {
|
||||
self.statusBarOverlaysWebView = [(NSNumber*)[self settingForKey:setting] boolValue];
|
||||
if (self.statusBarOverlaysWebView) {
|
||||
[self resizeWebView];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) initializeStatusBarBackgroundView
|
||||
{
|
||||
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
|
||||
statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation];
|
||||
|
||||
_statusBarBackgroundView = [[UIView alloc] initWithFrame:statusBarFrame];
|
||||
_statusBarBackgroundView.backgroundColor = _statusBarBackgroundColor;
|
||||
_statusBarBackgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin);
|
||||
_statusBarBackgroundView.autoresizesSubviews = YES;
|
||||
}
|
||||
|
||||
- (CGRect) invertFrameIfNeeded:(CGRect)rect orientation:(UIInterfaceOrientation)orientation {
|
||||
// landscape is where (width > height). On iOS < 8, we need to invert since frames are
|
||||
// always in Portrait context
|
||||
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) && (rect.size.width < rect.size.height)) {
|
||||
CGFloat temp = rect.size.width;
|
||||
rect.size.width = rect.size.height;
|
||||
rect.size.height = temp;
|
||||
rect.origin = CGPointZero;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void) setStatusBarOverlaysWebView:(BOOL)statusBarOverlaysWebView
|
||||
{
|
||||
// we only care about the latest iOS version or a change in setting
|
||||
if (!IsAtLeastiOSVersion(@"7.0") || statusBarOverlaysWebView == _statusBarOverlaysWebView) {
|
||||
return;
|
||||
}
|
||||
|
||||
_statusBarOverlaysWebView = statusBarOverlaysWebView;
|
||||
|
||||
[self resizeWebView];
|
||||
|
||||
if (statusBarOverlaysWebView) {
|
||||
|
||||
[_statusBarBackgroundView removeFromSuperview];
|
||||
|
||||
} else {
|
||||
|
||||
[self initializeStatusBarBackgroundView];
|
||||
[self.webView.superview addSubview:_statusBarBackgroundView];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (BOOL) statusBarOverlaysWebView
|
||||
{
|
||||
return _statusBarOverlaysWebView;
|
||||
}
|
||||
|
||||
- (void) overlaysWebView:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
id value = [command argumentAtIndex:0];
|
||||
if (!([value isKindOfClass:[NSNumber class]])) {
|
||||
value = [NSNumber numberWithBool:YES];
|
||||
}
|
||||
|
||||
self.statusBarOverlaysWebView = [value boolValue];
|
||||
}
|
||||
|
||||
- (void) refreshStatusBarAppearance
|
||||
{
|
||||
SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
|
||||
if ([self.viewController respondsToSelector:sel]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
[self.viewController performSelector:sel withObject:nil];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setStyleForStatusBar:(UIStatusBarStyle)style
|
||||
{
|
||||
if (_uiviewControllerBasedStatusBarAppearance) {
|
||||
CDVViewController* vc = (CDVViewController*)self.viewController;
|
||||
vc.sb_statusBarStyle = [NSNumber numberWithInt:style];
|
||||
[self refreshStatusBarAppearance];
|
||||
|
||||
} else {
|
||||
[[UIApplication sharedApplication] setStatusBarStyle:style];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setStatusBarStyle:(NSString*)statusBarStyle
|
||||
{
|
||||
// default, lightContent, blackTranslucent, blackOpaque
|
||||
NSString* lcStatusBarStyle = [statusBarStyle lowercaseString];
|
||||
|
||||
if ([lcStatusBarStyle isEqualToString:@"default"]) {
|
||||
[self styleDefault:nil];
|
||||
} else if ([lcStatusBarStyle isEqualToString:@"lightcontent"]) {
|
||||
[self styleLightContent:nil];
|
||||
} else if ([lcStatusBarStyle isEqualToString:@"blacktranslucent"]) {
|
||||
[self styleBlackTranslucent:nil];
|
||||
} else if ([lcStatusBarStyle isEqualToString:@"blackopaque"]) {
|
||||
[self styleBlackOpaque:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) styleDefault:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
[self setStyleForStatusBar:UIStatusBarStyleDefault];
|
||||
}
|
||||
|
||||
- (void) styleLightContent:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
[self setStyleForStatusBar:UIStatusBarStyleLightContent];
|
||||
}
|
||||
|
||||
- (void) styleBlackTranslucent:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 70000
|
||||
# define TRANSLUCENT_STYLE UIStatusBarStyleBlackTranslucent
|
||||
#else
|
||||
# define TRANSLUCENT_STYLE UIStatusBarStyleLightContent
|
||||
#endif
|
||||
[self setStyleForStatusBar:TRANSLUCENT_STYLE];
|
||||
}
|
||||
|
||||
- (void) styleBlackOpaque:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 70000
|
||||
# define OPAQUE_STYLE UIStatusBarStyleBlackOpaque
|
||||
#else
|
||||
# define OPAQUE_STYLE UIStatusBarStyleLightContent
|
||||
#endif
|
||||
[self setStyleForStatusBar:OPAQUE_STYLE];
|
||||
}
|
||||
|
||||
- (void) backgroundColorByName:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
id value = [command argumentAtIndex:0];
|
||||
if (!([value isKindOfClass:[NSString class]])) {
|
||||
value = @"black";
|
||||
}
|
||||
|
||||
SEL selector = NSSelectorFromString([value stringByAppendingString:@"Color"]);
|
||||
if ([UIColor respondsToSelector:selector]) {
|
||||
_statusBarBackgroundView.backgroundColor = [UIColor performSelector:selector];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _backgroundColorByHexString:(NSString*)hexString
|
||||
{
|
||||
unsigned int rgbValue = 0;
|
||||
NSScanner* scanner = [NSScanner scannerWithString:hexString];
|
||||
[scanner setScanLocation:1];
|
||||
[scanner scanHexInt:&rgbValue];
|
||||
|
||||
_statusBarBackgroundColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
|
||||
_statusBarBackgroundView.backgroundColor = _statusBarBackgroundColor;
|
||||
}
|
||||
|
||||
- (void) backgroundColorByHexString:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
NSString* value = [command argumentAtIndex:0];
|
||||
if (!([value isKindOfClass:[NSString class]])) {
|
||||
value = @"#000000";
|
||||
}
|
||||
|
||||
if (![value hasPrefix:@"#"] || [value length] < 7) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self _backgroundColorByHexString:value];
|
||||
}
|
||||
|
||||
- (void) hideStatusBar
|
||||
{
|
||||
if (_uiviewControllerBasedStatusBarAppearance) {
|
||||
CDVViewController* vc = (CDVViewController*)self.viewController;
|
||||
vc.sb_hideStatusBar = [NSNumber numberWithBool:YES];
|
||||
[self refreshStatusBarAppearance];
|
||||
|
||||
} else {
|
||||
UIApplication* app = [UIApplication sharedApplication];
|
||||
[app setStatusBarHidden:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) hide:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
UIApplication* app = [UIApplication sharedApplication];
|
||||
|
||||
if (!app.isStatusBarHidden)
|
||||
{
|
||||
|
||||
[self hideStatusBar];
|
||||
|
||||
if (IsAtLeastiOSVersion(@"7.0")) {
|
||||
[_statusBarBackgroundView removeFromSuperview];
|
||||
}
|
||||
|
||||
[self resizeWebView];
|
||||
|
||||
_statusBarBackgroundView.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) showStatusBar
|
||||
{
|
||||
if (_uiviewControllerBasedStatusBarAppearance) {
|
||||
CDVViewController* vc = (CDVViewController*)self.viewController;
|
||||
vc.sb_hideStatusBar = [NSNumber numberWithBool:NO];
|
||||
[self refreshStatusBarAppearance];
|
||||
|
||||
} else {
|
||||
UIApplication* app = [UIApplication sharedApplication];
|
||||
[app setStatusBarHidden:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) show:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
UIApplication* app = [UIApplication sharedApplication];
|
||||
|
||||
if (app.isStatusBarHidden)
|
||||
{
|
||||
BOOL isIOS7 = (IsAtLeastiOSVersion(@"7.0"));
|
||||
|
||||
[self showStatusBar];
|
||||
|
||||
if (isIOS7) {
|
||||
|
||||
[self resizeWebView];
|
||||
|
||||
if (!self.statusBarOverlaysWebView) {
|
||||
|
||||
// there is a possibility that when the statusbar was hidden, it was in a different orientation
|
||||
// from the current one. Therefore we need to expand the statusBarBackgroundView as well to the
|
||||
// statusBar's current size
|
||||
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
|
||||
statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation];
|
||||
CGRect sbBgFrame = _statusBarBackgroundView.frame;
|
||||
sbBgFrame.size = statusBarFrame.size;
|
||||
_statusBarBackgroundView.frame = sbBgFrame;
|
||||
[self.webView.superview addSubview:_statusBarBackgroundView];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
CGRect bounds = [[UIScreen mainScreen] applicationFrame];
|
||||
self.viewController.view.frame = bounds;
|
||||
}
|
||||
|
||||
_statusBarBackgroundView.hidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)resizeWebView {
|
||||
|
||||
CGRect bounds = [[UIScreen mainScreen] bounds];
|
||||
|
||||
bounds = [self invertFrameIfNeeded:bounds orientation:self.viewController.interfaceOrientation];
|
||||
|
||||
if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) {
|
||||
self.viewController.view.frame = bounds;
|
||||
}
|
||||
|
||||
self.webView.frame = bounds;
|
||||
|
||||
if (!self.statusBarOverlaysWebView) {
|
||||
|
||||
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
|
||||
statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation];
|
||||
|
||||
CGRect frame = self.webView.frame;
|
||||
frame.origin.y = statusBarFrame.size.height;
|
||||
frame.size.height -= statusBarFrame.size.height;
|
||||
self.webView.frame = frame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[UIApplication sharedApplication] removeObserver:self forKeyPath:@"statusBarHidden"];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIApplicationDidChangeStatusBarFrameNotification];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
|
||||
{
|
||||
[self fireTappedEvent];
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
110
plugins/cordova-plugin-statusbar/src/windows/StatusBarProxy.js
vendored
Normal file
110
plugins/cordova-plugin-statusbar/src/windows/StatusBarProxy.js
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var _supported = null; // set to null so we can check first time
|
||||
|
||||
function isSupported() {
|
||||
// if not checked before, run check
|
||||
if (_supported == null) {
|
||||
var viewMan = Windows.UI.ViewManagement;
|
||||
_supported = (viewMan.StatusBar && viewMan.StatusBar.getForCurrentView);
|
||||
}
|
||||
return _supported;
|
||||
}
|
||||
|
||||
function getViewStatusBar() {
|
||||
if (!isSupported()) {
|
||||
throw new Error("Status bar is not supported");
|
||||
}
|
||||
return Windows.UI.ViewManagement.StatusBar.getForCurrentView();
|
||||
}
|
||||
|
||||
function hexToRgb(hex) {
|
||||
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
|
||||
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
|
||||
return r + r + g + g + b + b;
|
||||
});
|
||||
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
_ready: function(win, fail) {
|
||||
win(statusBar.occludedRect.height !== 0);
|
||||
},
|
||||
|
||||
overlaysWebView: function () {
|
||||
// not supported
|
||||
},
|
||||
|
||||
styleDefault: function () {
|
||||
// dark text ( to be used on a light background )
|
||||
if (isSupported()) {
|
||||
getViewStatusBar().foregroundColor = { a: 0, r: 0, g: 0, b: 0 };
|
||||
}
|
||||
},
|
||||
|
||||
styleLightContent: function () {
|
||||
// light text ( to be used on a dark background )
|
||||
if (isSupported()) {
|
||||
getViewStatusBar().foregroundColor = { a: 0, r: 255, g: 255, b: 255 };
|
||||
}
|
||||
},
|
||||
|
||||
styleBlackTranslucent: function () {
|
||||
// #88000000 ? Apple says to use lightContent instead
|
||||
return module.exports.styleLightContent();
|
||||
},
|
||||
|
||||
styleBlackOpaque: function () {
|
||||
// #FF000000 ? Apple says to use lightContent instead
|
||||
return module.exports.styleLightContent();
|
||||
},
|
||||
|
||||
backgroundColorByHexString: function (win, fail, args) {
|
||||
var rgb = hexToRgb(args[0]);
|
||||
if(isSupported()) {
|
||||
var statusBar = getViewStatusBar();
|
||||
statusBar.backgroundColor = { a: 0, r: rgb.r, g: rgb.g, b: rgb.b };
|
||||
statusBar.backgroundOpacity = 1;
|
||||
}
|
||||
},
|
||||
|
||||
show: function (win, fail) {
|
||||
// added support check so no error thrown, when calling this method
|
||||
if (isSupported()) {
|
||||
getViewStatusBar().showAsync().done(win, fail);
|
||||
}
|
||||
},
|
||||
|
||||
hide: function (win, fail) {
|
||||
// added support check so no error thrown, when calling this method
|
||||
if (isSupported()) {
|
||||
getViewStatusBar().hideAsync().done(win, fail);
|
||||
}
|
||||
}
|
||||
};
|
||||
require("cordova/exec/proxy").add("StatusBar", module.exports);
|
||||
141
plugins/cordova-plugin-statusbar/src/wp/StatusBar.cs
Normal file
141
plugins/cordova-plugin-statusbar/src/wp/StatusBar.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
using Microsoft.Phone.Shell;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
|
||||
/*
|
||||
* http://www.idev101.com/code/User_Interface/StatusBar.html
|
||||
* https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/Bars.html
|
||||
* https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html#//apple_ref/c/econst/UIStatusBarStyleDefault
|
||||
* */
|
||||
|
||||
|
||||
namespace WPCordovaClassLib.Cordova.Commands
|
||||
{
|
||||
public class StatusBar : BaseCommand
|
||||
{
|
||||
|
||||
// returns an argb value, if the hex is only rgb, it will be full opacity
|
||||
protected Color ColorFromHex(string hexString)
|
||||
{
|
||||
string cleanHex = hexString.Replace("#", "").Replace("0x", "");
|
||||
// turn #FFF into #FFFFFF
|
||||
if (cleanHex.Length == 3)
|
||||
{
|
||||
cleanHex = "" + cleanHex[0] + cleanHex[0] + cleanHex[1] + cleanHex[1] + cleanHex[2] + cleanHex[2];
|
||||
}
|
||||
// add an alpha 100% if it is missing
|
||||
if (cleanHex.Length == 6)
|
||||
{
|
||||
cleanHex = "FF" + cleanHex;
|
||||
}
|
||||
int argb = Int32.Parse(cleanHex, NumberStyles.HexNumber);
|
||||
Color clr = Color.FromArgb((byte)((argb & 0xff000000) >> 0x18),
|
||||
(byte)((argb & 0xff0000) >> 0x10),
|
||||
(byte)((argb & 0xff00) >> 8),
|
||||
(byte)(argb & 0xff));
|
||||
return clr;
|
||||
}
|
||||
|
||||
public void _ready(string options)
|
||||
{
|
||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
bool isVis = SystemTray.IsVisible;
|
||||
// TODO: pass this to JS
|
||||
//Debug.WriteLine("Result::" + res);
|
||||
DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isVis));
|
||||
});
|
||||
}
|
||||
|
||||
public void overlaysWebView(string options)
|
||||
{ //exec(null, null, "StatusBar", "overlaysWebView", [doOverlay]);
|
||||
// string arg = JSON.JsonHelper.Deserialize<string[]>(options)[0];
|
||||
}
|
||||
|
||||
public void styleDefault(string options)
|
||||
{ //exec(null, null, "StatusBar", "styleDefault", []);
|
||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
SystemTray.ForegroundColor = Colors.Black;
|
||||
});
|
||||
}
|
||||
|
||||
public void styleLightContent(string options)
|
||||
{ //exec(null, null, "StatusBar", "styleLightContent", []);
|
||||
|
||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
SystemTray.ForegroundColor = Colors.White;
|
||||
});
|
||||
}
|
||||
|
||||
public void styleBlackTranslucent(string options)
|
||||
{ //exec(null, null, "StatusBar", "styleBlackTranslucent", []);
|
||||
styleLightContent(options);
|
||||
}
|
||||
|
||||
public void styleBlackOpaque(string options)
|
||||
{ //exec(null, null, "StatusBar", "styleBlackOpaque", []);
|
||||
styleLightContent(options);
|
||||
}
|
||||
|
||||
public void backgroundColorByName(string options)
|
||||
{ //exec(null, null, "StatusBar", "backgroundColorByName", [colorname]);
|
||||
// this should NOT be called, js should now be using/converting color names to hex
|
||||
}
|
||||
|
||||
public void backgroundColorByHexString(string options)
|
||||
{ //exec(null, null, "StatusBar", "backgroundColorByHexString", [hexString]);
|
||||
string argb = JSON.JsonHelper.Deserialize<string[]>(options)[0];
|
||||
|
||||
Color clr = ColorFromHex(argb);
|
||||
|
||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
SystemTray.Opacity = clr.A / 255.0d;
|
||||
SystemTray.BackgroundColor = clr;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void hide(string options)
|
||||
{ //exec(null, null, "StatusBar", "hide", []);
|
||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
SystemTray.IsVisible = false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void show(string options)
|
||||
{ //exec(null, null, "StatusBar", "show", []);
|
||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
SystemTray.IsVisible = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user