content: package com.wanjian.sak.layer.impl;
  
  import android.graphics.Bitmap;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Matrix;
  import android.graphics.Paint;
  import android.graphics.Rect;
  import android.graphics.drawable.BitmapDrawable;
  import android.graphics.drawable.Drawable;
  import android.view.InputEvent;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ImageView;
  import android.widget.TextView;
  
  import com.wanjian.sak.converter.ISizeConverter;
  import com.wanjian.sak.layer.Layer;
  import com.wanjian.sak.layer.impl_tmp.InfoLayer;
  import com.wanjian.sak.utils.ScreenUtils;
  
  import static android.view.View.GONE;
  import static android.view.View.INVISIBLE;
  import static android.view.View.VISIBLE;
  
  
  /**
   * Created by wanjian on 2016/10/24.
   */
  
  public class TreeView extends Layer {
    private Paint mPaint;
    private int mTabW;
    private int mTxtH;
    private int mCurLayer;
    private Matrix mMatrix;
    private Matrix mDrawMatrix;
    private int[] mLocation = new int[2];
    private float mLastX;
    private float mLastY;
    private int mMode = 0;
    private float mLastDist;
    private boolean mIsScale;
  
    @Override
    protected void onAttach(View rootView) {
      super.onAttach(rootView);
      init();
      invalidate();
    }
  
    private int convertSize(int leng) {
      return (int) getSizeConverter().convert(getContext(), leng).getLength();
    }
  
    private ISizeConverter getSizeConverter() {
      return ISizeConverter.CONVERTER;
    }
  
    private void init() {
      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mPaint.setColor(Color.WHITE);
      mPaint.setTextSize(ScreenUtils.dp2px(getContext(), 12));
      mTabW = ScreenUtils.dp2px(getContext(), 20);
      Rect rect = new Rect();
      mPaint.getTextBounds("Aj", 0, 2, rect);
      mTxtH = rect.height() * 2;
  //        setBackgroundColor(0x88000000);
      mDrawMatrix = new Matrix();
    }
  
    @Override
    protected void onAfterTraversal(View rootView) {
      super.onAfterTraversal(rootView);
      invalidate();
    }
  
    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      canvas.drawColor(0x88000000);
      canvas.setMatrix(mDrawMatrix);
      mCurLayer = -1;
      layerCount(canvas, getRootView());
    }
  
    private void layerCount(Canvas canvas, View view) {
  //    if (view == null || view instanceof RootContainerView || getViewFilter().filter(view) == false) {
  //      return;
  //    }
      mCurLayer++;
      drawLayer(canvas, view);
      if (view instanceof ViewGroup) {
        ViewGroup vg = ((ViewGroup) view);
        for (int i = 0; i < vg.getChildCount(); i++) {
          View child = vg.getChildAt(i);
          layerCount(canvas, child);
        }
      }
      mCurLayer--;
    }
  
    private void drawLayer(Canvas canvas, View view) {
      canvas.translate(0, mTxtH);
      canvas.save();
      if (view.getVisibility() != VISIBLE) {
        mPaint.setColor(0xFFAAAAAA);
      } else {
        mPaint.setColor(Color.WHITE);
      }
      for (int i = 0; i < mCurLayer; i++) {
        canvas.translate(mTabW, 0);
        canvas.drawText("|", 0, 0, mPaint);
      }
      canvas.translate(mTabW, 0);
      String txt = getInfo(view);
      canvas.drawText(txt, 0, 0, mPaint);
      if (view instanceof ImageView) {
        float len = mPaint.measureText(txt);
        canvas.translate(len, 0);
        drawBitmap(canvas, ((ImageView) view));
        canvas.translate(-len, 0);
      }
      canvas.restore();
    }
  
    private void drawBitmap(Canvas canvas, ImageView view) {
      if (view == null) {
        return;
      }
      Drawable drawable = view.getDrawable();
      if (drawable instanceof BitmapDrawable) {
        Bitmap bmp = ((BitmapDrawable) drawable).getBitmap();
        if (bmp != null && !bmp.isRecycled()) {
          if (mMatrix == null) {
            mMatrix = new Matrix();
          } else {
            mMatrix.reset();
          }
          float scale = mTxtH * 1.0f / bmp.getHeight();
          float w = scale * bmp.getWidth();
          canvas.drawText(" -bmp(w:" + convertSize(bmp.getWidth()) + " h:" + convertSize(bmp.getHeight()) + ")", w, 0, mPaint);
          mMatrix.setScale(scale, scale);
          canvas.translate(0, -mTxtH >> 1);
          canvas.drawBitmap(bmp, mMatrix, mPaint);
          canvas.translate(0, mTxtH >> 1);
        }
      }
  
    }
  
    protected String getInfo(View view) {
      StringBuilder sb = new StringBuilder(100);
      sb.append(view.getClass().getName()).append(" ");
  
      sb.append("-(w:").append(convertSize(view.getWidth()));
      sb.append(" h:").append(convertSize(view.getHeight())).append(") ");
  
      view.getLocationOnScreen(mLocation);
      sb.append(" -loc(x:")
          .append(convertSize(mLocation[0]))
          .append("-")
          .append(convertSize(mLocation[0] + view.getWidth()))
          .append(" y:")
          .append(convertSize(mLocation[1]))
          .append("-")
          .append(convertSize(mLocation[1] + view.getHeight()))
          .append(")");
  
      sb.append(" -P(l:").append(convertSize(view.getPaddingLeft())).append(" t:").append(convertSize(view.getPaddingTop()))
          .append(" r:").append(convertSize(view.getPaddingRight())).append(" b:").append(convertSize(view.getPaddingBottom())).append(")");
  
      ViewGroup.LayoutParams param = view.getLayoutParams();
      if (param instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams marginLayoutParams = ((ViewGroup.MarginLayoutParams) param);
        sb.append(" -M(l:").append(convertSize(marginLayoutParams.leftMargin)).append(" t:").append(convertSize(marginLayoutParams.topMargin))
            .append(" r:").append(convertSize(marginLayoutParams.rightMargin)).append(" b:").append(convertSize(marginLayoutParams.bottomMargin)).append(")");
  
      }
      int visible = view.getVisibility();
      String visStr = "";
      if (visible == VISIBLE) {
        visStr = "visible";
      } else if (visible == INVISIBLE) {
        visStr = "invisible";
      } else if (visible == GONE) {
        visStr = "gone";
      }
  
      if (view instanceof TextView) {
        String txt = ((TextView) view).getText().toString();
        sb.append(" -txt:").append(txt);
      }
      sb.append(" -visible:").append(visStr).append(" ");
      sb.append(" -extra:").append(view.getTag(InfoLayer.INFO_KEY));
  
      return sb.toString();
    }
  
    @Override
    protected boolean onBeforeInputEvent(View rootView, InputEvent event) {
      if (event instanceof MotionEvent) {
        onTouchEvent((MotionEvent) event);
        return true;
      }
      return false;
    }
  
    private boolean onTouchEvent(MotionEvent event) {
  
      switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
          mLastX = event.getX();
          mLastY = event.getY();
          mIsScale = false;
          mMode = 1;
          break;
        case MotionEvent.ACTION_UP:
          mMode = 0;
          break;
        case MotionEvent.ACTION_POINTER_UP:
          mMode -= 1;
          break;
        case MotionEvent.ACTION_POINTER_DOWN:
          mLastDist = spacing(event);
          mMode += 1;
          break;
  
        case MotionEvent.ACTION_MOVE:
          if (mMode >= 2) {
            float newDist = spacing(event);
            float factor = newDist / mLastDist;
            mDrawMatrix.postScale(factor, factor);
            mLastDist = newDist;
            mIsScale = true;
          } else {
            if (mIsScale) {
              break;
            }
            float curX = event.getX();
            float curY = event.getY();
            mDrawMatrix.postTranslate(curX - mLastX, curY - mLastY);
            mLastX = curX;
            mLastY = curY;
          }
          invalidate();
          break;
      }
  
      return true;
    }
  
  
    private float spacing(MotionEvent event) {
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return (float) Math.sqrt(x * x + y * y);
    }
  
  
    protected int px2dp(float px) {
      final float scale = getContext().getResources().getDisplayMetrics().density;
      return (int) (px / scale + 0.5f);
    }
  
  
  }
  