/** * Copyright (C) 2013- Iordan Iordanov * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ package com.undatech.opaque.input; import android.os.Vibrator; import android.widget.RelativeLayout; import android.widget.ImageButton; import android.view.MotionEvent; import android.view.View.OnClickListener; import android.view.View; import com.undatech.opaque.R; import com.undatech.opaque.RemoteCanvas; import com.undatech.opaque.RemoteCanvasActivity; import com.undatech.opaque.input.RemotePointer; public class InputHandlerSingleHanded extends InputHandlerDirectSwipePan { static final String TAG = "InputHandlerSingleHanded"; public static final String ID = "SingleHanded"; private RelativeLayout singleHandOpts; private ImageButton dragModeButton; private ImageButton rightDragModeButton; private ImageButton middleDragModeButton; private ImageButton scrollButton; private ImageButton zoomButton; private ImageButton cancelButton; int accumulatedScroll; private int eventStartX, eventStartY, eventAction, eventMeta; private boolean needInitPan; public InputHandlerSingleHanded(RemoteCanvasActivity activity, RemoteCanvas canvas, Vibrator myVibrator) { super(activity, canvas, myVibrator); initializeButtons(); } /** * Initializes the on-screen single-handed mode-selector buttons. */ private void initializeButtons() { singleHandOpts = (RelativeLayout) activity.findViewById(R.id.singleHandOpts); dragModeButton = (ImageButton) activity.findViewById(R.id.singleDrag); dragModeButton.setOnClickListener(new OnClickListener () { @Override public void onClick(View arg0) { startNewSingleHandedGesture(); dragMode = true; RemotePointer p = canvas.getPointer(); p.leftButtonDown(eventStartX, eventStartY, eventMeta); canvas.displayShortToastMessage(R.string.single_left); } }); rightDragModeButton = (ImageButton) activity.findViewById(R.id.singleRight); rightDragModeButton.setOnClickListener(new OnClickListener () { @Override public void onClick(View arg0) { startNewSingleHandedGesture(); rightDragMode = true; RemotePointer p = canvas.getPointer(); p.rightButtonDown(eventStartX, eventStartY, eventMeta); canvas.displayShortToastMessage(R.string.single_right); } }); middleDragModeButton = (ImageButton) activity.findViewById(R.id.singleMiddle); middleDragModeButton.setOnClickListener(new OnClickListener () { @Override public void onClick(View arg0) { startNewSingleHandedGesture(); middleDragMode = true; RemotePointer p = canvas.getPointer(); p.middleButtonDown(eventStartX, eventStartY, eventMeta); canvas.displayShortToastMessage(R.string.single_middle); } }); scrollButton = (ImageButton) activity.findViewById(R.id.singleScroll); scrollButton.setOnClickListener(new OnClickListener () { @Override public void onClick(View arg0) { startNewSingleHandedGesture(); canvas.cursorBeingMoved = true; inSwiping = true; RemotePointer p = canvas.getPointer(); p.moveMouseButtonUp(eventStartX, eventStartY, eventMeta); canvas.displayShortToastMessage(R.string.single_scroll); } }); zoomButton = (ImageButton) activity.findViewById(R.id.singleZoom); zoomButton.setOnClickListener(new OnClickListener () { @Override public void onClick(View arg0) { startNewSingleHandedGesture(); inScaling = true; canvas.displayShortToastMessage(R.string.single_zoom); } }); cancelButton = (ImageButton) activity.findViewById(R.id.singleCancel); cancelButton.setOnClickListener(new OnClickListener () { @Override public void onClick(View arg0) { singleHandOpts.setVisibility(View.GONE); canvas.displayShortToastMessage(R.string.single_cancel); } }); } /** * Indicates the start of a single-handed gesture. */ private void startNewSingleHandedGesture() { singleHandOpts.setVisibility(View.GONE); endDragModesAndScrolling (); singleHandedGesture = true; accumulatedScroll = 0; } /* * (non-Javadoc) * @see com.undatech.opaque.input.InputHandlerDirectSwipePan#getDescription() */ @Override public String getDescription() { return canvas.getResources().getString(R.string.input_method_single_handed_description); } /* * (non-Javadoc) * @see com.undatech.opaque.input.InputHandlerDirectSwipePan#getId() */ @Override public String getId() { return ID; } /* * (non-Javadoc) * @see com.undatech.opaque.input.InputHandlerGeneric#onLongPress(android.view.MotionEvent) */ @Override public void onLongPress(MotionEvent e) { //android.util.Log.e(TAG, "Long press."); if (singleHandedGesture || singleHandedJustEnded) return; boolean buttonsVisible = (singleHandOpts.getVisibility() == View.VISIBLE); initializeSingleHandedMode(e); if (buttonsVisible) canvas.displayShortToastMessage(R.string.single_reposition); else canvas.displayShortToastMessage(R.string.single_choose); } private void initializeSingleHandedMode(MotionEvent e) { eventStartX = getX(e); eventStartY = getY(e); xInitialFocus = e.getX(); yInitialFocus = e.getY(); needInitPan = true; eventAction = e.getAction(); eventMeta = e.getMetaState(); singleHandOpts.setVisibility(View.VISIBLE); // Move pointer to where we're performing gesture. RemotePointer p = canvas.getPointer(); p.moveMouseButtonUp(eventStartX, eventStartY, eventMeta); } /* * (non-Javadoc) * @see com.undatech.opaque.input.InputHandlerGeneric#onSingleTapConfirmed(android.view.MotionEvent) */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { boolean buttonsVisible = (singleHandOpts.getVisibility() == View.VISIBLE); // If the single-handed gesture buttons are visible, reposition pointer. if (buttonsVisible) { initializeSingleHandedMode(e); canvas.displayShortToastMessage(R.string.single_reposition); return true; } else return super.onSingleTapConfirmed(e); } /* * (non-Javadoc) * @see com.undatech.opaque.input.InputHandlerDirectSwipePan#onScroll(android.view.MotionEvent, android.view.MotionEvent, float, float) */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // If we are not in a single-handed gesture, simply pass events onto parent. if (!singleHandedGesture) return super.onScroll(e1, e2, distanceX, distanceY); // Otherwise, handle scrolling and zooming here. if (inSwiping) { scrollUp = false; scrollDown = false; scrollLeft = false; scrollRight = false; // Set needed parameters for scroll event to happen in super.super.onTouchEvent. int absX = (int)Math.abs(distanceX); int absY = (int)Math.abs(distanceY); if (absY > absX) { // Scrolling up/down. if (distanceY > 0) scrollDown = true; else scrollUp = true; swipeSpeed = (absY + accumulatedScroll)/15; accumulatedScroll += absY; } else { // Scrolling side to side. if (distanceX > 0) scrollRight = true; else scrollLeft = true; swipeSpeed = (absX + accumulatedScroll)/15; accumulatedScroll += absY; } if (swipeSpeed < 1) { swipeSpeed = 0; } else accumulatedScroll = 0; } else if (inScaling) { float scaleFactor = 1.0f + distanceY*0.01f; if (canvas != null && canvas.canvasZoomer != null) { float zoomFactor = canvas.canvasZoomer.getZoomFactor(); if (needInitPan) { needInitPan = false; canvas.absolutePan((int)(canvas.getAbsX() + (xInitialFocus - canvas.getWidth()/2.f)/zoomFactor), (int)(canvas.getAbsY() + (yInitialFocus - canvas.getHeight()/2.f)/zoomFactor)); } // If the scale factor actually changed, then pan to compensate for zoom. if (canvas.canvasZoomer.changeZoom(scaleFactor)) { canvas.relativePan((int)(distanceY*zoomFactor), (int)(distanceY*zoomFactor)); } } } return true; } }