diff --git a/src/android/ThemeableBrowser.java b/src/android/ThemeableBrowser.java index 673e0d828..86f49c2a6 100644 --- a/src/android/ThemeableBrowser.java +++ b/src/android/ThemeableBrowser.java @@ -106,6 +106,8 @@ public class ThemeableBrowser extends CordovaPlugin { private ThemeableBrowserDialog dialog; private WebView inAppWebView; + private LinearLayout leftButtonContainer; + private LinearLayout rightButtonContainer; private EditText edittext; private CallbackContext callbackContext; @@ -252,7 +254,12 @@ public void run() { }); } } - else { + else if (action.equals("changeButtonImage")) { + final int buttonIndex = args.getInt(0); + BrowserButton buttonProps = parseButtonProps(args.getString(1)); + this.changeButtonImage(buttonIndex, buttonProps); + } + else { return false; } return true; @@ -581,15 +588,17 @@ public void run() { } // Left Button Container layout - LinearLayout leftButtonContainer = new LinearLayout(cordova.getActivity()); - FrameLayout.LayoutParams leftButtonContainerParams = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + leftButtonContainer = new LinearLayout(cordova.getActivity()); + FrameLayout.LayoutParams leftButtonContainerParams = new FrameLayout.LayoutParams( + LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); leftButtonContainerParams.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; leftButtonContainer.setLayoutParams(leftButtonContainerParams); leftButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); // Right Button Container layout - LinearLayout rightButtonContainer = new LinearLayout(cordova.getActivity()); - FrameLayout.LayoutParams rightButtonContainerParams = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + rightButtonContainer = new LinearLayout(cordova.getActivity()); + FrameLayout.LayoutParams rightButtonContainerParams = new FrameLayout.LayoutParams( + LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rightButtonContainerParams.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL; rightButtonContainer.setLayoutParams(rightButtonContainerParams); rightButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); @@ -1133,8 +1142,63 @@ private void setBackground(View view, Drawable drawable) { } } - private Button createButton(BrowserButton buttonProps, String description, - View.OnClickListener listener) { + private void changeButtonImage(int buttonIndex, BrowserButton buttonProps) { + Resources activityRes = cordova.getActivity().getResources(); + File file = new File("www", buttonProps.wwwImage); + InputStream is = null; + BitmapDrawable drawable; + Button view; + if (ALIGN_RIGHT.equals(buttonProps.align)) { + //rightButtonContainer + view = (Button) rightButtonContainer.getChildAt(buttonIndex); + } else { + //leftButtonContainer + view = (Button) leftButtonContainer.getChildAt(buttonIndex); + } + + if (file != null) { + try { + is = cordova.getActivity().getAssets().open(file.getPath()); + Bitmap bitmap = BitmapFactory.decodeStream(is); + bitmap.setDensity((int) (DisplayMetrics.DENSITY_MEDIUM * buttonProps.wwwImageDensity)); + drawable = new BitmapDrawable(activityRes, bitmap); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + view.setBackgroundDrawable(drawable); + } else { + view.setBackground(drawable); + } + } catch (IOException ex) { + Log.e(LOG_TAG, ex.getMessage()); + } finally { + try { + is.close(); + } catch (Exception e) { + } + } + } + } + + private BrowserButton parseButtonProps(String buttonProps) { + BrowserButton result = null; + if (buttonProps != null && !buttonProps.isEmpty()) { + try { + result = ThemeableBrowserUnmarshaller.JSONToObj(buttonProps, BrowserButton.class); + } catch (Exception e) { + emitError(ERR_CRITICAL, String.format("Invalid JSON @s", e.toString())); + } + } else { + emitWarning(WRN_UNDEFINED, "No config was given."); + } + + if (result == null) { + result = new BrowserButton(); + } + + return result; + } + + private Button createButton(BrowserButton buttonProps, String description, View.OnClickListener listener) { Button result = null; if (buttonProps != null) { result = new Button(cordova.getActivity()); diff --git a/src/ios/CDVThemeableBrowser.h b/src/ios/CDVThemeableBrowser.h index ed59e22f1..06067688c 100644 --- a/src/ios/CDVThemeableBrowser.h +++ b/src/ios/CDVThemeableBrowser.h @@ -77,6 +77,7 @@ - (void)show:(CDVInvokedUrlCommand*)command; - (void)show:(CDVInvokedUrlCommand*)command withAnimation:(BOOL)animated; - (void)reload:(CDVInvokedUrlCommand*)command; +- (void)changeButtonImage:(CDVInvokedUrlCommand*)command; @end @@ -120,6 +121,7 @@ - (void)showLocationBar:(BOOL)show; - (void)showToolBar:(BOOL)show : (NSString*) toolbarPosition; - (void)setCloseButtonTitle:(NSString*)title; +- (void)changeButtonImage:(int)buttonIndex buttonProps:(NSDictionary*)buttonProps; - (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVThemeableBrowserOptions*) browserOptions navigationDelete:(CDVThemeableBrowser*) navigationDelegate statusBarStyle:(UIStatusBarStyle) statusBarStyle; diff --git a/src/ios/CDVThemeableBrowser.m b/src/ios/CDVThemeableBrowser.m index ce09b20ce..fbdab2ecf 100644 --- a/src/ios/CDVThemeableBrowser.m +++ b/src/ios/CDVThemeableBrowser.m @@ -57,6 +57,7 @@ Licensed to the Apache Software Foundation (ASF) under one #define TOOLBAR_DEF_HEIGHT 44.0 #define LOCATIONBAR_HEIGHT 21.0 #define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT)) +#define TAG_SALT 100 #pragma mark CDVThemeableBrowser @@ -66,6 +67,8 @@ @interface CDVThemeableBrowser () { NSURL *initUrl; // initial URL ThemeableBrowser opened with NSURL *originalUrl; } +@property (nonatomic,strong) dispatch_source_t timer; + @end @implementation CDVThemeableBrowser @@ -103,6 +106,8 @@ - (void)close:(CDVInvokedUrlCommand*)command withMessage:@"Close called but already closed."]; return; } + + dispatch_source_cancel(_timer); // Things are cleaned up in browserExit. [self.themeableBrowserViewController close]; } @@ -129,7 +134,7 @@ - (void)open:(CDVInvokedUrlCommand*)command NSString* url = [command argumentAtIndex:0]; NSString* target = [command argumentAtIndex:1 withDefault:kThemeableBrowserTargetSelf]; NSString* options = [command argumentAtIndex:2 withDefault:@"" andClass:[NSString class]]; - + self.callbackId = command.callbackId; if (url != nil) { @@ -161,6 +166,19 @@ - (void)open:(CDVInvokedUrlCommand*)command [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + NSTimeInterval delayTime=3.0f; + NSTimeInterval timeInterval=1.0f; + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); + dispatch_time_t startDelayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)); + dispatch_source_set_timer(_timer, startDelayTime, timeInterval * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC); + dispatch_source_set_event_handler(_timer, ^{ + CDVPluginResult* pluginResult; + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }); + dispatch_resume(_timer); } - (void)reload:(CDVInvokedUrlCommand*)command @@ -170,6 +188,14 @@ - (void)reload:(CDVInvokedUrlCommand*)command } } +- (void)changeButtonImage:(CDVInvokedUrlCommand *)command { + if (self.themeableBrowserViewController) { + NSInteger buttonIndex = [[command.arguments objectAtIndex:0] integerValue]; + NSDictionary* buttonProps = [command.arguments objectAtIndex:1];; + [self.themeableBrowserViewController changeButtonImage:buttonIndex buttonProps:buttonProps]; + } +} + - (CDVThemeableBrowserOptions*)parseOptions:(NSString*)options { CDVThemeableBrowserOptions* obj = [[CDVThemeableBrowserOptions alloc] init]; @@ -607,7 +633,7 @@ - (void)emitEvent:(NSDictionary*)event CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:event]; [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; } } @@ -835,12 +861,12 @@ - (void)createViews NSArray* customButtons = _browserOptions.customButtons; if (customButtons) { - NSInteger cnt = 0; + NSInteger cnt = [customButtons count]-1; // Reverse loop because we are laying out from outer to inner. for (NSDictionary* customButton in [customButtons reverseObjectEnumerator]) { UIButton* button = [self createButton:customButton action:@selector(goCustomButton:) withDescription:[NSString stringWithFormat:@"custom button at %ld", (long)cnt]]; if (button) { - button.tag = cnt; + button.tag = cnt+TAG_SALT; CGFloat width = [self getWidthFromButton:button]; if ([kThemeableBrowserAlignRight isEqualToString:customButton[kThemeableBrowserPropAlign]]) { [rightButtons addObject:button]; @@ -851,7 +877,7 @@ - (void)createViews } } - cnt += 1; + cnt -= 1; } } @@ -1196,6 +1222,17 @@ - (void)reload [self.webView reload]; } +- (void)changeButtonImage:(NSInteger) buttonIndex buttonProps:(NSDictionary *)buttonProps { + + UIButton* button = (UIButton *)[self.toolbar viewWithTag:buttonIndex+TAG_SALT]; + UIImage *image = [self getImage:buttonProps[kThemeableBrowserPropImage] + altPath:buttonProps[kThemeableBrowserPropWwwImage] + altDensity:[buttonProps[kThemeableBrowserPropWwwImageDensity] doubleValue]]; + if(button && image){ + [button setImage:image forState:UIControlStateNormal]; + } +} + - (void)navigateTo:(NSURL*)url { NSURLRequest* request = [NSURLRequest requestWithURL:url]; @@ -1234,7 +1271,7 @@ - (void)goForward:(id)sender - (void)goCustomButton:(id)sender { UIButton* button = sender; - NSInteger index = button.tag; + NSInteger index = button.tag-TAG_SALT; [self emitEventForButton:_browserOptions.customButtons[index] withIndex:[NSNumber numberWithLong:index]]; } diff --git a/www/themeablebrowser.js b/www/themeablebrowser.js index a6931bf4d..e2e7fae3d 100644 --- a/www/themeablebrowser.js +++ b/www/themeablebrowser.js @@ -80,6 +80,10 @@ ThemeableBrowser.prototype = { throw new Error('insertCSS requires exactly one of code or file to be specified'); } return this; + }, + + changeButtonImage: function(buttonIndex, buttonProps){ + exec(null, null, 'ThemeableBrowser', 'changeButtonImage', [buttonIndex, buttonProps]); } };