/* * For some reason, it's very difficult to create a layout that covers exactly the entire screen * and doesn't move when an unhandled key is pressed. The configuration we're using seems to * result in a layout that starts above the screen. So we split initialization into two * pieces, and here we find out where the overlay ended up and move it to be at the top * of the screen. * TODO(pweaver) Separating the menu and highlighting should be a cleaner way to solve this * issue */ private void configureOverlayAfterShow() { int[] location = new int[2]; mRelativeLayout.getLocationOnScreen(location); WindowManager.LayoutParams layoutParams = mOverlay.getParams(); layoutParams.y -= location[1]; mOverlay.setParams(layoutParams); }
/** @param overlay The overlay on which to draw focus indications */ public OverlayController(SimpleOverlay overlay) { mOverlay = overlay; mOverlay.setContentView(com.mpfa.empf.R.layout.switch_access_overlay_layout); mRelativeLayout = (RelativeLayout) mOverlay.findViewById(com.mpfa.empf.R.id.overlayRelativeLayout); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); mOverlay.getContext().registerReceiver(mBroadcastReceiver, filter); }
/** * @return If option scanning is enabled, gets the location of the menu at the top of the screen. * Otherwise null is returned. */ public Rect getMenuButtonLocation() { Button menuButton = (Button) mOverlay.findViewById(com.mpfa.empf.R.id.top_screen_menu_button); if (menuButton != null) { Rect locationOnScreen = new Rect(); menuButton.getGlobalVisibleRect(locationOnScreen); return locationOnScreen; } return null; }
/** * When option scanning is enabled, a menu button is drawn at the top of the screen. This button * offers the user the possibility of clearing the focus or choosing global actions (i.e Home, * Back, Notifications, etc). */ public void drawMenuButton() { Context context = mOverlay.getContext(); LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout menuButtonLayout = (LinearLayout) layoutInflater.inflate( com.mpfa.empf.R.layout.switch_access_global_menu_button, mRelativeLayout, false); addViewAndShow(menuButtonLayout); }
private void configureOverlayBeforeShow() { // The overlay shouldn't capture touch events final WindowManager.LayoutParams params = mOverlay.getParams(); params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; /* The overlay covers the entire screen. However, there is a left, top, right, and * bottom margin. */ final WindowManager wm = (WindowManager) mOverlay.getContext().getSystemService(Context.WINDOW_SERVICE); final Point size = new Point(); wm.getDefaultDisplay().getRealSize(size); params.height = size.y; params.width = size.x; params.x = 0; params.y = 0; mOverlay.setParams(params); }
/** * Get the overlay ready to show. This method displays an empty overlay and tweaks it to make sure * it's in the right location. */ public void configureOverlay() { configureOverlayBeforeShow(); mOverlay.show(); new Handler() .post( new Runnable() { @Override public void run() { configureOverlayAfterShow(); } }); }
public void highlightPerimeterOfRects(Iterable<Rect> rects, Paint highlightPaint) { final Set<Rect> rectsToHighlight = new HashSet<>(); final Paint finalHighlightPaint = new Paint(highlightPaint); for (Rect rect : rects) { rectsToHighlight.add(rect); } mOverlay.show(); /* * Run the rest of the function in a handler to give the thread a chance to draw the * overlay. */ new Handler() .post( new Runnable() { @Override public void run() { int[] layoutCoordinates = new int[2]; mRelativeLayout.getLocationOnScreen(layoutCoordinates); for (Rect rect : rectsToHighlight) { ShapeDrawable mainHighlightDrawable = new ShapeDrawable(new RectShape()); mainHighlightDrawable.setIntrinsicWidth(rect.width()); mainHighlightDrawable.setIntrinsicHeight(rect.height()); mainHighlightDrawable.getPaint().set(finalHighlightPaint); Drawable highlightDrawable = mainHighlightDrawable; if (MAIN_TO_OUTER_HIGHLIGHT_COLOR_MAP.containsKey( finalHighlightPaint.getColor())) { ShapeDrawable outerHighlightDrawable = new ShapeDrawable(new RectShape()); outerHighlightDrawable.setIntrinsicWidth(rect.width()); outerHighlightDrawable.setIntrinsicHeight(rect.height()); Paint outerHighlightPaint = new Paint(finalHighlightPaint); outerHighlightPaint.setColor( MAIN_TO_OUTER_HIGHLIGHT_COLOR_MAP.get(finalHighlightPaint.getColor())); outerHighlightPaint.setStrokeWidth(finalHighlightPaint.getStrokeWidth() / 2); outerHighlightDrawable.getPaint().set(outerHighlightPaint); Drawable[] layers = {mainHighlightDrawable, outerHighlightDrawable}; highlightDrawable = new LayerDrawable(layers); } ImageView imageView = new ImageView(mOverlay.getContext()); imageView.setBackground(highlightDrawable); // Align image with node we're highlighting final RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(rect.width(), rect.height()); layoutParams.leftMargin = rect.left - layoutCoordinates[0]; layoutParams.topMargin = rect.top - layoutCoordinates[1]; imageView.setLayoutParams(layoutParams); mRelativeLayout.addView(imageView); } } }); }
/** Obtain the context for drawing */ public Context getContext() { return mOverlay.getContext(); }
/** Shut down nicely */ public void shutdown() { mOverlay.getContext().unregisterReceiver(mBroadcastReceiver); mOverlay.hide(); }
/** Clear focus highlighting */ public void clearOverlay() { mRelativeLayout.removeAllViews(); mOverlay.hide(); }
/** Override focus highlighting with a custom overlay */ public void addViewAndShow(View view) { mRelativeLayout.addView(view); mOverlay.show(); }