<commit_before>package com.serenegiant.widget;
/*
 * libcommon
 * utility/helper classes for myself
 *
 * Copyright (c) 2014-2020 saki <EMAIL>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
*/

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import com.serenegiant.common.R;
import com.serenegiant.glutils.IRendererCommon;
import com.serenegiant.view.ViewUtils;

import androidx.annotation.NonNull;

import static com.serenegiant.view.ViewTransformDelegater.*;

/**
 * FIXME 拡大縮小回転移動処理をDelegaterへ分けたい
 * FIXME ViewTransformDelegaterを使うように変更する？AspectScaledTextureViewを継承しているから難しそう
 */
public class ZoomAspectScaledTextureView
	extends AspectScaledTextureView implements IRendererCommon {

	private static final boolean DEBUG = false;	// TODO for debugging
	private static final String TAG = ZoomAspectScaledTextureView.class.getSimpleName();

	/**
	 * タッチ操作の有効無効設定
	 */
	@TouchMode
	private int mHandleTouchEvent;
	private float mManualScale = 1.0f;
	private float mManualRotate = Float.MAX_VALUE;

	/**
	 * 拡大縮小回転移動のための射影行列のデフォルト値
	 */
	protected final Matrix mDefaultMatrix = new Matrix();
	/**
	 * 射影行列が変更されたかどうかのフラグ(キャッシュを更新するため)
	 */
	protected boolean mImageMatrixChanged;
	/**
	 * 毎回射影行列そのものにアクセスするとJNIのオーバーヘッドがあるのでJavaのfloat配列としてキャッシュ
	 */
	protected final float[] mMatrixCache = new float[9];
	/**
	 * タッチ操作開始時の射影行列保持用
	 */
	private final Matrix mSavedImageMatrix = new Matrix();
	/**
	 * 映像を移動可能な領域
	 */
	private final RectF mLimitRect = new RectF();
	/**
	 * 映像を移動可能な領域を示すLineSegment配列
	 */
	private final ViewUtils.LineSegment[] mLimitSegments = new ViewUtils.LineSegment[4];
	/**
	 * 表示されるViewの実際のサイズ
	 */
	private final RectF mImageRect = new RectF();
	/**
	 * scaled and moved and rotated corner coordinates of image
	 * [(left,top),(right,top),(right,bottom),(left.bottom)]
	 */
	private final float[] mTransCoords = new float[8];
	/**
	 * タッチイベントのID
	 */
	private int mPrimaryId, mSecondaryId;
	/**
	 * 1つ目のタッチでのx,y座標
	 */
	private float mPrimaryX, mPrimaryY;
	/**
	 * 2つ目のタッチでのx,y座標
	 */
	private float mSecondX, mSecondY;
	/**
	 * 拡大縮小・回転時に使用するピボット座標
	 */
	private float mPivotX, mPivotY;
	/**
	 * 平行移動量
	 */
	private float mTransX, mTransY;
	/**
	 * distance between touch points when start multi touch, for calculating zooming scale
	 */
	private float mTouchDistance;
	/**
	 * current rotating degree
	 */
	private float mCurrentDegrees;
	private boolean mIsRotating;
	/**
	 * Maximum zoom scale
	 */
	protected final float mMaxScale = DEFAULT_MAX_SCALE;
	/**
	 * Minimum zoom scale, set in #init as fit the image to this view bounds
	 */
	private float mMinScale = DEFAULT_MIN_SCALE;
	/**
	 * current state, -1/STATE_NON/STATE_WAITING/STATE_DRAGGING/STATE_CHECKING
	 * 					/STATE_ZOOMING/STATE_ROTATING
	 */
	@State
	private int mState = STATE_NON;
	/**
	 * Runnable instance to wait starting image reset
	 */
	private Runnable mWaitImageReset;
	/**
	 * Runnable instance to wait starting rotation
	 */
	private Runnable mStartCheckRotate;

	@MirrorMode
    private int mMirrorMode = MIRROR_NORMAL;

	public ZoomAspectScaledTextureView(final Context context) {
		this(context, null, 0);
	}

	public ZoomAspectScaledTextureView(final Context context, final AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public ZoomAspectScaledTextureView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		if (DEBUG) Log.v(TAG, "コンストラクタ");
		final TypedArray a = context.getTheme().obtainStyledAttributes(
				attrs, R.styleable.ZoomAspectScaledTextureView, defStyleAttr, 0);
		try {
			// getIntegerは整数じゃなければUnsupportedOperationExceptionを投げる
			mHandleTouchEvent = a.getInteger(R.styleable.ZoomAspectScaledTextureView_handle_touch_event, TOUCH_ENABLED_ALL);
		} catch (final UnsupportedOperationException e) {
			Log.d(TAG, TAG, e);
			final boolean b = a.getBoolean(R.styleable.ZoomAspectScaledTextureView_handle_touch_event, true);
			mHandleTouchEvent = b ? TOUCH_ENABLED_ALL : TOUCH_DISABLED;
		} finally {
			a.recycle();
		}
	}

	@SuppressLint({"ClickableViewAccessibility", "SwitchIntDef"})
	@Override<commit_msg>コメント追加<commit_after>package com.serenegiant.widget;
/*
 * libcommon
 * utility/helper classes for myself
 *
 * Copyright (c) 2014-2020 saki <EMAIL>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
*/

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import com.serenegiant.common.R;
import com.serenegiant.glutils.IRendererCommon;
import com.serenegiant.view.ViewUtils;

import androidx.annotation.NonNull;

import static com.serenegiant.view.ViewTransformDelegater.*;

/**
 * FIXME 拡大縮小回転移動処理をDelegaterへ分けたい
 * FIXME ViewTransformDelegaterを使うように変更する？AspectScaledTextureViewを継承しているから難しそう
 */
public class ZoomAspectScaledTextureView
	extends AspectScaledTextureView implements IRendererCommon {

	private static final boolean DEBUG = false;	// TODO for debugging
	private static final String TAG = ZoomAspectScaledTextureView.class.getSimpleName();

	/**
	 * タッチ操作の有効無効設定
	 */
	@TouchMode
	private int mHandleTouchEvent;
	private float mManualScale = 1.0f;
	private float mManualRotate = Float.MAX_VALUE;

	/**
	 * 拡大縮小回転移動のための射影行列のデフォルト値
	 */
	protected final Matrix mDefaultMatrix = new Matrix();
	/**
	 * 射影行列が変更されたかどうかのフラグ(キャッシュを更新するため)
	 */
	protected boolean mImageMatrixChanged;
	/**
	 * 毎回射影行列そのものにアクセスするとJNIのオーバーヘッドがあるのでJavaのfloat配列としてキャッシュ
	 */
	protected final float[] mMatrixCache = new float[9];
	/**
	 * タッチ操作開始時の射影行列保持用
	 */
	private final Matrix mSavedImageMatrix = new Matrix();
	/**
	 * 映像を移動可能な領域
	 */
	private final RectF mLimitRect = new RectF();
	/**
	 * 映像を移動可能な領域を示すLineSegment配列
	 */
	private final ViewUtils.LineSegment[] mLimitSegments = new ViewUtils.LineSegment[4];
	/**
	 * 表示されるViewの実際のサイズ
	 */
	private final RectF mImageRect = new RectF();
	/**
	 * scaled and moved and rotated corner coordinates of image
	 * [(left,top),(right,top),(right,bottom),(left.bottom)]
	 */
	private final float[] mTransCoords = new float[8];
	/**
	 * タッチイベントのID
	 */
	private int mPrimaryId, mSecondaryId;
	/**
	 * 1つ目のタッチでのx,y座標
	 */
	private float mPrimaryX, mPrimaryY;
	/**
	 * 2つ目のタッチでのx,y座標
	 */
	private float mSecondX, mSecondY;
	/**
	 * 拡大縮小・回転時に使用するピボット座標
	 */
	private float mPivotX, mPivotY;
	/**
	 * 平行移動量
	 */
	private float mTransX, mTransY;
	/**
	 * distance between touch points when start multi touch, for calculating zooming scale
	 */
	private float mTouchDistance;
	/**
	 * current rotating degree
	 */
	private float mCurrentDegrees;
	private boolean mIsRotating;
	/**
	 * Maximum zoom scale
	 */
	protected final float mMaxScale = DEFAULT_MAX_SCALE;
	/**
	 * Minimum zoom scale, set in #init as fit the image to this view bounds
	 */
	private float mMinScale = DEFAULT_MIN_SCALE;
	/**
	 * current state, -1/STATE_NON/STATE_WAITING/STATE_DRAGGING/STATE_CHECKING
	 * 					/STATE_ZOOMING/STATE_ROTATING
	 */
	@State
	private int mState = STATE_NON;
	/**
	 * Runnable instance to wait starting image reset
	 */
	private Runnable mWaitImageReset;
	/**
	 * Runnable instance to wait starting rotation
	 */
	private Runnable mStartCheckRotate;

	@MirrorMode
    private int mMirrorMode = MIRROR_NORMAL;

	/**
	 * コンストラクタ
	 * @param context
	 */
	public ZoomAspectScaledTextureView(final Context context) {
		this(context, null, 0);
	}

	/**
	 * コンストラクタ
	 * @param context
	 * @param attrs
	 */
	public ZoomAspectScaledTextureView(final Context context, final AttributeSet attrs) {
		this(context, attrs, 0);
	}

	/**
	 * コンストラクタ
	 * @param context
	 * @param attrs
	 * @param defStyleAttr
	 */
	public ZoomAspectScaledTextureView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		if (DEBUG) Log.v(TAG, "コンストラクタ");
		final TypedArray a = context.getTheme().obtainStyledAttributes(
				attrs, R.styleable.ZoomAspectScaledTextureView, defStyleAttr, 0);
		try {
			// getIntegerは整数じゃなければUnsupportedOperationExceptionを投げる
			mHandleTouchEvent = a.getInteger(R.styleable.ZoomAspectScaledTextureView_handle_touch_event, TOUCH_ENABLED_ALL);
		} catch (final UnsupportedOperationException e) {
			Log.d(TAG, TAG, e);
			final boolean b = a.getBoolean(R.styleable.ZoomAspectScaledTextureView_handle_touch_event, true);
			mHandleTouchEvent = b ? TOUCH_ENABLED_ALL : TOUCH_DISABLED;
		} finally {
			a.recycle();
		}
	}

	@SuppressLint({"ClickableViewAccessibility", "SwitchIntDef"})
	@Override
{'fraction_non_alphanumeric': 0.095351137487636, 'fraction_numerical': 0.004549950544015826, 'mean_word_length': 4.45361380798274, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4266750', 'n_tokens_mistral': 3795, 'n_tokens_neox': 3577, 'n_words': 818}