126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu/* 226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * Copyright (C) 2014 The Android Open Source Project 326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * 426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * Licensed under the Apache License, Version 2.0 (the "License"); 526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * you may not use this file except in compliance with the License. 626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * You may obtain a copy of the License at 726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * 826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * http://www.apache.org/licenses/LICENSE-2.0 926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * 1026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * Unless required by applicable law or agreed to in writing, software 1126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * distributed under the License is distributed on an "AS IS" BASIS, 1226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * See the License for the specific language governing permissions and 1426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * limitations under the License. 1526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu */ 1626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 1726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liupackage com.android.camera.widget; 1826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 1926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.content.Context; 2026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.graphics.Canvas; 2126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.graphics.Paint; 2226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.graphics.Path; 2326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.util.AttributeSet; 2426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.view.View; 2526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport android.widget.FrameLayout; 2626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 2726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liuimport com.android.camera2.R; 2826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 2926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu/** 3026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * This is a cling widget for settings button. In addition to drawing a cling button 3126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * background and overlaying text, it draws a small triangle that points at the 3226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * settings button that this cling is for. 3326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu */ 3426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liupublic class SettingsCling extends FrameLayout { 3526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu private final int mClingTriangleHeight; 3626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu private final int mClingTriangleWidth; 3726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu private final Path mTrianglePath = new Path(); 3826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu private final Paint mClingPaint = new Paint(); 3926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 4026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu public SettingsCling(Context context, AttributeSet attrs) { 4126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu super(context, attrs); 4226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu setWillNotDraw(false); 4326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mClingTriangleHeight = getResources().getDimensionPixelSize( 4426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu R.dimen.settings_cling_triangle_height); 4526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mClingTriangleWidth = getResources().getDimensionPixelSize( 4626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu R.dimen.settings_cling_triangle_width); 4726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mClingPaint.setColor(getResources().getColor(R.color.settings_cling_color)); 4826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mClingPaint.setStyle(Paint.Style.FILL); 4926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu } 5026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 5126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu /** 5226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * Updates the current position of the cling based on a reference view. If there 5326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * is enough space to lay out the cling on top of the reference view, then have 5426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * the cling on top. Otherwise, position the cling underneath the reference view. 5526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * 5626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu * @param referenceView a view that cling uses as a position reference 5726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu */ 5826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu public void updatePosition(View referenceView) { 5926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu if (referenceView == null) { 6026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu return; 6126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu } 6226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu // Right align cling: 6326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu float referenceRight = referenceView.getX() + referenceView.getMeasuredWidth(); 6426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu setTranslationX(referenceRight - getMeasuredWidth()); 6526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 6626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu float referenceTop = referenceView.getY(); 6726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu if (referenceTop < getMeasuredHeight()) { 6826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu // Layout cling under reference view. 6926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu setTranslationY(referenceTop + referenceView.getMeasuredHeight()); 7026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu float triangleStartX = getMeasuredWidth() - referenceView.getMeasuredWidth() / 2; 7126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu float triangleStartY = 0; 7226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.reset(); 7326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.moveTo(triangleStartX, triangleStartY); 7426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.lineTo(triangleStartX - mClingTriangleWidth / 2, 7526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu triangleStartY + mClingTriangleHeight); 7626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.lineTo(triangleStartX + mClingTriangleWidth / 2, 7726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu triangleStartY + mClingTriangleHeight); 7826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.lineTo(triangleStartX, triangleStartY); 7926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu } else { 8026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu // Layout cling on top of reference view. 8126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu setTranslationY(referenceTop - getMeasuredHeight()); 8226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu float triangleStartX = getMeasuredWidth() - referenceView.getMeasuredWidth() / 2; 8326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu float triangleStartY = getMeasuredHeight(); 8426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.reset(); 8526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.moveTo(triangleStartX, triangleStartY); 8626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.lineTo(triangleStartX - mClingTriangleWidth / 2, 8726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu triangleStartY - mClingTriangleHeight); 8826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.lineTo(triangleStartX + mClingTriangleWidth / 2, 8926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu triangleStartY - mClingTriangleHeight); 9026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mTrianglePath.lineTo(triangleStartX, triangleStartY); 9126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu } 9226aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu invalidate(); 9326aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu } 9426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu 9526aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu @Override 9626aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu public void onDraw(Canvas canvas) { 9726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu super.onDraw(canvas); 9826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu // Draw triangle. 9926aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu canvas.drawPath(mTrianglePath, mClingPaint); 10026aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu } 10126aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu} 102