Back to project page Visu.
The source code is released under:
Apache License
If you think the Android project Visu listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/***************************************************************************************** * DrawHelper.java * * Clase que permite graficar las muestras en pantalla. * ****************************************************************************************/ /*from ww w .j a v a2 s . c om*/ package com.ufavaloro.android.visu.draw; import java.text.DecimalFormat; import com.ufavaloro.android.visu.R; import com.ufavaloro.android.visu.UI.MainActivity; import com.ufavaloro.android.visu.draw.channel.Channel; import com.ufavaloro.android.visu.draw.channel.ChannelList; import com.ufavaloro.android.visu.draw.channel.InfoBox; import com.ufavaloro.android.visu.draw.channel.Label; import com.ufavaloro.android.visu.draw.channel.SignalBox; import com.ufavaloro.android.visu.storage.datatypes.StudyData; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.LightingColorFilter; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Rect; import android.os.Handler; import android.util.AttributeSet; import android.util.SparseArray; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class DrawHelper extends SurfaceView implements SurfaceHolder.Callback { /***************************************************************************************** * Inicio de atributos de clase * *****************************************************************************************/ // Canales private ChannelList mChannelList = new ChannelList(); // Thread de graficaci?n private DrawingThread mDrawingThread; // Pincel private Paint mPaint = new Paint(); // Array de Punteros Touch (dedos apoyados en la pantalla) private SparseArray<TouchPointer> mTouchPointer = new SparseArray<TouchPointer>(); // Alto de la pantalla private int mTotalHeight; // Ancho de la pantalla private int mTotalWidth; // Cantidad de p?ginas del visualizador private int mTotalPages = 4; // Sensibilidad del Zoom en X private double mHorizontalSensitivity = 0.025; // Sensibilidad del Zoom en Y private int mVerticalSensitivity = 3; // Valor anterior de la distancia del Zoom en X private double mOldDx = 0; // Valor anterior del per?metro del Zoom en Y private double mOldDy = 0; // Sensibilidad del desplazamiento de la Se?al private int mPanSensitivity; // Valor anterior en X del desplazamiento anterior private float mOldX = 0; // Bool para reconocer el segundo tapping para pausear private boolean mFirstTap = false; // Se utiliza para calcular el tiempo entre eventos t?ctiles private long mTapTime = 0; // Matriz de ubicaci?n private ReferenceMatrix mReferenceMatrix; private int mPressedChannel; private boolean mFlagUp = false; private boolean mUiVisibility = false; public boolean currentlyRecording; private Label mLabelAwaitingConnections; private boolean mDrawOk = false; public boolean onlineDrawBuffersOk = false; private double mHorizontalZoomThreshold; private double mVerticalZoomThreshold; private double mDxAcum = 0; private double mDyAcum = 0; BitmapManager mBitmapManager; /***************************************************************************************** * Inicio de m?todos de clase * *****************************************************************************************/ /***************************************************************************************** * M?todos principales * *****************************************************************************************/ // Constructor public DrawHelper(Context context, AttributeSet attrs) { // M?todo de superclase super(context, attrs); // Le informamos al Holder que va a recibir llamados de este SurfaceView getHolder().addCallback(this); } // M?todo para inicializar las variables principales private void initialSetup() { // Obtengo ancho y alto de la pantalla mTotalWidth = this.getWidth(); mTotalHeight = this.getHeight(); // Umbral de detecci?n de Zoom mHorizontalZoomThreshold = (float) (mTotalWidth*0.005); mVerticalZoomThreshold = (float) (mTotalHeight*0.001); mHorizontalZoomThreshold = (float) (mTotalWidth*0.005); mVerticalZoomThreshold = (float) (mTotalHeight*0.001); // Genero matriz posicional mReferenceMatrix = new ReferenceMatrix(mTotalHeight, mTotalWidth); mReferenceMatrix.setVerticalDivisor(Channel.getSignalBoxWidthPercent()*mTotalWidth); // Inicializo bitmaps mBitmapManager = new BitmapManager(getContext()); bitmapSetup(); // Inicializo Labels labelSetup(); } // M?todo que configura los Labels private void labelSetup() { // Label de esperando conexi?n mLabelAwaitingConnections = new Label(); mLabelAwaitingConnections.setText("Esperando conexiones entrantes"); int textSize = getBoundedTextSize(mLabelAwaitingConnections , 0.9 * mBitmapManager.getBackgroundLogoWidth() , 0.15 * mBitmapManager.getBackgroundLogoHeight()); mLabelAwaitingConnections.setTextSize(textSize); int widthCorrection = mBitmapManager.getBackgroundLogoWidth() - mLabelAwaitingConnections.getBoundingBox().width(); int heightCorrection = mLabelAwaitingConnections.getBoundingBox().height(); mLabelAwaitingConnections.setX(mBitmapManager.getBackgroundLogoX() + (widthCorrection / 2)); mLabelAwaitingConnections.setY(mBitmapManager.getBackgroundLogoY() + mBitmapManager.getBackgroundLogoHeight() + heightCorrection); } // M?todo que configura los Bitmaps private void bitmapSetup() { mBitmapManager.setIconsWidth((int) (0.07 * mTotalWidth)); mBitmapManager.setIconsHeight((int) (0.11 * mTotalHeight)); mBitmapManager.setIconsLeftPadding((int) (0.05 * mTotalHeight)); mBitmapManager.setIconsUpperPadding((int) (0.1 * mTotalHeight)); mBitmapManager.setup(); // Fondo de pantalla inicial Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_logo); mBitmapManager.setBackgroundLogoWidth((int) (0.5 * mTotalWidth)); mBitmapManager.setBackgroundLogoHeight((int) (0.3 * mTotalHeight)); mBitmapManager.setBackgroundLogo(Bitmap.createScaledBitmap(bitmap , mBitmapManager.getBackgroundLogoWidth() , mBitmapManager.getBackgroundLogoHeight() , false)); mBitmapManager.setBackgroundLogoX((int) ((0.5 * mTotalWidth) / 2)); mBitmapManager.setBackgroundLogoY((int) ((0.7 * mTotalHeight) / 2)); } // M?todo que recibe y almacena muestras public synchronized void draw(short[] samples, int channelNumber) { Channel channel = mChannelList.getChannelAtKey(channelNumber); if(mChannelList.size() == 0 || channel == null || mDrawOk == false) return; if (channel.isPaused() == false) channel.storeSamples(samples); } // M?todo que se llama cuando se dibuja en el SurfaceView @Override protected synchronized void onDraw(Canvas canvas) { // M?todo de superclase super.onDraw(canvas); // Fondo gris canvas.drawColor(Color.LTGRAY); // Dibujo canales drawChannels(canvas); // Dibujo Bitmaps drawBitmaps(canvas); // Dibujo divisiones drawDivisions(canvas); // Dibujo otros labels drawOtherLabels(canvas); } /***************************************************************************************** * M?todos para dibujar en el SurfaceView * *****************************************************************************************/ // M?todo que grafica los canales private synchronized void drawChannels(Canvas canvas) { // Dibujo signal boxes drawSignalBoxes(canvas); // Dibujo info boxes drawInfoBoxes(canvas); } // M?todo que grafica Bitmaps private synchronized void drawBitmaps(Canvas canvas) { ColorFilter filter = new LightingColorFilter(Color.LTGRAY, 1); mPaint.setColorFilter(filter); mPaint.setAlpha(250); // Dibujo ?cono de estudio nuevo if (mUiVisibility == true || mChannelList.size() == 0) { canvas.drawBitmap(mBitmapManager.getNewStudyIcon() , mBitmapManager.getNewStudyIconX() , mBitmapManager.getNewStudyIconY() , mPaint); } // Dibujo ?cono de configurar canales if (mUiVisibility == true && mChannelList.getOnlineChannelsQty() > 0) { canvas.drawBitmap(mBitmapManager.getConfigureChannelsIcon() , mBitmapManager.getConfigureChannelsIconX() , mBitmapManager.getConfigureChannelsIconY() , mPaint); } // Dibujo ?cono de parar estudio if (mUiVisibility == true && mChannelList.size() != 0 && currentlyRecording == true) { canvas.drawBitmap(mBitmapManager.getStopStudyIcon() , mBitmapManager.getStopStudyIconX() , mBitmapManager.getStopStudyIconY() , mPaint); } // Dibujo fondo if (mChannelList.size() == 0) { mPaint.setAlpha(130); canvas.drawBitmap(mBitmapManager.getBackgroundLogo() , mBitmapManager.getBackgroundLogoX() , mBitmapManager.getBackgroundLogoY() , mPaint); mPaint.setAlpha(255); } mPaint.setColorFilter(null); } // M?todo que dibuja el SignalBox private synchronized void drawSignalBoxes(Canvas canvas) { // Dibujo se?al drawSignals(canvas); // Dibujo labels de amplitud drawAmplitudeLabels(canvas); // Dibujo labels de voltage //drawVoltageLabels(canvas); // Dibujo labels de tiempo drawTimeLabels(canvas); } // M?todo que grafica la se?al private synchronized void drawSignals(Canvas canvas) { for (int i = 0; i < mChannelList.size(); i++) { Channel channel = mChannelList.getChannelAtIndex(i); // Obtengo resoluci?n del canal int bits = channel.getStudyData().getAcquisitionData().getBits(); float adcSteps = (float) (Math.pow(2, bits) - 1); float halfAdcSteps = adcSteps / 2; // Obtengo offset del canal float offset = channel.getSignalBox().getMidLine(); // Obtengo color del canal int[] rgb = channel.getColor().getRGB(); setPaint(Color.rgb(rgb[0], rgb[1], rgb[2]), 5); // Obtengo zooms del canal float verticalZoom = channel.getSignalBox().getDrawBuffer().getVerticalZoom(); float horizontalZoom = channel.getSignalBox().getDrawBuffer().getHorizontalZoom(); // Calculo correci?n de zoom horizontal float zoomCorrection = (1 - horizontalZoom) * SignalBox.getWidth(); // Dibujo punto a punto el canal for (int j = 0; j < SignalBox.getWidth() - 1; j++) { // Obtengo muestras int y0Sample = channel.getSignalBox().getDrawBuffer().getSample(j); int yfSample = channel.getSignalBox().getDrawBuffer().getSample(j + 1); // Valor x inicial float x0 = horizontalZoom * (j) + zoomCorrection; // Valor y inicial float y0 = offset - (float) ((verticalZoom * (y0Sample - halfAdcSteps) / halfAdcSteps)); // Valor x final float xf = horizontalZoom * (j + 1) + zoomCorrection; // Valor y final float yf = offset - (float) ((verticalZoom * (yfSample - halfAdcSteps) / halfAdcSteps)); // Dibujo si y solo si el punto est? dentro de los l?mites gr?ficos del signalbox float lowerBound = offset - (InfoBox.getBoxHeight() / 2); float upperBound = offset + (InfoBox.getBoxHeight() / 2) - 1; if ((y0 > lowerBound && y0 < upperBound) && (yf > lowerBound && yf < upperBound)) { canvas.drawPoint(x0, y0, mPaint); } } } } // M?todo para dibujar las amplitudes de la se?al private synchronized void drawAmplitudeLabels(Canvas canvas) { for (int i = 0; i < mChannelList.size(); i++) { Channel channel = mChannelList.getChannelAtIndex(i); float padding = (float) (SignalBox.getWidth() * 0.02); setPaint(Color.GRAY, 1); mPaint.setAlpha(100); Label labelMinAmplitude = channel.getSignalBox().getLabelMinAmplitude(); String minAmplitude = labelMinAmplitude.getText(); float yMinAmplitude = labelMinAmplitude.getY(); float correction = channel.getSignalBox().getAmplitudeCorrection(); mPaint.setTextSize(labelMinAmplitude.getTextSize()); canvas.drawLine(0, yMinAmplitude - correction, padding, yMinAmplitude - correction, mPaint); canvas.drawText(minAmplitude, padding, yMinAmplitude, mPaint); Label labelMaxAmplitude = channel.getSignalBox().getLabelMaxAmplitude(); String maxAmplitude = labelMaxAmplitude.getText(); float yMaxAmplitude = labelMaxAmplitude.getY(); mPaint.setTextSize(labelMaxAmplitude.getTextSize()); canvas.drawLine(0, yMaxAmplitude, padding, yMaxAmplitude, mPaint); canvas.drawText(maxAmplitude, padding, yMaxAmplitude, mPaint); mPaint.setAlpha(255); } } // M?todo para dibujar los valores de voltaje de la se?al private synchronized void drawVoltageLabels(Canvas canvas) { for (int i = 0; i < mChannelList.size(); i++) { SignalBox signalBox = mChannelList.getChannelAtIndex(i).getSignalBox(); float padding = (float) (SignalBox.getWidth() * 0.02); setPaint(Color.GRAY, 1); mPaint.setAlpha(100); Label labelMinVoltage = signalBox.getLabelMinVoltage(); String minVoltage = labelMinVoltage.getText(); float yMinVoltage = labelMinVoltage.getY(); float correction = signalBox.getVoltageCorrection(); mPaint.setTextSize(labelMinVoltage.getTextSize()); canvas.drawLine(0, yMinVoltage - 3, padding, yMinVoltage - 3, mPaint); canvas.drawText(minVoltage, padding, yMinVoltage - 3, mPaint); Label labelMaxVoltage = signalBox.getLabelMaxVoltage(); String maxVoltage = labelMaxVoltage.getText(); float yMaxVoltage = labelMaxVoltage.getY(); mPaint.setTextSize(labelMaxVoltage.getTextSize()); canvas.drawLine(0, yMaxVoltage - correction + 3, padding, yMaxVoltage - correction + 3, mPaint); canvas.drawText(maxVoltage, padding, yMaxVoltage + 3, mPaint); } } // M?todo para dibujar los valores de tiempo de la se?al private synchronized void drawTimeLabels(Canvas canvas) { for (int i = 0; i < mChannelList.size(); i++) { Channel channel = mChannelList.getChannelAtIndex(i); float timePixels = channel.getSignalBox().getLabelTimePixels(); Label labelTime = channel.getSignalBox().getTimeLabel(); String time = labelTime.getText(); float yTime = labelTime.getY(); float xTime = labelTime.getX() - 20; // Barra horizontal de tiempo setPaint(Color.GRAY, 1); mPaint.setAlpha(150); mPaint.setTextSize(labelTime.getTextSize()); canvas.drawLine(xTime, yTime, xTime + timePixels, yTime, mPaint); // Label que muestra el tiempo float labelTimeWidth = labelTime.getBoundingBox().width(); float labelTimeHeigth = labelTime.getBoundingBox().height(); canvas.drawText(time, (float) (xTime - (labelTimeWidth * 0.5) + (timePixels * 0.5)), (float) (yTime - (labelTimeHeigth * 0.25)), mPaint); // Barritas verticales de los costados canvas.drawLine(xTime, yTime - 5, xTime, yTime + 5, mPaint); canvas.drawLine(xTime + timePixels, yTime - 5, xTime + timePixels, yTime + 5, mPaint); } } // M?todo que dibuja todas las Figuras en el SurfaceView private synchronized void drawInfoBoxes(Canvas canvas) { for (int i = 0; i < mChannelList.size(); i++) { // Obtengo Channel Channel channel = mChannelList.getChannelAtIndex(i); Label label; // Obtengo color del canal int[] rgb = channel.getColor().getRGB(); setPaint(Color.rgb(rgb[0], rgb[1], rgb[2]), 2); mPaint.setAlpha(200); // Dibujo Label de n?mero de Canal label = channel.getInfoBox().getLabelChannel(); mPaint.setTextSize(label.getTextSize()); canvas.drawText(label.getText(), label.getX(), label.getY(), mPaint); // Dibujo label de Fs label = channel.getInfoBox().getPatientLabel(); mPaint.setTextSize(label.getTextSize()); canvas.drawText(label.getText(), label.getX(), label.getY(), mPaint); /* Dibujo Label de Pausa setPaint(Color.RED, 2); if (channel.getInfoBox().getPaused() == true) { label = infoBox.getLabelPaused(); mPaint.setTextSize(label.getTextSize()); canvas.drawText(label.getText(), label.getX(), label.getY(), mPaint); } */ } mPaint.setAlpha(255); } // M?todo para dibujar las divisiones entre canales private synchronized void drawDivisions(Canvas canvas) { setPaint(Color.GRAY, 3); mPaint.setAlpha(130); ColorFilter filter = new LightingColorFilter(Color.LTGRAY, 1); mPaint.setColorFilter(filter); for (int i = 0; i < mChannelList.size(); i++) { canvas.drawLine(0, i*Channel.getHeight(), mTotalWidth, i*Channel.getHeight(), mPaint); } if (mChannelList.size() > 0) { canvas.drawLine(SignalBox.getWidth(), 0, SignalBox.getWidth(), mTotalHeight, mPaint); } mPaint.setAlpha(255); mPaint.setColorFilter(null); } // Dibujo otros labels private synchronized void drawOtherLabels(Canvas canvas) { // Label de "Esperando conexiones entrantes" if(mChannelList.size() == 0) { mPaint.setTextSize(mLabelAwaitingConnections.getTextSize()); canvas.drawText(mLabelAwaitingConnections.getText() , mLabelAwaitingConnections.getX() , mLabelAwaitingConnections.getY() , mPaint); } // Label de los canales ocultados if(mChannelList.getHiddenChannelsLabels().size() > 0 && mUiVisibility == true || mChannelList.size() == 0) { for(int i = 0; i < mChannelList.getHiddenChannelsLabels().size(); i++) { int channelKey = mChannelList.getHiddenChannelsLabels().keyAt(i); Label label = mChannelList.getHiddenChannelsLabels().get(channelKey); label.setTextSize(getBoundedTextSize(label, mBitmapManager.getIconsWidth(), mBitmapManager.getIconsHeight())); label.setX((int) ((0.05 * mTotalHeight) + (i*mBitmapManager.getIconsWidth()))); label.setY(mTotalHeight - mBitmapManager.getIconsHeight()); Channel deletedChannel = mChannelList.getHiddenChannels().get(channelKey); int[] rgb = deletedChannel.getColor().getRGB(); setPaint(Color.rgb(rgb[0], rgb[1], rgb[2]), 5); mPaint.setAlpha(100); canvas.drawText(label.getText(), label.getX(), label.getY(), mPaint); } } } // M?todo que configura el color y grosor del brush private synchronized void setPaint(int color, float strokeWidth) { mPaint.setColor(color); mPaint.setAntiAlias(true); mPaint.setStyle(Style.FILL); mPaint.setStrokeWidth(strokeWidth); } /***************************************************************************************** * M?todos para manejar los canales y sus caracter?sticas * *****************************************************************************************/ /************************************************************************************* * Agregar/eliminar canales * *************************************************************************************/ // M?todo para agregar un canal online public synchronized void addChannel(StudyData studyData, boolean online) { if(online) { mChannelList.addChannel(mTotalHeight, mTotalWidth, mTotalPages, studyData); } else { mChannelList.addChannel(mTotalHeight, mTotalWidth, studyData); } mReferenceMatrix.addChannel(); mPanSensitivity = (int) (SignalBox.getWidth() * 0.012); } public synchronized void hideChannel(int channelIndex) { mChannelList.hideChannel(channelIndex); mReferenceMatrix.removeChannel(); } public synchronized void removeChannel(int channelIndex) { mChannelList.removeChannel(channelIndex); mReferenceMatrix.removeChannel(); } /************************************************************************************* * Men? de usuario * *************************************************************************************/ // Men? con las opciones del canal private void channelMenu(int channelNumber) { ((MainActivity) getContext()).channelOptionsDialog(channelNumber); } /***************************************************************************************** * M?todos para el manejo de eventos t?ctiles * *****************************************************************************************/ /************************************************************************************* * Listener principal * *************************************************************************************/ // M?todo que responde a los eventos t?ctiles @Override public boolean onTouchEvent(MotionEvent event) { int touchPointerIndex = event.getActionIndex(); int touchPointerId = event.getPointerId(touchPointerIndex); switch (event.getAction() & MotionEvent.ACTION_MASK) { // Puntero apoyado case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: TouchPointer touchPointer = new TouchPointer(); touchPointer.x = event.getX(touchPointerIndex); touchPointer.x0 = touchPointer.x; touchPointer.y = event.getY(touchPointerIndex); touchPointer.y0 = touchPointer.y; mTouchPointer.put(touchPointerId, touchPointer); onTouch_PauseChannel(); onTouch_NewStudyIcon(); onTouch_ConfigureChannelsIcon(); onTouch_StopStudyIcon(); onTouch_HiddenChannelLabel(); mLongPressHandler.postDelayed(longPressed, 1000); break; // Puntero levantado case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mTouchPointer.remove(touchPointerId); mFlagUp = true; mLongPressHandler.removeCallbacks(longPressed); break; // Puntero en movimiento case MotionEvent.ACTION_MOVE: for (int i = 0; i < event.getPointerCount(); i++) { TouchPointer tp2 = mTouchPointer.get(event.getPointerId(i)); if (tp2 != null) { tp2.x = event.getX(i); tp2.y = event.getY(i); } } onTouch_Pan(); onTouch_HorizontalZoom(); onTouch_VerticalZoom(); break; } return true; } // Deleted Channel Labels private void onTouch_HiddenChannelLabel() { if (mUiVisibility == true || mChannelList.size() == 0) { TouchPointer tp = mTouchPointer.valueAt(0); for(int i = 0; i < mChannelList.getHiddenChannelsLabels().size(); i++) { Label label = mChannelList.getHiddenChannelsLabels().valueAt(i); int width = label.getBoundingBox().width(); int height = label.getBoundingBox().height(); if (tp.x > label.getX() && tp.x < label.getX() + width) { if (tp.y < label.getY() && tp.y > label.getY() - height) { mChannelList.restoreChannel(mChannelList.getHiddenChannels().keyAt(i)); mReferenceMatrix.addChannel(); } } } } } // Bot?n de nuevo estudio private void onTouch_NewStudyIcon() { if (mUiVisibility == true || mChannelList.size() == 0) { TouchPointer tp = mTouchPointer.valueAt(0); int width = mBitmapManager.getNewStudyIcon().getWidth(); int height = mBitmapManager.getNewStudyIcon().getHeight(); if (tp.x > mBitmapManager.getNewStudyIconX() && tp.x < mBitmapManager.getNewStudyIconX() + width) { if (tp.y > mBitmapManager.getNewStudyIconY() && tp.y < mBitmapManager.getNewStudyIconY() + height) { ((MainActivity) getContext()).mainMenuDialog(); } } } } // Bot?n de configurar canales private void onTouch_ConfigureChannelsIcon() { if (mUiVisibility == true && mChannelList.getOnlineChannelsQty() > 0) { TouchPointer tp = mTouchPointer.valueAt(0); int width = mBitmapManager.getConfigureChannelsIcon().getWidth(); int height = mBitmapManager.getConfigureChannelsIcon().getHeight(); if (tp.x > mBitmapManager.getConfigureChannelsIconX() && tp.x < mBitmapManager.getConfigureChannelsIconX() + width) { if (tp.y > mBitmapManager.getConfigureChannelsIconY() && tp.y < mBitmapManager.getConfigureChannelsIconY() + height) { ((MainActivity) getContext()).onlineChannelPropertiesDialog(-1); } } } } // Bot?n de parar estudio private void onTouch_StopStudyIcon() { if (mUiVisibility == true && mChannelList.size() != 0 && currentlyRecording == true) { TouchPointer tp = mTouchPointer.valueAt(0); int width = mBitmapManager.getStopStudyIcon().getWidth(); int height = mBitmapManager.getStopStudyIcon().getHeight(); if (tp.x > mBitmapManager.getStopStudyIconX() && tp.x < mBitmapManager.getStopStudyIconX() + width) { if (tp.y > mBitmapManager.getStopStudyIconY() && tp.y < mBitmapManager.getStopStudyIconY() + height) { ((MainActivity) getContext()).stopStudyDialog(); } } } } // Qu? hago cuando el evento es Zoom en X? private void onTouch_HorizontalZoom() { if (mChannelList.size() == 0 || mTouchPointer.size() != 2) return; // Calculo distancia entre los dedos TouchPointer tp1 = mTouchPointer.valueAt(0); TouchPointer tp2 = mTouchPointer.valueAt(1); double newDx = Math.abs(tp1.x - tp2.x); int channelNumber = mReferenceMatrix.getChannel(tp1.y0, tp1.x0) - 1; if (channelNumber >= 0) { Channel channel = mChannelList.getChannelAtIndex(channelNumber); float oldZoomValue = 1; float newZoomValue = 1; // Si la distancia aumenta => Zoom In if (newDx > mOldDx) { mDxAcum = (newDx-mOldDx) + mDxAcum; if(mDxAcum > mHorizontalZoomThreshold) { oldZoomValue = channel.getHorizontalZoom(); newZoomValue = (float) (oldZoomValue + mHorizontalSensitivity); channel.setHorizontalZoom(newZoomValue); mDxAcum = 0; } } // Si la distancia disminuye => Zoom Out if (newDx < mOldDx) { mDxAcum = (newDx-mOldDx) + mDxAcum; if(mDxAcum < -mHorizontalZoomThreshold) { oldZoomValue = channel.getHorizontalZoom(); if (oldZoomValue >= 1 + mHorizontalSensitivity) { newZoomValue = (float) (oldZoomValue - mHorizontalSensitivity); channel.setHorizontalZoom(newZoomValue); } mDxAcum = 0; } } // Renuevo el valor de la distancia mOldDx = newDx; } } // Qu? hago cuando el evento es Zoom en Y ? private void onTouch_VerticalZoom() { if (mChannelList.size() == 0 || mTouchPointer.size() != 2) return; // Obtengo las coordenadas de los tres dedos TouchPointer tp1 = mTouchPointer.valueAt(0); TouchPointer tp2 = mTouchPointer.valueAt(1); double newDy = Math.abs(tp1.y - tp2.y); int channelNumber = mReferenceMatrix.getChannel(tp1.y0, tp1.x0) - 1; if (channelNumber >= 0) { Channel channel = mChannelList.getChannelAtIndex(channelNumber); float oldZoomValue = 1; float newZoomValue = 1; // Si aumenta el per?metro => Zoom Out if (newDy > mOldDy) { mDyAcum = (newDy-mOldDy) + mDyAcum; if(mDyAcum > mVerticalZoomThreshold) { if (channel.getVerticalZoom() < Channel.getHeight()/2 - mVerticalSensitivity) { oldZoomValue = channel.getVerticalZoom(); newZoomValue = (float) (oldZoomValue + mVerticalSensitivity); channel.setVerticalZoom(newZoomValue); } mDyAcum = 0; } } // Si disminuye el per?metro => Zoom In if (newDy < mOldDy) { mDyAcum = (newDy-mOldDy) + mDyAcum; if(mDyAcum < -mVerticalZoomThreshold) { if (channel.getVerticalZoom() > mVerticalSensitivity) { oldZoomValue = channel.getVerticalZoom(); newZoomValue = (float) (oldZoomValue - mVerticalSensitivity); channel.setVerticalZoom(newZoomValue); } mDyAcum = 0; } } // Renuevo el valor del per?metro mOldDy = newDy; } } // Qu? hago cuando el evento es desplazar la Se?al? private void onTouch_Pan() { if (mChannelList.size() == 0) return; if (mTouchPointer.size() == 1) { Channel channel; TouchPointer tp = mTouchPointer.valueAt(0); int channelNumber = mReferenceMatrix.getChannel(tp.y0, tp.x0) - 1; if (channelNumber >= 0) { channel = mChannelList.getChannelAtIndex(channelNumber); if (channel.isPaused() == true || !channel.isOnline()) { // Si muevo el dedo hacia la derecha... if (tp.x > mOldX) { channel.getSignalBox().panRight(mPanSensitivity); } // Si muevo el dedo hacia la izquierda... if (tp.x < mOldX) { channel.getSignalBox().panLeft(mPanSensitivity); } mOldX = (float) tp.x; } } } } // Qu? hago cuando el evento es un Double Tap? private void onTouch_PauseChannel() { if (mChannelList.size() == 0) return; TouchPointer tp = mTouchPointer.valueAt(0); int totalPointers = mTouchPointer.size(); long time = System.currentTimeMillis(); int channelNumber = mReferenceMatrix.getChannel(tp.y0, tp.x0) - 1; long deltaTime = time - mTapTime; // Si no es el primer tap, el tiempo entre este tap y el anterior es < a // 300 mS, hay un solo dedo apoyado y este fue apoyado en la zona de // visualizacion if (mFirstTap == true && deltaTime <= 300 && tp.x < SignalBox.getWidth()) { if (totalPointers == 1 && channelNumber == mPressedChannel && channelNumber >= 0 && mFlagUp == true) { // Flipeo el bool de pausa Channel channel = mChannelList.getChannelAtIndex(channelNumber); boolean oldPausedValue = channel.isPaused(); boolean newPausedValue = !oldPausedValue; channel.setPaused(newPausedValue); // Si es el caso que estoy des-pauseando, igualo los ?ndices del Buffer. // Esto hace que se resuma la graficaci?n desde la posici?n de la ?ltima // muestra registrada. if (channel.isPaused() == false) channel.getSignalBox().resetGraphingIndex(); // Vuelvo a poner en false el bool de Primer Tap mFirstTap = false; mFlagUp = false; mTapTime = 0; } // Si es el primer tap } else if (tp.x < SignalBox.getWidth()) { if (channelNumber >= 0) { mPressedChannel = channelNumber; // Pongo en true el bool de Primer Tap mFirstTap = true; // Obtengo el tiempo actual para restarle al tiempo del segundo tap y // chequear que no haya m?s de 300 mS entre Taps mTapTime = time; } } } // Qu? hago cuando el evento es un Long Press sobre un InfoBox? final Handler mLongPressHandler = new Handler(); Runnable longPressed = new Runnable() { public void run() { if (mChannelList.size() < 0) return; final TouchPointer tp = mTouchPointer.valueAt(0); final int channelNumber = -mReferenceMatrix.getChannel(tp.y0, tp.x0) - 1; int isInfoBox = mReferenceMatrix.getChannel(tp.y0, tp.x0); if (isInfoBox < 0) { channelMenu(channelNumber); } } }; /***************************************************************************************** * Thread de graficaci?n y m?todos afines * *****************************************************************************************/ // Thread de graficaci?n (inner class) private class DrawingThread extends Thread { // Objeto que "une" el Bitmap (Canvas) con el SurfaceView private SurfaceHolder mSurfaceHolder; // Bitmap sobre el cual dibujo private Canvas mCanvas; // Candado que traba el thread private Object mPauseLock; // Flag de pausa private boolean mPaused; // Flag de run private boolean mRun; // Tiempo de espera entre ciclos de graficaci?n private long mSleep; // Constructor public DrawingThread(SurfaceHolder mSurfaceHolder, DrawHelper mPlotSurfaceView) { this.mSurfaceHolder = mSurfaceHolder; mRun = false; mPauseLock = new Object(); mPaused = false; mSleep = 0; } // Thread.run() @SuppressLint("WrongCall") public void run() { this.setPriority(MAX_PRIORITY); while (mRun) { mCanvas = null; // Dibujo muestra try { // Lockeo el canvas para poder dibujar mCanvas = mSurfaceHolder.lockCanvas(); // Si el locking fue exitoso, obtuve un objeto de tipo // Canvas if (mCanvas != null) { // Si no hay otro onDraw dibujando sobre el Canvas synchronized (mSurfaceHolder) { // Dibujo onDraw(mCanvas); } } // Termin? de dibujar } finally { // Unlockeo el Canvas if (mCanvas != null) mSurfaceHolder.unlockCanvasAndPost(mCanvas); } // Candado de pausa // Deja el Thread en espera utilizando wait() hasta que mPaused // == false synchronized (mPauseLock) { while (mPaused) { try { mPauseLock.wait(); } catch (InterruptedException e) { } } } try { Thread.sleep(mSleep); } catch (InterruptedException e1) { e1.printStackTrace(); } }// while(mRun) }// run() // Pauseo el Thread public void onPause() { synchronized (mPauseLock) { mPaused = true; } } // Resumo el Thread public void onResume() { synchronized (mPauseLock) { mPaused = false; mPauseLock.notifyAll(); } } // Setter de mRun public void setRunning(boolean mRun) { this.mRun = mRun; } }//DrawingThread // M?todo para empezar a graficar private void startDrawingThread() { mDrawingThread = new DrawingThread(getHolder(), this); mDrawingThread.setRunning(true); mDrawingThread.start(); } // M?todo para parar la graficaci?n private void stopDrawingThread() { boolean retry = true; mDrawingThread.setRunning(false); while (retry) { try { mDrawingThread.join(); retry = false; } catch (InterruptedException e) { } } } /***************************************************************************************** * Otros m?todos * *****************************************************************************************/ // M?todo para obtener el tama?o de texto apropiado para los labels del // InfoBox private int getBoundedTextSize(Label label, double boxWidth, double boxHeight) { Rect rect = new Rect(); int i = 0; while (true) { mPaint.setTextSize(i); mPaint.getTextBounds(label.getText(), 0, label.getText().length(), rect); double width = rect.width(); double height = rect.height(); if (width > boxWidth || height > boxHeight) { break; } i++; } return i; } // M?todo para saber si el Status Bar y Action Bar est?n visibles public void setUiVisibility(boolean mUiVisibility) { this.mUiVisibility = mUiVisibility; } public void startDrawing() { mDrawOk = true; } public void stopDrawing() { mDrawOk = false; } /***************************************************************************************** * M?todos de Ciclo de Vida * *****************************************************************************************/ // M?todo que se llama cuando se crea el SurfaceView @Override public void surfaceCreated(SurfaceHolder arg0) { // Inicializo variables initialSetup(); // Inicializo thread de graficaci?n startDrawingThread(); // Todo OK. Instancio mSurfaceViewVisualizador en Visualizador.java ((MainActivity) getContext()).setupAfterSurfaceCreated(); } // M?todo que se llama cuando el SurfaceView sufre alg?n cambio @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } // M?todo que se llama cuando se destruye el SurfaceView @Override public void surfaceDestroyed(SurfaceHolder arg0) { mDrawingThread.setRunning(false); stopDrawingThread(); } public ChannelList getChannels() { return mChannelList; } }// DrawingSurface