ViewDayHourItem.java :  » Calendar » ancal » pl » magot » vetch » ancal » views » Android Open Source

Android Open Source » Calendar » ancal 
ancal » pl » magot » vetch » ancal » views » ViewDayHourItem.java

package pl.magot.vetch.ancal.views;


import android.content.*;
import android.graphics.*;
import android.view.MotionEvent;
import android.view.View;
import android.widget.*;
import pl.magot.vetch.ancal.*;

public class ViewDayHourItem extends LinearLayout
{
  //inner invisible view for touch mode
  public class InvisibleView extends View
  {
    //fields
    private final int iFrame = 2;
    
    //methods
    public InvisibleView(Context context)
    {
      super(context);
      setFocusable(false);
      LinearLayout.LayoutParams layParams = 
        new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
      this.setLayoutParams(layParams);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
      setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));         
    }    
    private int measureWidth(int measureSpec)
    {
      return MeasureSpec.getSize(measureSpec);
    }     
    private int measureHeight(int measureSpec)
    {
      return iFrame + iItemTextHeight + iFrame + iFrame;      
    }    
  }

  //types
  public interface OnItemClick
  {
    public void OnClick(ViewDayHourItem item);
  }
  
  //fields
  private static final String sStrHour = "00";
  private static final String sStrTime = "00:00";
  private static final String sStrUSTimeMark = "mm"; //am/pm
  private static final String sStrUSTimeAM = "am";
  private static final String sStrUSTimePM = "pm";
  
  //fields
  private static final int iSpace = 4;
  private static final int iFrame = 2;
  private static final Typeface tfMono = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL);
  private static final float fTextSize = 20;

  //fields
  private boolean b24HourMode = false;
  private int iHour = 0;
  private int iCurrentHour = -1;
  protected OnItemClick itemClick = null;
  
  //default hour width, full time width, am/pm width
  private int iSpaceWidthUSTimeMark = 0;
  private int iSpaceWidthHourWithUSTimeMark = 0;  
  private int iSpaceWidthTimeWithUSTimeMark = 0;
  private int iSpaceWidthHourArea = 0;
  private int iSpaceWidthTimeArea = 0;
  private int iItemTextHeight = 0;
  
  //colors
  private final static int iColorTime = 0xFFFF8800;
  private final static int iColorMark = 0xFFAA5500;
  private final static int iColorTimeFocused = 0xFFFFCC66;
  private final static int iColorTimeTouch = 0xFF222222;
  private final int iTouchSliderColor = 0xBBFF8800;
  private final int iTouchPatternColor = 0xFF995500;
  
  //fields
  protected Paint mpt = null;

  //touch mode fields
  private static InvisibleView invView = null;
  private boolean bTouchedDown = false;
  private RectF rtTouchRect = new RectF();
  private RectF rtTimeTouchRect = new RectF();
  private RectF rtTouchSliderRect = new RectF();
  private RectF rectSliderArrow = new RectF();
  private int iTouchPosX = 0;
  private int iLastTimeMinutes = 0;

  //methods
  public ViewDayHourItem(Context context, int iHour, int iItemTextHeight)
  {
    super(context);

    this.iHour = iHour;
    this.iItemTextHeight = iItemTextHeight;
    
    mpt = new Paint();
    mpt.setAntiAlias(true);
    mpt.setTextSize(fTextSize);
    
    setWillNotDraw(false);
    
    setOrientation(LinearLayout.VERTICAL);
    LayoutParams lparams = new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    setLayoutParams(lparams);

    //invisible view
    if (invView == null)
    {
      invView = new InvisibleView(context);
      invView.setVisibility(View.INVISIBLE);
    }
  }
    
  public void SetItemClick(OnItemClick itemClick)  
  {
    this.itemClick = itemClick;  
  }

  public void SetItemData(boolean b24HourMode, int iSpaceWidthHour, int iSpaceWidthTime, int iSpaceWidthUSTimeMark)
  {
    this.b24HourMode = b24HourMode;
    UpdateTimeFormat(b24HourMode, iSpaceWidthHour, iSpaceWidthTime, iSpaceWidthUSTimeMark);
    UpdateHeight();
  }
  
  public void SetCurrentHour(int iCurrentHour)
  {
    this.iCurrentHour = iCurrentHour;     
  }
  
  public void UpdateTimeFormat(boolean b24HourMode, int iSpaceWidthHour, int iSpaceWidthTime, int iSpaceWidthUSTimeMark)
  {
    this.iSpaceWidthUSTimeMark = (b24HourMode?0:iSpaceWidthUSTimeMark);
    this.iSpaceWidthHourWithUSTimeMark = iSpaceWidthHour + (b24HourMode?0:(iSpaceWidthUSTimeMark + iFrame));
    this.iSpaceWidthTimeWithUSTimeMark = iSpaceWidthTime + (b24HourMode?0:(iSpaceWidthUSTimeMark + iFrame));
    this.iSpaceWidthHourArea = iSpace + iSpaceWidthHourWithUSTimeMark + iSpace;
    this.iSpaceWidthTimeArea = iSpace + iSpaceWidthTimeWithUSTimeMark + iSpace;
    setPadding(iSpaceWidthHourArea, iFrame + iFrame, iFrame, iFrame + iFrame);
  }
  
  
  public int GetHour()
  {
    return iHour;
  }
  
  public int GetMinutes()
  {
    return iLastTimeMinutes;
  }

  public static int GetTextHeight(Paint mpt)
  {
    mpt.setTypeface(null);
    mpt.setTextSize(fTextSize);    
    mpt.setFakeBoldText(true);
    return (int)(-mpt.ascent() + mpt.descent());
  }
  
  public static int GetSpaceWidthHour(Paint mpt)
  {
    mpt.setTypeface(tfMono);
    mpt.setTextSize(fTextSize);    
    mpt.setFakeBoldText(true);
    return (int)mpt.measureText(sStrHour);
  }
  
  public static int GetSpaceWidthTime(Paint mpt)
  {
    mpt.setTypeface(tfMono);
    mpt.setTextSize(fTextSize);    
    mpt.setFakeBoldText(true);
    return (int)mpt.measureText(sStrTime);    
  }

  public static int GetSpaceWidthUSTimeMark(Paint mpt)
  {
    mpt.setTypeface(tfMono);
    mpt.setTextSize(fTextSize);    
    mpt.setFakeBoldText(false);
    return (int)mpt.measureText(sStrUSTimeMark);    
  }  
    
  private int GetMinHeight()
  {
    return getPaddingTop() + iFrame + iItemTextHeight + iFrame + getPaddingBottom() - 1;
  }

  public void UpdateHeight()
  {
    this.getLayoutParams().height = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
    if (getChildCount() == 0)
    {
      if ((iHour >= 6) && (iHour <= 22))
      {
        this.getLayoutParams().height = GetMinHeight(); 
      } else {
        this.getLayoutParams().height = 0; 
      }
    }
  }
   
  public boolean IsMinimized()
  {
    return getHeight() == 0;
  }
  
  @Override
  protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)
  {
    super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
    invalidate();
  }
  
  @Override
  protected void onDraw(Canvas canvas)
  {
    super.onDraw(canvas);
        
    mpt.setAntiAlias(true);
    mpt.setTextSize(fTextSize);    
    mpt.setTypeface(tfMono);
    mpt.setFakeBoldText(true);
    mpt.setShader(null);
    mpt.setUnderlineText(false);
        
    final boolean bIsFocused = hasFocus();
    final int iHeight = getHeight() - iFrame;
    final int iWidth = getWidth();    
    final int iTimePosY = (- (int)mpt.ascent()) + iFrame + iFrame + 1;

    if (!IsMinimized())
    {
      GetTouchRectangle();
      
      DrawBackground(canvas, iWidth, iHeight, bIsFocused);
      
      DrawTime(canvas, iTimePosY, iWidth, iHeight, bIsFocused);
      
      if (bTouchedDown)
      {
        GetTouchSliderRectangle();
        DrawTouchSlider(canvas);
        DrawTouchBar(canvas);
      }
    }
   }

  private void DrawBackground(Canvas canvas, int iWidth, int iHeight, boolean bIsFocused)
  {      
    mpt.setTypeface(null);     
    mpt.setShader(null);    

    //draw touch slider background
    if (bTouchedDown)
    {
      mpt.setColor(iColorTime);
      canvas.drawRoundRect(rtTouchRect, 3, 3, mpt);
    }

    //draw gradient line 
    LinearGradient lGrad = new LinearGradient((getWidth() >> 2), 0, getWidth(), 0,
        0xFFFFFFFF, 0x00FFFFFF, Shader.TileMode.CLAMP);    
    mpt.setShader(lGrad);    
    canvas.drawLine(0, 0, getWidth(), 0, mpt);
    
    mpt.setShader(null);
  }
  
  private String GetHourString()
  {        
    if (b24HourMode)
    {
      return Integer.toString(iHour);
    } else {
      int iDisplayHour = iHour;      
      if (iDisplayHour == 0)
        iDisplayHour = 12;      
      if (iDisplayHour > 12)
        iDisplayHour -= 12;
      return Integer.toString(iDisplayHour);
    }
  }
  
  private String GetMinutesString()
  {    
    if (iLastTimeMinutes > 9)
      return ":" + Integer.toString(iLastTimeMinutes);
    return ":0" + Integer.toString(iLastTimeMinutes);
  }

  private String GetUSTimeMark()
  {
    if (iHour >= 12)
      return sStrUSTimePM;
    return sStrUSTimeAM;
  }

  private void DrawTime(Canvas canvas, int iTimePosY, int iWidth, int iHeight, boolean bIsFocused)
  {
    mpt.setAntiAlias(true);
    mpt.setTextSize(fTextSize);    
    mpt.setTypeface(tfMono);
    mpt.setFakeBoldText(true);
    mpt.setShader(null);
    
    mpt.setUnderlineText(false);
    if (iCurrentHour == iHour)
      mpt.setUnderlineText(true);
    
    //draw hour
    final String sHour = GetHourString();
    final int iStrHourWidth = (int)mpt.measureText(sHour);    
    final int iTimePosX = iSpaceWidthHourArea - iStrHourWidth - iFrame - iSpaceWidthUSTimeMark - iSpace;
    mpt.setColor((bTouchedDown)?iColorTimeTouch:iColorTime);
    if (bIsFocused)
      mpt.setColor(iColorTimeFocused);          
    canvas.drawText(sHour, iTimePosX, iTimePosY, mpt);
        
    //draw minutes
    int iMarkPosX = iTimePosX + iStrHourWidth + iFrame;
    if (bTouchedDown)
    {
      final String sMinutes = GetMinutesString();
      final int iStrMinutesWidth = (int)mpt.measureText(sMinutes);    
      final int iMinutesPosX = iTimePosX + iStrHourWidth;
      iMarkPosX = iMinutesPosX + iStrMinutesWidth + iFrame;
      canvas.drawText(sMinutes, iMinutesPosX, iTimePosY, mpt);
    }
    
    //draw us time mark
    if (!b24HourMode)
    {            
      mpt.setFakeBoldText(false);
      mpt.setColor(iColorMark);
      if (bIsFocused)
        mpt.setColor(iColorTimeFocused);          
      canvas.drawText(GetUSTimeMark(), iMarkPosX, iTimePosY, mpt);
    }
    
    mpt.setUnderlineText(false);
  }
  
  private void DrawTouchSlider(Canvas canvas)
  {
    //draw inner background
    mpt.setShader(null);
    mpt.setColor(iColorTimeTouch);
    canvas.drawRoundRect(rtTouchSliderRect, 3, 3, mpt);
    
    //draw slider pattern
    mpt.setColor(iTouchPatternColor);
    mpt.setStrokeWidth(4);
    mpt.setStrokeCap(Paint.Cap.ROUND);
    
    rectSliderArrow.set(rtTouchSliderRect);    
    final int iArrowWidth = 6;
    final int iArrowSpace = 8;
    final int iArrowCount = (int)(rtTouchSliderRect.width() / (iArrowWidth + iArrowSpace));

    final int iMargin = (int)rtTouchSliderRect.width() - (iArrowCount * (iArrowWidth + iArrowSpace));
    rectSliderArrow.left += iMargin;
    
    for (int i = 0; i < iArrowCount; i++)
    {    
      DrawTouchSliderArrow(canvas, rectSliderArrow, iArrowWidth);      
      rectSliderArrow.left += iArrowWidth + iArrowSpace;
    }
            
    mpt.setStrokeWidth(0);
  }
  
  private void DrawTouchSliderArrow(Canvas canvas, RectF rect, int iArrowWidth)
  {
    int istartX = (int)(rect.left);
    int istopX = (int)(rect.left + iArrowWidth);    
    int iCenter = (int)(rect.top + (rect.height() / 2));    
    canvas.drawLine(istartX, rect.top + 5, istopX, iCenter, mpt);
    canvas.drawLine(istartX, rect.bottom - 5, istopX, iCenter, mpt);    
  }

  private void DrawTouchBar(Canvas canvas)
  {
    //draw inner background
    mpt.setShader(null);
    mpt.setColor(iTouchSliderColor);

    //control ranges
    float fMaxRight = rtTouchSliderRect.right;  
    rtTouchSliderRect.right = iTouchPosX;
    if (rtTouchSliderRect.right > fMaxRight)
      rtTouchSliderRect.right = fMaxRight;
    if (rtTouchSliderRect.right < rtTouchSliderRect.left)
      rtTouchSliderRect.right = rtTouchSliderRect.left;

    canvas.drawRoundRect(rtTouchSliderRect, 2, 2, mpt);
  }  
    
  public int CalculateTimeMinutes()
  {
    RectF rectSlider = GetTouchSliderRectangle();    
    if (iTouchPosX > 0)
    {
      if ((iTouchPosX > rectSlider.left) && (iTouchPosX < rectSlider.right))
      {
        float fRange = rectSlider.right - rectSlider.left;
        float fPos = iTouchPosX - rectSlider.left;        
        float fStep = (fRange / 60);
        int iMinutes = (int)(fPos / fStep);        
        if (iMinutes < 0)
          iMinutes = 0;
        if (iMinutes > 59)
          iMinutes = 59;
                
        int iModulo = iMinutes % 5;        
        iMinutes = iMinutes - iModulo; 
                                
        return iMinutes;
      }
    }  
    return 0;
  }  
  
  public void doItemClick()
  {
    if (itemClick != null)
        itemClick.OnClick(this);  
  }
  
  private RectF GetTouchRectangle()
  {
     rtTouchRect.set(0, 3, getWidth() - 1, GetMinHeight() - 2);      
    return rtTouchRect;
  }
  
  private RectF GetTimeTouchRectangle()
  {
    rtTimeTouchRect.set(iFrame, 2, iSpaceWidthTimeArea - iFrame, GetMinHeight() - 2);
    return rtTimeTouchRect;
  }
  
  private RectF GetTouchSliderRectangle()
  {
    rtTouchSliderRect.set(GetTouchRectangle());    
    rtTouchSliderRect.inset(2, 2);
    rtTouchSliderRect.left = iSpaceWidthTimeArea + iSpace + iSpace;
    rtTouchSliderRect.right = rtTouchSliderRect.right - iSpace - iSpace - iSpace;
    return rtTouchSliderRect;
  }  
  
  private boolean TouchInTimeArea(MotionEvent event)
  {
    RectF rect = GetTimeTouchRectangle();
    if (rect.contains(event.getX(), event.getY()))
      return true;    
    return false;
  }
  
  @Override
  public boolean onTouchEvent(MotionEvent event)
  {
    boolean bHandled = false;
    if (event.getAction() == MotionEvent.ACTION_DOWN)
    {      
      if (TouchInTimeArea(event))
      {                
        bHandled = true;
        bTouchedDown = true;
        iLastTimeMinutes = 0;
        iTouchPosX = 0;
        EnableInnerViewSpace(true);
        invalidate();
        Utils.startAlphaAnimIn(ViewDayHourItem.this);
      }
    }
    if (event.getAction() == MotionEvent.ACTION_CANCEL)
    {
      bHandled = true;
      bTouchedDown = false;
      iTouchPosX = 0;
      EnableInnerViewSpace(false);
      invalidate();
    }
    if (event.getAction() == MotionEvent.ACTION_UP)
    {
       bHandled = true;
       bTouchedDown = false;
      EnableInnerViewSpace(false);
       invalidate();              
      doItemClick();
    }
    if (event.getAction() == MotionEvent.ACTION_MOVE)
    {
      bHandled = true;
      iTouchPosX = (int)event.getX();
       iLastTimeMinutes = CalculateTimeMinutes();       
      invalidate();
    }
    return bHandled;            
  }
  
  private void EnableInnerViewSpace(boolean bEnable)
  {
    if (bEnable)
    {
      this.addView(invView, 0);      
    } else {
      this.removeView(invView);
    }
  }
    
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.