@Override
  public void processProperties(KrollDict d) {

    if (d.containsKey(TiC.PROPERTY_PAGE_WIDTH)) {
      setPageWidth(d.get(TiC.PROPERTY_PAGE_WIDTH));
    }
    if (d.containsKey(TiC.PROPERTY_PAGE_OFFSET)) {
      setPageOffset(d.get(TiC.PROPERTY_PAGE_OFFSET));
    }

    if (d.containsKey(TiC.PROPERTY_VIEWS)) {
      setViews(d.get(TiC.PROPERTY_VIEWS));
    }

    if (d.containsKey(TiC.PROPERTY_CURRENT_PAGE)) {
      int page = d.optInt(TiC.PROPERTY_CURRENT_PAGE, 0);
      if (page > 0) {
        setCurrentPage(page);
      }
    }

    if (d.containsKey(TiC.PROPERTY_SHOW_PAGING_CONTROL)) {
      if (TiConvert.toBoolean(d, TiC.PROPERTY_SHOW_PAGING_CONTROL)) {
        showPager();
      }
    }

    if (d.containsKey(TiC.PROPERTY_SCROLLING_ENABLED)) {
      mEnabled = TiConvert.toBoolean(d, TiC.PROPERTY_SCROLLING_ENABLED);
    }

    if (d.containsKey(TiC.PROPERTY_OVER_SCROLL_MODE)) {
      if (Build.VERSION.SDK_INT >= 9) {
        mPager.setOverScrollMode(
            TiConvert.toInt(d.get(TiC.PROPERTY_OVER_SCROLL_MODE), View.OVER_SCROLL_ALWAYS));
      }
    }

    if (d.containsKey(TiC.PROPERTY_CACHE_SIZE)) {
      cacheSize = TiConvert.toInt(d, TiC.PROPERTY_CACHE_SIZE);
      if (cacheSize < 3) {
        // WHAT.  Let's make it something sensible.
        cacheSize = 3;
      }
      updateCacheSize();
    }

    if (d.containsKey(TiC.PROPERTY_TRANSITION)) {
      transition =
          TransitionHelper.transitionFromObject(
              (HashMap) d.get(TiC.PROPERTY_TRANSITION), null, null);
      mPager.updatePageTransformer();
    }
    super.processProperties(d);
  }
  @Kroll.method
  public void show(KrollDict args) {
    Log.d(TAG, "show called");

    final Crouton crouton;

    Activity activity;
    String text = "";
    Style style = null;
    Builder config = new Configuration.Builder();

    if (args.containsKey(TiC.PROPERTY_ACTIVITY)) {
      ActivityProxy activityProxy = (ActivityProxy) args.get(TiC.PROPERTY_ACTIVITY);
      activity = activityProxy.getActivity();
    } else {
      activity = TiApplication.getInstance().getCurrentActivity();
    }

    if (args.containsKey(TiC.PROPERTY_TEXT)) {
      text = TiConvert.toString(args.get(TiC.PROPERTY_TEXT));
    }

    if (args.containsKey(TiC.PROPERTY_STYLE)) {
      style = getStyle(TiConvert.toInt(args.get(TiC.PROPERTY_STYLE)));
    }

    if (args.containsKey(TiC.PROPERTY_COLOR)) {

      String color = (String) args.get(TiC.PROPERTY_COLOR);

      style = new Style.Builder().setBackgroundColorValue(TiConvert.toColor(color)).build();
    }

    if (style == null) {
      style = Style.INFO;
    }

    crouton = Crouton.makeText(activity, text, style);

    if (args.containsKey(TiC.PROPERTY_DURATION)) {
      config.setDuration(TiConvert.toInt(args.get(TiC.PROPERTY_DURATION)));
      crouton.setConfiguration(config.build());
    }

    TiUIHelper.runUiDelayedIfBlock(
        new Runnable() {
          @Override
          public void run() {
            crouton.show();
          }
        });
  }
  protected void handleAddRoute(HashMap routeMap) {
    Object routeArray = routeMap.get("points");
    if (routeArray instanceof Object[]) {
      Object[] routes = (Object[]) routeArray;
      MapPoint[] pointsType = new MapPoint[routes.length];
      for (int i = 0; i < routes.length; i++) {

        if (routes[i] instanceof HashMap) {
          HashMap tempRoute = (HashMap) routes[i];
          MapPoint mp =
              new MapPoint(
                  TiConvert.toDouble(tempRoute, "latitude"),
                  TiConvert.toDouble(tempRoute, "longitude"));
          pointsType[i] = mp;
        }
      }

      MapRoute mr =
          new MapRoute(
              pointsType,
              TiConvert.toColor(routeMap, "color"),
              TiConvert.toInt(routeMap, "width"),
              TiConvert.toString(routeMap, "name"));

      if (mapView == null) {
        this.routes.add(mr);
      } else {
        mapView.addRoute(mr);
      }
    }
  }
 @Override
 public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) {
   if ("volume".equals(key)) {
     setVolume(TiConvert.toFloat(newValue));
   } else if ("time".equals(key)) {
     setTime(TiConvert.toInt(newValue));
   }
 }
Example #5
0
  public Integer optInt(String key, Integer defaultValue) {
    Integer result = defaultValue;

    if (containsKey(key)) {
      result = TiConvert.toInt(get(key), defaultValue);
    }
    return result;
  }
  @Kroll.method
  public Crouton make(KrollDict args) {
    Log.d(TAG, "make called");

    Crouton crouton;

    Activity activity;
    String text = "";
    Style style = null;
    Builder config = new Configuration.Builder();

    if (args.containsKey(TiC.PROPERTY_ACTIVITY)) {
      ActivityProxy activityProxy = (ActivityProxy) args.get(TiC.PROPERTY_ACTIVITY);
      activity = activityProxy.getActivity();
    } else {
      activity = TiApplication.getInstance().getCurrentActivity();
    }

    if (args.containsKey(TiC.PROPERTY_TEXT)) {
      text = TiConvert.toString(args.get(TiC.PROPERTY_TEXT));
    }

    if (args.containsKey(TiC.PROPERTY_STYLE)) {
      style = getStyle(TiConvert.toInt(args.get(TiC.PROPERTY_STYLE)));
    }

    if (args.containsKey(TiC.PROPERTY_COLOR)) {

      String color = (String) args.get(TiC.PROPERTY_COLOR);

      style = new Style.Builder().setBackgroundColorValue(TiConvert.toColor(color)).build();
    }

    if (style == null) {
      style = Style.INFO;
    }

    crouton = Crouton.makeText(activity, text, style);

    if (args.containsKey(TiC.PROPERTY_DURATION)) {
      config.setDuration(TiConvert.toInt(args.get(TiC.PROPERTY_DURATION)));
      crouton.setConfiguration(config.build());
    }

    return crouton;
  }
  @Kroll.method
  @Kroll.getProperty
  public int getPluginState() {
    int pluginState = TiUIWebView.PLUGIN_STATE_OFF;

    if (hasProperty(TiC.PROPERTY_PLUGIN_STATE)) {
      pluginState = TiConvert.toInt(getProperty(TiC.PROPERTY_PLUGIN_STATE));
    }

    return pluginState;
  }
  @Override
  public void processProperties(KrollDict d) {
    if (d.containsKey("volume")) {
      setVolume(TiConvert.toFloat(d, "volume"));
    } else {
      setVolume(0.5f);
    }

    if (d.containsKey("time")) {
      setTime(TiConvert.toInt(d, "time"));
    }
  }
 /**
  * Check whether the called view is a text editor, in which case it would make sense to
  * automatically display a soft input window for it.
  */
 @Override
 public boolean onCheckIsTextEditor() {
   if (proxy.hasProperty(TiC.PROPERTY_SOFT_KEYBOARD_ON_FOCUS)
       && TiConvert.toInt(proxy.getProperty(TiC.PROPERTY_SOFT_KEYBOARD_ON_FOCUS))
           == TiUIView.SOFT_KEYBOARD_HIDE_ON_FOCUS) {
     return false;
   }
   if (proxy.hasProperty(TiC.PROPERTY_EDITABLE)
       && !(TiConvert.toBoolean(proxy.getProperty(TiC.PROPERTY_EDITABLE)))) {
     return false;
   }
   return true;
 }
 protected void didProcessProperties() {
   if ((mProcessUpdateFlags & TIFLAG_NEEDS_OPTIONS) != 0) {
     clearDialog();
     getBuilder().setView(null);
     String[] optionText = TiConvert.toStringArray(proxy.getProperty(TiC.PROPERTY_OPTIONS));
     int selectedIndex = TiConvert.toInt(proxy.getProperty(TiC.PROPERTY_SELECTED_INDEX), -1);
     if (selectedIndex >= optionText.length) {
       selectedIndex = -1;
     }
     processOptions(optionText, selectedIndex);
     mProcessUpdateFlags &= ~TIFLAG_NEEDS_OPTIONS;
   }
   super.didProcessProperties();
 }
  @Override
  public void propertySet(String key, Object newValue, Object oldValue, boolean changedProperty) {
    switch (key) {
      case TiC.PROPERTY_MESSAGE:
        message = TiConvert.toString(newValue);
        break;

      case TiC.PROPERTY_DURATION:
        toast.setDuration(TiConvert.toInt(newValue));
        break;

      case "verticalMargin":
        verticalMargin = TiConvert.toFloat(newValue, verticalMargin);
        toast.setMargin(horizontalMargin, verticalMargin);
        break;

      case "horizontalMargin":
        horizontalMargin = TiConvert.toFloat(newValue, horizontalMargin);
        toast.setMargin(horizontalMargin, verticalMargin);
        break;
      case "offsetX":
        offsetX = TiConvert.toInt(newValue, offsetX);
        toast.setGravity(gravity, offsetX, offsetY);
        break;
      case "offsetY":
        offsetY = TiConvert.toInt(newValue, offsetY);
        toast.setGravity(gravity, offsetX, offsetY);
        break;
      case "gravity":
        gravity = TiConvert.toInt(newValue, gravity);
        toast.setGravity(gravity, offsetX, offsetY);
        break;
      default:
        super.propertySet(key, newValue, oldValue, changedProperty);
        break;
    }
  }
Example #12
0
  protected void initialize() throws IOException {
    try {
      mp = new MediaPlayer();
      String url = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_URL));
      if (URLUtil.isAssetUrl(url)) {
        Context context = proxy.getTiContext().getTiApp();
        String path = url.substring(TiConvert.ASSET_URL.length());
        AssetFileDescriptor afd = null;
        try {
          afd = context.getAssets().openFd(path);
          // Why mp.setDataSource(afd) doesn't work is a problem for another day.
          // http://groups.google.com/group/android-developers/browse_thread/thread/225c4c150be92416
          mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        } catch (IOException e) {
          Log.e(LCAT, "Error setting file descriptor: ", e);
        } finally {
          if (afd != null) {
            afd.close();
          }
        }
      } else {
        Uri uri = Uri.parse(url);
        if (uri.getScheme().equals(TiC.PROPERTY_FILE)) {
          mp.setDataSource(uri.getPath());
        } else {
          remote = true;
          mp.setDataSource(url);
        }
      }

      mp.setLooping(looping);
      mp.setOnCompletionListener(this);
      mp.setOnErrorListener(this);
      mp.setOnInfoListener(this);
      mp.setOnBufferingUpdateListener(this);

      mp.prepare(); // Probably need to allow for Async
      setState(STATE_INITIALIZED);

      setVolume(volume);
      if (proxy.hasProperty(TiC.PROPERTY_TIME)) {
        setTime(TiConvert.toInt(proxy.getProperty(TiC.PROPERTY_TIME)));
      }
    } catch (Throwable t) {
      Log.w(LCAT, "Issue while initializing : ", t);
      release();
      setState(STATE_STOPPED);
    }
  }
 private void setPaintOptions() {
   tiPaint = new Paint();
   tiPaint.setAntiAlias(true);
   tiPaint.setDither(true);
   tiPaint.setColor(
       (props.containsKeyAndNotNull("strokeColor"))
           ? TiConvert.toColor(props, "strokeColor")
           : TiConvert.toColor("black"));
   tiPaint.setStyle(Paint.Style.STROKE);
   tiPaint.setStrokeJoin(Paint.Join.ROUND);
   tiPaint.setStrokeCap(Paint.Cap.ROUND);
   tiPaint.setStrokeWidth(
       (props.containsKeyAndNotNull("strokeWidth"))
           ? TiConvert.toFloat(props.get("strokeWidth"))
           : 12);
   tiPaint.setAlpha(
       (props.containsKeyAndNotNull("strokeAlpha"))
           ? TiConvert.toInt(props.get("strokeAlpha"))
           : 255);
   alphaState =
       (props.containsKeyAndNotNull("strokeAlpha"))
           ? TiConvert.toInt(props.get("strokeAlpha"))
           : 255;
 }
 @Override
 public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) {
   if (TiC.PROPERTY_CURRENT_PAGE.equals(key)) {
     setCurrentPage(TiConvert.toInt(newValue));
   } else if (TiC.PROPERTY_SHOW_PAGING_CONTROL.equals(key)) {
     boolean show = TiConvert.toBoolean(newValue);
     if (show) {
       showPager();
     } else {
       hidePager();
     }
   } else if (TiC.PROPERTY_SCROLLING_ENABLED.equals(key)) {
     mEnabled = TiConvert.toBoolean(newValue);
   } else if (TiC.PROPERTY_OVER_SCROLL_MODE.equals(key)) {
     if (Build.VERSION.SDK_INT >= 9) {
       mPager.setOverScrollMode(TiConvert.toInt(newValue, View.OVER_SCROLL_ALWAYS));
     }
   } else if (TiC.PROPERTY_CACHE_SIZE.equals(key)) {
     cacheSize = TiConvert.toInt(newValue);
     if (cacheSize < 3) {
       // WHAT.  Let's make it something sensible.
       cacheSize = 3;
     }
     updateCacheSize();
   } else if (TiC.PROPERTY_PAGE_WIDTH.equals(key)) {
     setPageWidth(newValue);
   } else if (TiC.PROPERTY_PAGE_OFFSET.equals(key)) {
     setPageOffset(newValue);
   } else if (TiC.PROPERTY_TRANSITION.equals(key)) {
     transition = TransitionHelper.transitionFromObject((HashMap) newValue, null, null);
     mPager.updatePageTransformer();
     nativeView.invalidate();
   } else {
     super.propertyChanged(key, oldValue, newValue, proxy);
   }
 }
 public void removeView(Object view) {
   if (view instanceof Number) {
     int viewIndex = TiConvert.toInt(view);
     if (viewIndex >= 0 && viewIndex < mViews.size()) {
       mViews.remove(viewIndex);
       getProxy().setProperty(TiC.PROPERTY_VIEWS, mViews.toArray());
       mAdapter.notifyDataSetChanged();
     }
   } else if (view instanceof TiViewProxy) {
     TiViewProxy proxy = (TiViewProxy) view;
     if (mViews.contains(proxy)) {
       mViews.remove(proxy);
       getProxy().setProperty(TiC.PROPERTY_VIEWS, mViews.toArray());
       mAdapter.notifyDataSetChanged();
     }
   }
 }
  @Kroll.getProperty
  @Kroll.method
  public TabProxy getActiveTab() {
    TabProxy activeTab = null;

    if (peekView() != null) {
      TiUITabGroup tg = (TiUITabGroup) peekView();
      int activeTabIndex = tg.getActiveTab();

      if (activeTabIndex < 0) {
        Log.e(LCAT, "unable to get active tab, invalid index returned: " + activeTabIndex);
      } else if (activeTabIndex >= tabs.size()) {
        Log.e(LCAT, "unable to get active tab, index is larger than tabs array: " + activeTabIndex);
      }
      activeTab = tabs.get(activeTabIndex);
    } else {
      if (initialActiveTab instanceof Number) {
        int tabsIndex = TiConvert.toInt(initialActiveTab);
        if (tabsIndex >= tabs.size()) {
          activeTab = tabs.get(tabsIndex);
        } else {
          Log.e(LCAT, "Unable to get active tab, initialActiveTab index is larger than tabs array");
        }
      } else if (initialActiveTab instanceof TabProxy) {
        activeTab = (TabProxy) initialActiveTab;
      } else {
        Log.e(LCAT, "Unable to get active tab, initialActiveTab is not recognized");
      }
    }

    if (activeTab == null) {
      String errorMessage =
          "Failed to get activeTab, make sure tabs are added first before calling getActiveTab()";
      Log.e(LCAT, errorMessage);
      throw new RuntimeException(errorMessage);
    }
    return activeTab;
  }
  @Kroll.method
  public void showCamera(@SuppressWarnings("rawtypes") HashMap options) {
    Activity activity = TiApplication.getInstance().getCurrentActivity();

    Log.d(TAG, "showCamera called", Log.DEBUG_MODE);

    KrollFunction successCallback = null;
    KrollFunction cancelCallback = null;
    KrollFunction errorCallback = null;
    boolean autohide = true;
    boolean saveToPhotoGallery = false;

    if (options.containsKey("success")) {
      successCallback = (KrollFunction) options.get("success");
    }
    if (options.containsKey("cancel")) {
      cancelCallback = (KrollFunction) options.get("cancel");
    }
    if (options.containsKey("error")) {
      errorCallback = (KrollFunction) options.get("error");
    }

    Object autohideOption = options.get("autohide");
    if (autohideOption != null) {
      autohide = TiConvert.toBoolean(autohideOption);
    }

    Object saveToPhotoGalleryOption = options.get("saveToPhotoGallery");
    if (saveToPhotoGalleryOption != null) {
      saveToPhotoGallery = TiConvert.toBoolean(saveToPhotoGalleryOption);
    }

    // Use our own custom camera activity when an overlay is provided.
    if (options.containsKey("overlay")) {
      TiCameraActivity.overlayProxy = (TiViewProxy) options.get("overlay");

      TiCameraActivity.callbackContext = getKrollObject();
      TiCameraActivity.successCallback = successCallback;
      TiCameraActivity.errorCallback = errorCallback;
      TiCameraActivity.cancelCallback = cancelCallback;
      TiCameraActivity.saveToPhotoGallery = saveToPhotoGallery;
      TiCameraActivity.whichCamera = CAMERA_REAR; // default.

      // This option is only applicable when running the custom
      // TiCameraActivity, since we can't direct the built-in
      // Activity to open a specific camera.
      Object whichCamera = options.get("whichCamera");
      if (whichCamera != null) {
        TiCameraActivity.whichCamera = TiConvert.toInt(whichCamera);
      }
      TiCameraActivity.autohide = autohide;

      Intent intent = new Intent(activity, TiCameraActivity.class);
      activity.startActivity(intent);
      return;
    }

    Camera camera = null;
    try {
      camera = Camera.open();
      if (camera != null) {
        camera.release();
        camera = null;
      }

    } catch (Throwable t) {
      if (camera != null) {
        camera.release();
      }

      if (errorCallback != null) {
        errorCallback.call(
            getKrollObject(),
            new Object[] {createErrorResponse(NO_CAMERA, "Camera not available.")});
      }

      return;
    }

    TiActivitySupport activitySupport = (TiActivitySupport) activity;
    TiFileHelper tfh = TiFileHelper.getInstance();

    TiIntentWrapper cameraIntent = new TiIntentWrapper(new Intent());
    if (TiCameraActivity.overlayProxy == null) {
      cameraIntent.getIntent().setAction(MediaStore.ACTION_IMAGE_CAPTURE);
      cameraIntent.getIntent().addCategory(Intent.CATEGORY_DEFAULT);
    } else {
      cameraIntent
          .getIntent()
          .setClass(TiApplication.getInstance().getBaseContext(), TiCameraActivity.class);
    }

    cameraIntent.setWindowId(TiIntentWrapper.createActivityName("CAMERA"));
    PackageManager pm = (PackageManager) activity.getPackageManager();
    List<ResolveInfo> activities =
        pm.queryIntentActivities(cameraIntent.getIntent(), PackageManager.MATCH_DEFAULT_ONLY);

    // See if it's the HTC camera app
    boolean isHTCCameraApp = false;

    for (ResolveInfo rs : activities) {
      try {
        if (rs.activityInfo.applicationInfo.sourceDir.contains("HTC")
            || Build.MANUFACTURER.equals("HTC")) {
          isHTCCameraApp = true;
          break;
        }
      } catch (NullPointerException e) {
        // Ignore
      }
    }

    File imageDir = null;
    File imageFile = null;

    try {
      if (saveToPhotoGallery) {
        // HTC camera application will create its own gallery image
        // file.
        if (!isHTCCameraApp) {
          imageFile = createGalleryImageFile();
        }

      } else {
        if (activity.getIntent() != null) {
          String name = TiApplication.getInstance().getAppInfo().getName();
          // For HTC cameras, specifying the directory from
          // getExternalStorageDirectory is /mnt/sdcard and
          // using that path prevents the gallery from recognizing it.
          // To avoid this we use /sdcard instead
          // (this is a legacy path we've been using)
          if (isHTCCameraApp) {
            imageDir = new File(PHOTO_DCIM_CAMERA, name);
          } else {
            File rootsd = Environment.getExternalStorageDirectory();
            imageDir = new File(rootsd.getAbsolutePath() + "/dcim/Camera/", name);
          }
          if (!imageDir.exists()) {
            imageDir.mkdirs();
            if (!imageDir.exists()) {
              Log.w(TAG, "Attempt to create '" + imageDir.getAbsolutePath() + "' failed silently.");
            }
          }

        } else {
          imageDir = tfh.getDataDirectory(false);
        }

        imageFile = tfh.getTempFile(imageDir, ".jpg", true);
      }

    } catch (IOException e) {
      Log.e(TAG, "Unable to create temp file", e);
      if (errorCallback != null) {
        errorCallback.callAsync(
            getKrollObject(), createErrorResponse(UNKNOWN_ERROR, e.getMessage()));
      }

      return;
    }

    // Get the taken date for the last image in EXTERNAL_CONTENT_URI.
    String[] projection = {Images.ImageColumns.DATE_TAKEN};
    String dateTaken = null;
    Cursor c =
        activity
            .getContentResolver()
            .query(
                Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                null,
                null,
                Images.ImageColumns.DATE_TAKEN);
    if (c != null) {
      if (c.moveToLast()) {
        dateTaken = c.getString(0);
      }
      c.close();
      c = null;
    }

    CameraResultHandler resultHandler = new CameraResultHandler();
    resultHandler.imageFile = imageFile;
    resultHandler.saveToPhotoGallery = saveToPhotoGallery;
    resultHandler.successCallback = successCallback;
    resultHandler.cancelCallback = cancelCallback;
    resultHandler.errorCallback = errorCallback;
    resultHandler.activitySupport = activitySupport;
    resultHandler.cameraIntent = cameraIntent.getIntent();
    resultHandler.dateTaken_lastImageInExternalContentURI = dateTaken;

    if (imageFile != null) {
      String imageUrl = "file://" + imageFile.getAbsolutePath();
      cameraIntent.getIntent().putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse(imageUrl));
      resultHandler.imageUrl = imageUrl;
    }

    activity.runOnUiThread(resultHandler);
  }
 public int getRepeatCount() {
   if (proxy.hasProperty(TiC.PROPERTY_REPEAT_COUNT)) {
     return TiConvert.toInt(proxy.getProperty(TiC.PROPERTY_REPEAT_COUNT));
   }
   return INFINITE;
 }
 @Override
 public void propertySet(String key, Object newValue, Object oldValue, boolean changedProperty) {
   AlertDialog dialog = (AlertDialog) dialogWrapper.getDialog();
   if (key.startsWith(TiC.PROPERTY_ACCESSIBILITY_PREFIX)) {
     if (dialog != null) {
       ListView listView = dialog.getListView();
       if (listView != null) {
         if (key.equals(TiC.PROPERTY_ACCESSIBILITY_HIDDEN)) {
           int importance = ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
           if (newValue != null && TiConvert.toBoolean(newValue)) {
             importance = ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO;
           }
           ViewCompat.setImportantForAccessibility(listView, importance);
         } else {
           listView.setContentDescription(composeContentDescription());
         }
       }
     }
     return;
   }
   switch (key) {
     case TiC.PROPERTY_TITLE:
       if (dialog != null) {
         dialog.setTitle(Html.fromHtml((String) newValue));
       } else {
         getBuilder().setTitle(Html.fromHtml(TiConvert.toString(newValue)));
       }
       break;
     case TiC.PROPERTY_MESSAGE:
       if (dialog != null) {
         dialog.setMessage(Html.fromHtml((String) newValue));
       } else {
         getBuilder().setMessage(Html.fromHtml(TiConvert.toString(newValue)));
       }
       break;
     case TiC.PROPERTY_BUTTON_NAMES:
       clearDialog();
       processButtons(TiConvert.toStringArray(newValue));
       break;
     case TiC.PROPERTY_OK:
       clearDialog();
       processButtons(new String[] {TiConvert.toString(newValue)});
       break;
     case TiC.PROPERTY_CUSTOM_VIEW:
       clearDialog();
       processView(newValue);
       break;
     case TiC.PROPERTY_PERSISTENT:
       dialogWrapper.setPersistent(TiConvert.toBoolean(newValue));
       break;
     case TiC.PROPERTY_CANCEL:
       cancelIndex = TiConvert.toInt(newValue, -1);
       break;
     case TiC.PROPERTY_OPTIONS:
       {
         mProcessUpdateFlags |= TIFLAG_NEEDS_OPTIONS;
         break;
       }
     case TiC.PROPERTY_SELECTED_INDEX:
       {
         mProcessUpdateFlags |= TIFLAG_NEEDS_OPTIONS;
         break;
       }
     case TiC.PROPERTY_HIDE_ON_CLICK:
       hideOnClick = TiConvert.toBoolean(newValue);
       if (dialog != null) {
         dialog.setCancelable(hideOnClick);
       }
       break;
     case TiC.PROPERTY_TAP_OUT_DISMISS:
       tapToDismiss = TiConvert.toBoolean(newValue);
       if (dialog != null) {
         dialog.setCanceledOnTouchOutside(tapToDismiss);
       }
       break;
     default:
       super.propertySet(key, newValue, oldValue, changedProperty);
       break;
   }
 }
Example #20
0
  @Kroll.method
  public KrollDict convertPointToView(KrollDict point, TiViewProxy dest) {
    if (point == null) {
      throw new IllegalArgumentException("convertPointToView: point must not be null");
    }

    if (dest == null) {
      throw new IllegalArgumentException("convertPointToView: destinationView must not be null");
    }

    if (!point.containsKey(TiC.PROPERTY_X)) {
      throw new IllegalArgumentException(
          "convertPointToView: required property \"x\" not found in point");
    }

    if (!point.containsKey(TiC.PROPERTY_Y)) {
      throw new IllegalArgumentException(
          "convertPointToView: required property \"y\" not found in point");
    }

    // The spec says to throw an exception if x or y cannot be converted to numbers.
    // TiConvert does that automatically for us.
    int x = TiConvert.toInt(point, TiC.PROPERTY_X);
    int y = TiConvert.toInt(point, TiC.PROPERTY_Y);

    TiUIView view = peekView();
    TiUIView destView = dest.peekView();
    if (view == null) {
      Log.w(LCAT, "convertPointToView: view has not been attached, cannot convert point");
      return null;
    }

    if (destView == null) {
      Log.w(
          LCAT, "convertPointToView: destinationView has not been attached, cannot convert point");
      return null;
    }

    View nativeView = view.getNativeView();
    View destNativeView = destView.getNativeView();
    if (nativeView == null || nativeView.getParent() == null) {
      Log.w(LCAT, "convertPointToView: view has not been attached, cannot convert point");
      return null;
    }

    if (destNativeView == null || destNativeView.getParent() == null) {
      Log.w(
          LCAT, "convertPointToView: destinationView has not been attached, cannot convert point");
      return null;
    }

    int viewLocation[] = new int[2];
    int destLocation[] = new int[2];
    nativeView.getLocationInWindow(viewLocation);
    destNativeView.getLocationInWindow(destLocation);

    if (DBG) {
      Log.d(
          LCAT, "nativeView location in window, x: " + viewLocation[0] + ", y: " + viewLocation[1]);
      Log.d(
          LCAT,
          "destNativeView location in window, x: " + destLocation[0] + ", y: " + destLocation[1]);
    }

    int pointWindowX = viewLocation[0] + x;
    int pointWindowY = viewLocation[1] + y;

    KrollDict destPoint = new KrollDict();
    destPoint.put(TiC.PROPERTY_X, pointWindowX - destLocation[0]);
    destPoint.put(TiC.PROPERTY_Y, pointWindowY - destLocation[1]);
    return destPoint;
  }
Example #21
0
 private int getRepeatCount() {
   if (proxy.hasDynamicValue("repeatCount")) {
     return TiConvert.toInt(proxy.getDynamicValue("repeatCount"));
   }
   return INFINITE;
 }
  @Override
  public boolean handleMessage(Message msg) {
    switch (msg.what) {
      case MSG_SET_ITEMS:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          handleSetItems(result.getArg());
          result.setResult(null);
          return true;
        }

      case MSG_GET_ITEMS:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          result.setResult(itemProperties.toArray());
          return true;
        }

      case MSG_APPEND_ITEMS:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          handleAppendItems(result.getArg());
          result.setResult(null);
          return true;
        }

      case MSG_INSERT_ITEMS_AT:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          KrollDict data = (KrollDict) result.getArg();
          int index = data.getInt(TiC.EVENT_PROPERTY_INDEX);
          handleInsertItemsAt(index, data.get(TiC.PROPERTY_DATA));
          result.setResult(null);
          return true;
        }

      case MSG_DELETE_ITEMS_AT:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          KrollDict data = (KrollDict) result.getArg();
          int index = data.getInt(TiC.EVENT_PROPERTY_INDEX);
          int count = data.getInt(TiC.PROPERTY_COUNT);
          handleDeleteItemsAt(index, count);
          result.setResult(null);
          return true;
        }

      case MSG_REPLACE_ITEMS_AT:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          KrollDict data = (KrollDict) result.getArg();
          int index = data.getInt(TiC.EVENT_PROPERTY_INDEX);
          int count = data.getInt(TiC.PROPERTY_COUNT);
          handleReplaceItemsAt(index, count, data.get(TiC.PROPERTY_DATA));
          result.setResult(null);
          return true;
        }

      case MSG_GET_ITEM_AT:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          KrollDict item = handleGetItemAt(TiConvert.toInt(result.getArg()));
          result.setResult(item);
          return true;
        }

      case MSG_UPDATE_ITEM_AT:
        {
          AsyncResult result = (AsyncResult) msg.obj;
          KrollDict data = (KrollDict) result.getArg();
          int index = data.getInt(TiC.EVENT_PROPERTY_INDEX);
          handleUpdateItemAt(index, data.get(TiC.PROPERTY_DATA));
          result.setResult(null);
          return true;
        }

      default:
        {
          return super.handleMessage(msg);
        }
    }
  }
Example #23
0
  public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) {
    if (key.equals(TiC.PROPERTY_LEFT)) {
      if (newValue != null) {
        layoutParams.optionLeft =
            TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_LEFT);
      } else {
        layoutParams.optionLeft = null;
      }
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_TOP)) {
      if (newValue != null) {
        layoutParams.optionTop =
            TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_TOP);
      } else {
        layoutParams.optionTop = null;
      }
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_CENTER)) {
      TiConvert.updateLayoutCenter(newValue, layoutParams);
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_RIGHT)) {
      if (newValue != null) {
        layoutParams.optionRight =
            TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_RIGHT);
      } else {
        layoutParams.optionRight = null;
      }
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_BOTTOM)) {
      if (newValue != null) {
        layoutParams.optionBottom =
            TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_BOTTOM);
      } else {
        layoutParams.optionBottom = null;
      }
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_SIZE)) {
      if (newValue instanceof HashMap) {
        HashMap<String, Object> d = (HashMap) newValue;
        propertyChanged(TiC.PROPERTY_WIDTH, oldValue, d.get(TiC.PROPERTY_WIDTH), proxy);
        propertyChanged(TiC.PROPERTY_HEIGHT, oldValue, d.get(TiC.PROPERTY_HEIGHT), proxy);
      } else if (newValue != null) {
        Log.w(
            LCAT,
            "Unsupported property type ("
                + (newValue.getClass().getSimpleName())
                + ") for key: "
                + key
                + ". Must be an object/dictionary");
      }
    } else if (key.equals(TiC.PROPERTY_HEIGHT)) {
      if (newValue != null) {
        if (!newValue.equals(TiC.SIZE_AUTO)) {
          layoutParams.optionHeight =
              TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_HEIGHT);
          layoutParams.autoHeight = false;
        } else {
          layoutParams.optionHeight = null;
          layoutParams.autoHeight = true;
        }
      } else {
        layoutParams.optionHeight = null;
      }
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_WIDTH)) {
      if (newValue != null) {
        if (!newValue.equals(TiC.SIZE_AUTO)) {
          layoutParams.optionWidth =
              TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_WIDTH);
          layoutParams.autoWidth = false;
        } else {
          layoutParams.optionWidth = null;
          layoutParams.autoWidth = true;
        }
      } else {
        layoutParams.optionWidth = null;
      }
      layoutNativeView();
    } else if (key.equals(TiC.PROPERTY_ZINDEX)) {
      if (newValue != null) {
        layoutParams.optionZIndex = TiConvert.toInt(newValue);
      } else {
        layoutParams.optionZIndex = 0;
      }
      layoutNativeView(true);
    } else if (key.equals(TiC.PROPERTY_FOCUSABLE)) {
      boolean focusable = TiConvert.toBoolean(proxy.getProperty(TiC.PROPERTY_FOCUSABLE));
      nativeView.setFocusable(focusable);
      if (focusable) {
        registerForKeyClick(nativeView);
      } else {
        // nativeView.setOnClickListener(null); // ? mistake? I assume OnKeyListener was meant
        nativeView.setOnKeyListener(null);
      }
    } else if (key.equals(TiC.PROPERTY_TOUCH_ENABLED)) {
      doSetClickable(TiConvert.toBoolean(newValue));
    } else if (key.equals(TiC.PROPERTY_VISIBLE)) {
      nativeView.setVisibility(TiConvert.toBoolean(newValue) ? View.VISIBLE : View.INVISIBLE);
    } else if (key.equals(TiC.PROPERTY_ENABLED)) {
      nativeView.setEnabled(TiConvert.toBoolean(newValue));
    } else if (key.startsWith(TiC.PROPERTY_BACKGROUND_PADDING)) {
      Log.i(LCAT, key + " not yet implemented.");
    } else if (key.equals(TiC.PROPERTY_OPACITY)
        || key.startsWith(TiC.PROPERTY_BACKGROUND_PREFIX)
        || key.startsWith(TiC.PROPERTY_BORDER_PREFIX)) {
      // Update first before querying.
      proxy.setProperty(key, newValue);

      KrollDict d = proxy.getProperties();

      boolean hasImage = hasImage(d);
      boolean hasColorState = hasColorState(d);
      boolean hasBorder = hasBorder(d);

      boolean requiresCustomBackground = hasImage || hasColorState || hasBorder;

      if (!requiresCustomBackground) {
        if (background != null) {
          background.releaseDelegate();
          background.setCallback(null);
          background = null;
        }

        if (d.containsKeyAndNotNull(TiC.PROPERTY_BACKGROUND_COLOR)) {
          Integer bgColor = TiConvert.toColor(d, TiC.PROPERTY_BACKGROUND_COLOR);
          if (nativeView != null) {
            nativeView.setBackgroundColor(bgColor);
            nativeView.postInvalidate();
          }
        } else {
          if (key.equals(TiC.PROPERTY_OPACITY)) {
            setOpacity(TiConvert.toFloat(newValue));
          }
          if (nativeView != null) {
            nativeView.setBackgroundDrawable(null);
            nativeView.postInvalidate();
          }
        }
      } else {
        boolean newBackground = background == null;
        if (newBackground) {
          background = new TiBackgroundDrawable();
        }

        Integer bgColor = null;

        if (!hasColorState) {
          if (d.get(TiC.PROPERTY_BACKGROUND_COLOR) != null) {
            bgColor = TiConvert.toColor(d, TiC.PROPERTY_BACKGROUND_COLOR);
            if (newBackground
                || (key.equals(TiC.PROPERTY_OPACITY)
                    || key.equals(TiC.PROPERTY_BACKGROUND_COLOR))) {
              background.setBackgroundColor(bgColor);
            }
          }
        }

        if (hasImage || hasColorState) {
          if (newBackground || key.startsWith(TiC.PROPERTY_BACKGROUND_PREFIX)) {
            handleBackgroundImage(d);
          }
        }

        if (hasBorder) {
          if (newBackground) {
            initializeBorder(d, bgColor);
          } else if (key.startsWith(TiC.PROPERTY_BORDER_PREFIX)) {
            handleBorderProperty(key, newValue);
          }
        }
        applyCustomBackground();
      }
      if (nativeView != null) {
        nativeView.postInvalidate();
      }
    } else if (key.equals(TiC.PROPERTY_SOFT_KEYBOARD_ON_FOCUS)) {
      Log.w(
          LCAT,
          "Focus state changed to "
              + TiConvert.toString(newValue)
              + " not honored until next focus event.");
    } else if (key.equals(TiC.PROPERTY_TRANSFORM)) {
      if (nativeView != null) {
        applyTransform((Ti2DMatrix) newValue);
      }
    } else if (key.equals(TiC.PROPERTY_KEEP_SCREEN_ON)) {
      if (nativeView != null) {
        nativeView.setKeepScreenOn(TiConvert.toBoolean(newValue));
      }
    } else {
      TiViewProxy viewProxy = getProxy();
      if (viewProxy != null && viewProxy.isLocalizedTextId(key)) {
        viewProxy.setLocalizedText(key, TiConvert.toString(newValue));
      } else {
        if (DBG) {
          Log.d(LCAT, "Unhandled property key: " + key);
        }
      }
    }
  }
 @Override
 public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) {
   if (Log.isDebugModeEnabled()) {
     Log.d(TAG, "Property: " + key + " old: " + oldValue + " new: " + newValue, Log.DEBUG_MODE);
   }
   if (key.equals(TiC.PROPERTY_ENABLED)) {
     tv.setEnabled(TiConvert.toBoolean(newValue));
   } else if (key.equals(TiC.PROPERTY_VALUE)) {
     tv.setText(TiConvert.toString(newValue));
   } else if (key.equals(TiC.PROPERTY_MAX_LENGTH)) {
     maxLength = TiConvert.toInt(newValue);
     // truncate if current text exceeds max length
     Editable currentText = tv.getText();
     if (maxLength >= 0 && currentText.length() > maxLength) {
       CharSequence truncateText = currentText.subSequence(0, maxLength);
       int cursor = tv.getSelectionStart() - 1;
       if (cursor > maxLength) {
         cursor = maxLength;
       }
       tv.setText(truncateText);
       tv.setSelection(cursor);
     }
   } else if (key.equals(TiC.PROPERTY_COLOR)) {
     tv.setTextColor(TiConvert.toColor((String) newValue));
   } else if (key.equals(TiC.PROPERTY_HINT_TEXT)) {
     tv.setHint((String) newValue);
   } else if (key.equals(TiC.PROPERTY_ELLIPSIZE)) {
     if (TiConvert.toBoolean(newValue)) {
       tv.setEllipsize(TruncateAt.END);
     } else {
       tv.setEllipsize(null);
     }
   } else if (key.equals(TiC.PROPERTY_TEXT_ALIGN) || key.equals(TiC.PROPERTY_VERTICAL_ALIGN)) {
     String textAlign = null;
     String verticalAlign = null;
     if (key.equals(TiC.PROPERTY_TEXT_ALIGN)) {
       textAlign = TiConvert.toString(newValue);
     } else if (proxy.hasProperty(TiC.PROPERTY_TEXT_ALIGN)) {
       textAlign = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_TEXT_ALIGN));
     }
     if (key.equals(TiC.PROPERTY_VERTICAL_ALIGN)) {
       verticalAlign = TiConvert.toString(newValue);
     } else if (proxy.hasProperty(TiC.PROPERTY_VERTICAL_ALIGN)) {
       verticalAlign = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_VERTICAL_ALIGN));
     }
     handleTextAlign(textAlign, verticalAlign);
   } else if (key.equals(TiC.PROPERTY_KEYBOARD_TYPE)
       || (key.equals(TiC.PROPERTY_AUTOCORRECT)
           || key.equals(TiC.PROPERTY_AUTOCAPITALIZATION)
           || key.equals(TiC.PROPERTY_PASSWORD_MASK)
           || key.equals(TiC.PROPERTY_EDITABLE))) {
     KrollDict d = proxy.getProperties();
     handleKeyboard(d);
   } else if (key.equals(TiC.PROPERTY_RETURN_KEY_TYPE)) {
     handleReturnKeyType(TiConvert.toInt(newValue));
   } else if (key.equals(TiC.PROPERTY_FONT)) {
     TiUIHelper.styleText(tv, (HashMap) newValue);
   } else if (key.equals(TiC.PROPERTY_AUTO_LINK)) {
     TiUIHelper.linkifyIfEnabled(tv, newValue);
   } else {
     super.propertyChanged(key, oldValue, newValue, proxy);
   }
 }
  @Override
  public void processProperties(KrollDict d) {
    super.processProperties(d);

    if (d.containsKey(TiC.PROPERTY_ENABLED)) {
      tv.setEnabled(TiConvert.toBoolean(d, TiC.PROPERTY_ENABLED, true));
    }

    if (d.containsKey(TiC.PROPERTY_MAX_LENGTH) && field) {
      maxLength = TiConvert.toInt(d.get(TiC.PROPERTY_MAX_LENGTH), -1);
    }

    // Disable change event temporarily as we are setting the default value
    disableChangeEvent = true;
    if (d.containsKey(TiC.PROPERTY_VALUE)) {
      tv.setText(d.getString(TiC.PROPERTY_VALUE));
    } else {
      tv.setText("");
    }
    disableChangeEvent = false;

    if (d.containsKey(TiC.PROPERTY_COLOR)) {
      tv.setTextColor(TiConvert.toColor(d, TiC.PROPERTY_COLOR));
    }

    if (d.containsKey(TiC.PROPERTY_HINT_TEXT)) {
      tv.setHint(d.getString(TiC.PROPERTY_HINT_TEXT));
    }

    if (d.containsKey(TiC.PROPERTY_ELLIPSIZE)) {
      if (TiConvert.toBoolean(d, TiC.PROPERTY_ELLIPSIZE)) {
        tv.setEllipsize(TruncateAt.END);
      } else {
        tv.setEllipsize(null);
      }
    }

    if (d.containsKey(TiC.PROPERTY_FONT)) {
      TiUIHelper.styleText(tv, d.getKrollDict(TiC.PROPERTY_FONT));
    }

    if (d.containsKey(TiC.PROPERTY_TEXT_ALIGN) || d.containsKey(TiC.PROPERTY_VERTICAL_ALIGN)) {
      String textAlign = null;
      String verticalAlign = null;
      if (d.containsKey(TiC.PROPERTY_TEXT_ALIGN)) {
        textAlign = d.getString(TiC.PROPERTY_TEXT_ALIGN);
      }
      if (d.containsKey(TiC.PROPERTY_VERTICAL_ALIGN)) {
        verticalAlign = d.getString(TiC.PROPERTY_VERTICAL_ALIGN);
      }
      handleTextAlign(textAlign, verticalAlign);
    }

    if (d.containsKey(TiC.PROPERTY_RETURN_KEY_TYPE)) {
      handleReturnKeyType(TiConvert.toInt(d.get(TiC.PROPERTY_RETURN_KEY_TYPE), RETURNKEY_DEFAULT));
    }

    if (d.containsKey(TiC.PROPERTY_KEYBOARD_TYPE)
        || d.containsKey(TiC.PROPERTY_AUTOCORRECT)
        || d.containsKey(TiC.PROPERTY_PASSWORD_MASK)
        || d.containsKey(TiC.PROPERTY_AUTOCAPITALIZATION)
        || d.containsKey(TiC.PROPERTY_EDITABLE)) {
      handleKeyboard(d);
    }

    if (d.containsKey(TiC.PROPERTY_AUTO_LINK)) {
      TiUIHelper.linkifyIfEnabled(tv, d.get(TiC.PROPERTY_AUTO_LINK));
    }
  }
Example #26
0
  @Override
  public void propertyChanged(String key, Object oldValue, Object newValue, TiProxy proxy) {
    if (DBG) {
      Log.d(LCAT, "Property: " + key + " old: " + oldValue + " new: " + newValue);
    }
    if (key.equals("enabled")) {
      tv.setEnabled(TiConvert.toBoolean(newValue));
    } else if (key.equals("value")) {
      tv.setText((String) newValue);
    } else if (key.equals("color")) {
      tv.setTextColor(TiConvert.toColor((String) newValue));
    } else if (key.equals("passwordMask")) {
      if (TiConvert.toBoolean(newValue) == true) {
        // This shouldn't be needed but it's belts & braces
        tv.setKeyListener(TextKeyListener.getInstance(false, Capitalize.NONE));
        // Both setTransform & keyboard type are required
        tv.setTransformationMethod(PasswordTransformationMethod.getInstance());
        // We also need to set the keyboard type - otherwise the password mask won't be applied
        handleKeyboardType(KEYBOARD_PASSWORD, false);
      } else {
        handleKeyboardType(KEYBOARD_DEFAULT, false);
      }
    } else if (key.equals("hintText")) {
      tv.setHint((String) newValue);
    } else if (key.equals("textAlign") || key.equals("verticalAlign")) {
      String textAlign = null;
      String verticalAlign = null;
      if (key.equals("textAlign")) {
        textAlign = TiConvert.toString(newValue);
      }
      if (key.equals("verticalAlign")) {
        verticalAlign = TiConvert.toString(newValue);
      }
      handleTextAlign(textAlign, verticalAlign);
    } else if (key.equals("autocapitalization")) {

      // TODO Missing
      Capitalize autoCapValue = null;

      switch (TiConvert.toInt(newValue)) {
        case TEXT_AUTOCAPITALIZATION_NONE:
          autoCapValue = Capitalize.NONE;
          break;

        case TEXT_AUTOCAPITALIZATION_ALL:
          autoCapValue = Capitalize.CHARACTERS;
          break;

        case TEXT_AUTOCAPITALIZATION_SENTENCES:
          autoCapValue = Capitalize.SENTENCES;
          break;

        case TEXT_AUTOCAPITALIZATION_WORDS:
          autoCapValue = Capitalize.WORDS;
          break;

        default:
          Log.w(LCAT, "Unknown AutoCapitalization Value [" + TiConvert.toString(newValue) + "]");
          break;
      }

      if (null != autoCapValue) {
        tv.setKeyListener(TextKeyListener.getInstance(false, autoCapValue));
      }

    } else if (key.equals("keyboardType") || (key.equals("autocorrect"))) {
      TiDict d = proxy.getDynamicProperties();
      boolean autocorrect = false;
      if (d.containsKey("autocorrect")) {
        autocorrect = d.getBoolean("autocorrect");
      }

      handleKeyboardType(TiConvert.toInt(d, "keyboardType"), autocorrect);
    } else if (key.equals("returnKeyType")) {
      handleReturnKeyType(TiConvert.toInt(newValue));
    } else if (key.equals("font")) {
      TiUIHelper.styleText(tv, (TiDict) newValue);
    } else {
      super.propertyChanged(key, oldValue, newValue, proxy);
    }
  }
  public TiBubbleAndroidView(TiViewProxy proxy) {
    super(proxy);

    prop = proxy.getProperties();

    LayoutArrangement arrangement = LayoutArrangement.DEFAULT;

    if (proxy.hasProperty(TiC.PROPERTY_LAYOUT)) {
      String layoutProperty = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_LAYOUT));
      if (layoutProperty.equals(TiC.LAYOUT_HORIZONTAL)) {
        arrangement = LayoutArrangement.HORIZONTAL;
      } else if (layoutProperty.equals(TiC.LAYOUT_VERTICAL)) {
        arrangement = LayoutArrangement.VERTICAL;
      }
    }

    TiCompositeLayout nativeView = new TiCompositeLayout(proxy.getActivity(), arrangement);
    setNativeView(nativeView);

    if (nativeBubbleView == null) {
      Activity currentActivity = proxy.getActivity();
      if (currentActivity == null) {
        currentActivity = TiApplication.getAppCurrentActivity();
      }
      nativeBubbleView = new NativeBubbleView(currentActivity);

      LayoutParams params = new LayoutParams();
      params.height = android.widget.FrameLayout.LayoutParams.MATCH_PARENT;
      params.width = android.widget.FrameLayout.LayoutParams.MATCH_PARENT;

      ViewGroup savedParent = null;
      int childIndex = -1;

      TiUIView parentView = proxy.getParent().getOrCreateView();
      View parentNativeView = (View) parentView.getNativeView();

      if (parentNativeView != null) {
        ViewParent nativeParent = (ViewParent) parentNativeView;

        if (nativeParent instanceof ViewGroup) {
          savedParent = (ViewGroup) nativeParent;
          childIndex = savedParent.indexOfChild(nativeView);
          savedParent.removeView(nativeView);
        }
      }

      nativeBubbleView.addView(nativeView, params);

      if (savedParent != null) {
        savedParent.addView(nativeBubbleView, childIndex, getLayoutParams());
      }

      if (prop.containsKey("bubbleRadius")) {
        float radius = 0;
        TiDimension radiusDim =
            TiConvert.toTiDimension(prop.get("bubbleRadius"), TiDimension.TYPE_WIDTH);
        if (radiusDim != null) {
          radius = (float) radiusDim.getPixels(getNativeView());
        }
        nativeBubbleView.setBubbleRadius(radius);
      }

      if (prop.containsKey("bubbleColor")) {
        nativeBubbleView.setBubbleColor(TiConvert.toColor(prop, "bubbleColor"));
      } else {
        Integer bgColor = TiConvert.toColor(prop, TiC.PROPERTY_BACKGROUND_COLOR);
        if (bgColor != null) {
          nativeBubbleView.setBubbleColor(bgColor);
        }
      }

      if (prop.containsKey("bubbleBeak")) {
        nativeBubbleView.setBubbleBeak(TiConvert.toInt(prop, "bubbleBeak"));
      }

      if (prop.containsKey("bubbleBeakVertical")) {
        nativeBubbleView.setBubbleBeakVertical(TiConvert.toInt(prop, "bubbleBeakVertical"));
      }

      parentView.remove(this);
      parentView.add(this);
    }
  }
 public Integer getInt(String key) {
   return TiConvert.toInt(get(key));
 }
  public void handleKeyboard(KrollDict d) {
    int type = KEYBOARD_ASCII;
    boolean passwordMask = false;
    boolean editable = true;
    int autocorrect = InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
    int autoCapValue = 0;

    if (d.containsKey(TiC.PROPERTY_AUTOCORRECT)
        && !TiConvert.toBoolean(d, TiC.PROPERTY_AUTOCORRECT, true)) {
      autocorrect = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
    }

    if (d.containsKey(TiC.PROPERTY_EDITABLE)) {
      editable = TiConvert.toBoolean(d, TiC.PROPERTY_EDITABLE, true);
    }

    if (d.containsKey(TiC.PROPERTY_AUTOCAPITALIZATION)) {

      switch (TiConvert.toInt(
          d.get(TiC.PROPERTY_AUTOCAPITALIZATION), TEXT_AUTOCAPITALIZATION_NONE)) {
        case TEXT_AUTOCAPITALIZATION_NONE:
          autoCapValue = 0;
          break;
        case TEXT_AUTOCAPITALIZATION_ALL:
          autoCapValue =
              InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
                  | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
                  | InputType.TYPE_TEXT_FLAG_CAP_WORDS;
          break;
        case TEXT_AUTOCAPITALIZATION_SENTENCES:
          autoCapValue = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
          break;

        case TEXT_AUTOCAPITALIZATION_WORDS:
          autoCapValue = InputType.TYPE_TEXT_FLAG_CAP_WORDS;
          break;
        default:
          Log.w(
              TAG,
              "Unknown AutoCapitalization Value ["
                  + d.getString(TiC.PROPERTY_AUTOCAPITALIZATION)
                  + "]");
          break;
      }
    }

    if (d.containsKey(TiC.PROPERTY_PASSWORD_MASK)) {
      passwordMask = TiConvert.toBoolean(d, TiC.PROPERTY_PASSWORD_MASK, false);
    }

    if (d.containsKey(TiC.PROPERTY_KEYBOARD_TYPE)) {
      type = TiConvert.toInt(d.get(TiC.PROPERTY_KEYBOARD_TYPE), KEYBOARD_DEFAULT);
    }

    int typeModifiers = autocorrect | autoCapValue;
    int textTypeAndClass = typeModifiers;
    // For some reason you can't set both TYPE_CLASS_TEXT and TYPE_TEXT_FLAG_NO_SUGGESTIONS
    // together.
    // Also, we need TYPE_CLASS_TEXT for passwords.
    if ((autocorrect != InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS || passwordMask)
        && type != KEYBOARD_DECIMAL_PAD) {
      textTypeAndClass = textTypeAndClass | InputType.TYPE_CLASS_TEXT;
    }

    tv.setCursorVisible(true);
    switch (type) {
      case KEYBOARD_DEFAULT:
      case KEYBOARD_ASCII:
        // Don't need a key listener, inputType handles that.
        break;
      case KEYBOARD_NUMBERS_PUNCTUATION:
        textTypeAndClass |= (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_TEXT);
        tv.setKeyListener(
            new NumberKeyListener() {
              @Override
              public int getInputType() {
                return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_TEXT;
              }

              @Override
              protected char[] getAcceptedChars() {
                return new char[] {
                  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-', '+', '_', '*', '-',
                  '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '=', '{', '}', '[', ']', '|',
                  '\\', '<', '>', ',', '?', '/', ':', ';', '\'', '"', '~'
                };
              }
            });
        break;
      case KEYBOARD_URL:
        Log.d(TAG, "Setting keyboard type URL-3", Log.DEBUG_MODE);
        tv.setImeOptions(EditorInfo.IME_ACTION_GO);
        textTypeAndClass |= InputType.TYPE_TEXT_VARIATION_URI;
        break;
      case KEYBOARD_DECIMAL_PAD:
        textTypeAndClass |=
            (InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
      case KEYBOARD_NUMBER_PAD:
        tv.setKeyListener(DigitsKeyListener.getInstance(true, true));
        textTypeAndClass |= InputType.TYPE_CLASS_NUMBER;
        break;
      case KEYBOARD_PHONE_PAD:
        tv.setKeyListener(DialerKeyListener.getInstance());
        textTypeAndClass |= InputType.TYPE_CLASS_PHONE;
        break;
      case KEYBOARD_EMAIL_ADDRESS:
        textTypeAndClass |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
        break;
    }

    if (passwordMask) {
      textTypeAndClass |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
      // Sometimes password transformation does not work properly when the input type is set after
      // the transformation method.
      // This issue has been filed at http://code.google.com/p/android/issues/detail?id=7092
      tv.setInputType(textTypeAndClass);
      tv.setTransformationMethod(PasswordTransformationMethod.getInstance());

      // turn off text UI in landscape mode b/c Android numeric passwords are not masked correctly
      // in landscape mode.
      if (type == KEYBOARD_NUMBERS_PUNCTUATION
          || type == KEYBOARD_DECIMAL_PAD
          || type == KEYBOARD_NUMBER_PAD) {
        tv.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
      }

    } else {
      tv.setInputType(textTypeAndClass);
      if (tv.getTransformationMethod() instanceof PasswordTransformationMethod) {
        tv.setTransformationMethod(null);
      }
    }
    if (!editable) {
      tv.setKeyListener(null);
      tv.setCursorVisible(false);
    }

    // setSingleLine() append the flag TYPE_TEXT_FLAG_MULTI_LINE to the current inputType, so we
    // want to call this
    // after we set inputType.
    if (!field) {
      tv.setSingleLine(false);
    }
  }
  @Override
  public void propertySet(String key, Object newValue, Object oldValue, boolean changedProperty) {
    switch (key) {
      case TiC.PROPERTY_SCALES_PAGE_TO_FIT:
        getWebView().getSettings().setLoadWithOverviewMode(TiConvert.toBoolean(newValue));
        break;
      case TiC.PROPERTY_CACHE_MODE:
        getWebView()
            .getSettings()
            .setCacheMode(TiConvert.toInt(newValue, AndroidModule.WEBVIEW_LOAD_DEFAULT));
        break;
      case TiC.PROPERTY_URL:
        if (!TiC.URL_ANDROID_ASSET_RESOURCES.equals(TiConvert.toString(newValue))) {
          setUrl(TiConvert.toString(newValue));
        } else {
          setUrl(null);
        }
        break;
      case TiC.PROPERTY_HTML:
        setHtml(
            TiConvert.toString(newValue),
            (HashMap<String, Object>) (proxy.getProperty(WebViewProxy.OPTIONS_IN_SETHTML)));
        break;
      case TiC.PROPERTY_DATA:
        if (newValue instanceof TiBlob) {
          setData((TiBlob) newValue);
        } else {
          setData(null);
        }
        break;
      case TiC.PROPERTY_LIGHT_TOUCH_ENABLED:
        getWebView().getSettings().setLightTouchEnabled(TiConvert.toBoolean(newValue));
        break;
      case TiC.PROPERTY_PLUGIN_STATE:
        setPluginState(TiConvert.toInt(newValue));
        break;
      case TiC.PROPERTY_SHOW_SCROLLBARS:
        boolean value = TiConvert.toBoolean(newValue);
        getWebView().setVerticalScrollBarEnabled(value);
        getWebView().setHorizontalScrollBarEnabled(value);
        break;
      case TiC.PROPERTY_OVER_SCROLL_MODE:
        nativeView.setOverScrollMode(TiConvert.toInt(newValue, View.OVER_SCROLL_ALWAYS));
        break;
      case TiC.PROPERTY_SCROLLING_ENABLED:
        setScrollingEnabled(newValue);
        break;
      case TiC.PROPERTY_SHOW_HORIZONTAL_SCROLL_INDICATOR:
        nativeView.setHorizontalScrollBarEnabled(TiConvert.toBoolean(newValue));
        break;
      case TiC.PROPERTY_SHOW_VERTICAL_SCROLL_INDICATOR:
        nativeView.setVerticalScrollBarEnabled(TiConvert.toBoolean(newValue));
        break;
      case TiC.PROPERTY_ENABLE_JAVASCRIPT_INTERFACE:
        boolean enableJavascriptInterface = TiConvert.toBoolean(newValue, true);
        if (Build.VERSION.SDK_INT > 16 || enableJavascriptInterface) {
          client.getBinding().addJavascriptInterfaces();
        } else {
          client.getBinding().removeJavascriptInterfaces();
        }
        break;
      default:
        super.propertySet(key, newValue, oldValue, changedProperty);
        break;
    }

    if (changedProperty) {
      // If TiUIView's propertyChanged ended up making a TiBackgroundDrawable
      // for the background, we must set the WebView background color to transparent
      // in order to see any of it.
      boolean isBgRelated =
          (key.startsWith(TiC.PROPERTY_BACKGROUND_PREFIX)
              || key.startsWith(TiC.PROPERTY_BORDER_PREFIX));
      if (isBgRelated
          && nativeView != null
          && nativeView.getBackground() instanceof TiBackgroundDrawable) {
        nativeView.setBackgroundColor(Color.TRANSPARENT);
      }
    }
  }