1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.widget; 18 19 import android.content.Context; 20 import android.graphics.Canvas; 21 import android.graphics.Paint; 22 import android.graphics.Path; 23 import android.util.AttributeSet; 24 import android.view.View; 25 import android.widget.FrameLayout; 26 27 import com.android.camera2.R; 28 29 /** 30 * This is a cling widget for settings button. In addition to drawing a cling button 31 * background and overlaying text, it draws a small triangle that points at the 32 * settings button that this cling is for. 33 */ 34 public class SettingsCling extends FrameLayout { 35 private final int mClingTriangleHeight; 36 private final int mClingTriangleWidth; 37 private final Path mTrianglePath = new Path(); 38 private final Paint mClingPaint = new Paint(); 39 40 public SettingsCling(Context context, AttributeSet attrs) { 41 super(context, attrs); 42 setWillNotDraw(false); 43 mClingTriangleHeight = getResources().getDimensionPixelSize( 44 R.dimen.settings_cling_triangle_height); 45 mClingTriangleWidth = getResources().getDimensionPixelSize( 46 R.dimen.settings_cling_triangle_width); 47 mClingPaint.setColor(getResources().getColor(R.color.settings_cling_color)); 48 mClingPaint.setStyle(Paint.Style.FILL); 49 } 50 51 /** 52 * Updates the current position of the cling based on a reference view. If there 53 * is enough space to lay out the cling on top of the reference view, then have 54 * the cling on top. Otherwise, position the cling underneath the reference view. 55 * 56 * @param referenceView a view that cling uses as a position reference 57 */ 58 public void updatePosition(View referenceView) { 59 if (referenceView == null) { 60 return; 61 } 62 // Right align cling: 63 float referenceRight = referenceView.getX() + referenceView.getMeasuredWidth(); 64 setTranslationX(referenceRight - getMeasuredWidth()); 65 66 float referenceTop = referenceView.getY(); 67 if (referenceTop < getMeasuredHeight()) { 68 // Layout cling under reference view. 69 setTranslationY(referenceTop + referenceView.getMeasuredHeight()); 70 float triangleStartX = getMeasuredWidth() - referenceView.getMeasuredWidth() / 2; 71 float triangleStartY = 0; 72 mTrianglePath.reset(); 73 mTrianglePath.moveTo(triangleStartX, triangleStartY); 74 mTrianglePath.lineTo(triangleStartX - mClingTriangleWidth / 2, 75 triangleStartY + mClingTriangleHeight); 76 mTrianglePath.lineTo(triangleStartX + mClingTriangleWidth / 2, 77 triangleStartY + mClingTriangleHeight); 78 mTrianglePath.lineTo(triangleStartX, triangleStartY); 79 } else { 80 // Layout cling on top of reference view. 81 setTranslationY(referenceTop - getMeasuredHeight()); 82 float triangleStartX = getMeasuredWidth() - referenceView.getMeasuredWidth() / 2; 83 float triangleStartY = getMeasuredHeight(); 84 mTrianglePath.reset(); 85 mTrianglePath.moveTo(triangleStartX, triangleStartY); 86 mTrianglePath.lineTo(triangleStartX - mClingTriangleWidth / 2, 87 triangleStartY - mClingTriangleHeight); 88 mTrianglePath.lineTo(triangleStartX + mClingTriangleWidth / 2, 89 triangleStartY - mClingTriangleHeight); 90 mTrianglePath.lineTo(triangleStartX, triangleStartY); 91 } 92 invalidate(); 93 } 94 95 @Override 96 public void onDraw(Canvas canvas) { 97 super.onDraw(canvas); 98 // Draw triangle. 99 canvas.drawPath(mTrianglePath, mClingPaint); 100 } 101 } 102