diff --git a/OsmAnd/jni/osmand/common.cpp b/OsmAnd/jni/osmand/common.cpp index f3b85a7da7..661109e2f9 100644 --- a/OsmAnd/jni/osmand/common.cpp +++ b/OsmAnd/jni/osmand/common.cpp @@ -122,7 +122,6 @@ std::string getString(jstring st) { const char* utf = globalEnv()->GetStringUTFChars(st, NULL); std::string res(utf); globalEnv()->ReleaseStringUTFChars(st, utf); - globalEnv()->DeleteLocalRef(st); return res; } diff --git a/OsmAnd/libs/armeabi/libosmand.so b/OsmAnd/libs/armeabi/libosmand.so index 55c3a3884c..493455f742 100755 Binary files a/OsmAnd/libs/armeabi/libosmand.so and b/OsmAnd/libs/armeabi/libosmand.so differ diff --git a/OsmAnd/res/drawable-hdpi/back_to_loc_disabled.png b/OsmAnd/res/drawable-hdpi/back_to_loc_disabled.png new file mode 100644 index 0000000000..14d3f2d9a7 Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/back_to_loc_disabled.png differ diff --git a/OsmAnd/res/drawable-hdpi/back_to_loc_normal.png b/OsmAnd/res/drawable-hdpi/back_to_loc_normal.png new file mode 100644 index 0000000000..8dcee1289c Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/back_to_loc_normal.png differ diff --git a/OsmAnd/res/drawable-hdpi/back_to_loc_pressed.png b/OsmAnd/res/drawable-hdpi/back_to_loc_pressed.png new file mode 100644 index 0000000000..b1d0ac7edd Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/back_to_loc_pressed.png differ diff --git a/OsmAnd/res/drawable-hdpi/globus_normal.png b/OsmAnd/res/drawable-hdpi/globus_normal.png new file mode 100644 index 0000000000..d2f2cd00ae Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/globus_normal.png differ diff --git a/OsmAnd/res/drawable-hdpi/globus_pressed.png b/OsmAnd/res/drawable-hdpi/globus_pressed.png new file mode 100644 index 0000000000..96b114fc02 Binary files /dev/null and b/OsmAnd/res/drawable-hdpi/globus_pressed.png differ diff --git a/OsmAnd/res/drawable/back_to_loc.xml b/OsmAnd/res/drawable/back_to_loc.xml new file mode 100644 index 0000000000..5bccca150f --- /dev/null +++ b/OsmAnd/res/drawable/back_to_loc.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/OsmAnd/res/drawable/back_to_loc_disabled.png b/OsmAnd/res/drawable/back_to_loc_disabled.png new file mode 100644 index 0000000000..8c54b0cac4 Binary files /dev/null and b/OsmAnd/res/drawable/back_to_loc_disabled.png differ diff --git a/OsmAnd/res/drawable/back_to_loc_normal.png b/OsmAnd/res/drawable/back_to_loc_normal.png new file mode 100644 index 0000000000..ee1efd4555 Binary files /dev/null and b/OsmAnd/res/drawable/back_to_loc_normal.png differ diff --git a/OsmAnd/res/drawable/back_to_loc_pressed.png b/OsmAnd/res/drawable/back_to_loc_pressed.png new file mode 100644 index 0000000000..5c0b100dc0 Binary files /dev/null and b/OsmAnd/res/drawable/back_to_loc_pressed.png differ diff --git a/OsmAnd/res/drawable/globus.xml b/OsmAnd/res/drawable/globus.xml new file mode 100644 index 0000000000..ea615c7ec7 --- /dev/null +++ b/OsmAnd/res/drawable/globus.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/OsmAnd/res/drawable/globus_normal.png b/OsmAnd/res/drawable/globus_normal.png new file mode 100644 index 0000000000..84ed4e4720 Binary files /dev/null and b/OsmAnd/res/drawable/globus_normal.png differ diff --git a/OsmAnd/res/drawable/globus_pressed.png b/OsmAnd/res/drawable/globus_pressed.png new file mode 100644 index 0000000000..f95f7de330 Binary files /dev/null and b/OsmAnd/res/drawable/globus_pressed.png differ diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 0cee0ef213..9c420ae3f8 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -611,7 +611,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso } } - protected void backToLocationImpl() { + public void backToLocationImpl() { backToLocation.setVisibility(View.INVISIBLE); PointLocationLayer locationLayer = mapLayers.getLocationLayer(); if(!isMapLinkedToLocation()){ diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 28f96bf4c7..f07b065994 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -132,16 +132,15 @@ public class MapActivityLayers { // 7. point navigation layer navigationLayer = new PointNavigationLayer(); mapView.addLayer(navigationLayer, 7); - // 8. map info layer - mapInfoLayer = new MapInfoLayer(activity, routeLayer); - mapView.addLayer(mapInfoLayer, 8); - // 9. context menu layer + // 8. context menu layer contextMenuLayer = new ContextMenuLayer(activity); - mapView.addLayer(contextMenuLayer, 9); + mapView.addLayer(contextMenuLayer, 8); + // 9. map info layer + mapInfoLayer = new MapInfoLayer(activity, routeLayer); + mapView.addLayer(mapInfoLayer, 9); // 10. route info layer routeInfoLayer = new RouteInfoLayer(routingHelper, (LinearLayout) activity.findViewById(R.id.RouteLayout)); mapView.addLayer(routeInfoLayer, 10); - // 11. route info layer mapControlsLayer = new MapControlsLayer(activity); mapView.addLayer(mapControlsLayer, 11); diff --git a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java index 5dc436fc08..bf6777b4ac 100644 --- a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java @@ -545,6 +545,10 @@ public class MapRenderRepositories { renderer.generateNewBitmap(currentRenderingContext, cObjects, bmp, prefs.USE_ENGLISH_NAMES.get(), renderingReq, notifyList, fillColor); } + // Force to use rendering request in order to prevent Garbage Collector when it is used in C++ + if(renderingReq != null){ + System.out.println("Debug :" + renderingReq != null); + } String renderingDebugInfo = currentRenderingContext.renderingDebugInfo; currentRenderingContext.ended = true; if (checkWhetherInterrupted()) { diff --git a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java index 73387dfaf8..b395e97bd4 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java @@ -12,8 +12,6 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.routing.RoutingHelper.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper.TurnType; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; @@ -36,9 +34,10 @@ import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; import android.view.WindowManager; -import android.widget.FrameLayout; -import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.LinearLayout.LayoutParams; public class MapInfoLayer extends OsmandMapLayer { @@ -78,14 +77,8 @@ public class MapInfoLayer extends OsmandMapLayer { private DisplayMetrics dm; private float scaleCoefficient; - private Bitmap compass; private Paint paintImg; - private final static int[] pressedState = new int[]{android.R.attr.state_pressed}; - private final static int[] simpleState = new int[]{}; - - - private TextInfoControl distanceControl; private TextInfoControl speedControl; private TextInfoControl leftTimeControl; @@ -184,7 +177,6 @@ public class MapInfoLayer extends OsmandMapLayer { pathTransform.postScale(scaleCoefficient, scaleCoefficient); pathTransform.postTranslate(boundsForMiniRoute.left, boundsForMiniRoute.top); - compass = BitmapFactory.decodeResource(view.getResources(), R.drawable.compass); LEFT_MARGIN_X = (int) (LEFT_MARGIN_X * scaleCoefficient); STATUS_BAR_MARGIN_X = (int) (STATUS_BAR_MARGIN_X * scaleCoefficient); @@ -193,27 +185,22 @@ public class MapInfoLayer extends OsmandMapLayer { LEFT_MARGIN_Y = statusBar.getMeasuredHeight() ; Drawable time = view.getResources().getDrawable(R.drawable.info_time); - speedControl = new TextInfoControl(R.drawable.box_top, null, time.getMinimumWidth(), paintText, paintSubText); - leftTimeControl = new TextInfoControl(R.drawable.box_top, null, time.getMinimumWidth(), paintText, paintSubText) { + speedControl = new TextInfoControl(R.drawable.box_top, null, 0, paintText, paintSubText); + leftTimeControl = new TextInfoControl(R.drawable.box_top, time, 0, paintText, paintSubText); + leftTimeControl.setOnClickListener(new View.OnClickListener() { + @Override - public boolean isClickable() { - return true; - } - @Override - public void click() { + public void onClick(View v) { showArrivalTime = !showArrivalTime; view.getSettings().SHOW_ARRIVAL_TIME_OTHERWISE_EXPECTED_TIME.set(showArrivalTime); view.refreshMap(); } - }; + }); distanceControl = new TextInfoControl(R.drawable.box_top, view.getResources().getDrawable(R.drawable.info_target), 0, - paintText, paintSubText) { + paintText, paintSubText); + distanceControl.setOnClickListener(new View.OnClickListener() { @Override - public boolean isClickable() { - return true; - } - @Override - public void click() { + public void onClick(View v) { AnimateDraggingMapThread thread = view.getAnimatedDraggingThread(); LatLon pointToNavigate = view.getSettings().getPointToNavigate(); if(pointToNavigate != null){ @@ -222,7 +209,7 @@ public class MapInfoLayer extends OsmandMapLayer { fZoom, true); } } - }; + }); leftControls.add(distanceControl); leftControls.add(speedControl); leftControls.add(leftTimeControl); @@ -239,14 +226,17 @@ public class MapInfoLayer extends OsmandMapLayer { public void relayoutLeftControls(MapInfoControl... cs){ for(MapInfoControl c : cs) { - c.prefferedLayout(); + c.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); } int w = 0; for(MapInfoControl c : leftControls) { w = Math.max(w, c.getMeasuredWidth()); } + int x = LEFT_MARGIN_X; + int y = LEFT_MARGIN_Y; for(MapInfoControl c : leftControls) { - c.layout(w, c.getHeight()); + c.layout(x, y, x + w, y + c.getMeasuredHeight()); + y += c.getMeasuredHeight(); } } @@ -303,20 +293,13 @@ public class MapInfoLayer extends OsmandMapLayer { drawRouteInfo(canvas); // draw left controls - int h = 0; - for(int i=0; i= 0; i--) { - h -= leftControls.get(i).getHeight(); - canvas.save(); - canvas.translate(LEFT_MARGIN_X, h); - if(leftControls.get(i).isVisible()) { + if(leftControls.get(i).getMeasuredHeight() > 0) { leftControls.get(i).onDraw(canvas); } - canvas.restore(); } + + // draw status bar if(statusBar.getRight() == 0) { Rect statusBarPadding = new Rect(); statusBarBackground.getPadding(statusBarPadding); @@ -441,30 +424,39 @@ public class MapInfoLayer extends OsmandMapLayer { return true; } + private View pressedView = null; + @Override public boolean onTouchEvent(MotionEvent event) { - int x = (int)event.getX(); - int y = (int)event.getY(); + int x = (int) event.getX(); + int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_DOWN) { - MapInfoControl control = detectLeftControl(x, y); - if (control != null && control.isClickable()) { - control.setPressed(true); - view.refreshMap(); - } - } - if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { - MapInfoControl control = detectLeftControl(x, y); - for(MapInfoControl c : leftControls){ - if(c.isPressed()) { - if(control == c) { - c.click(); + pressedView = null; + ArrayList touchables = statusBar.getTouchables(); + touchables.addAll(leftControls); + for (View v : touchables) { + if (v.getMeasuredHeight() > 0 && v.isClickable()) { + if (v.getLeft() <= x && x <= v.getRight() && v.getTop() <= y && y <= v.getBottom()) { + pressedView = v; + break; } - c.setPressed(false); } + } + if (pressedView != null) { + pressedView.setPressed(true); view.refreshMap(); } + return pressedView != null; } - return false; + boolean pressed = pressedView != null; + if (pressed && (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)) { + pressedView.setPressed(false); + if (pressedView.getLeft() <= x && x <= pressedView.getRight() && pressedView.getTop() <= y && y <= pressedView.getBottom()) { + pressedView.performClick(); + } + view.refreshMap(); + } + return pressed; } @@ -477,46 +469,25 @@ public class MapInfoLayer extends OsmandMapLayer { return true; } } - MapInfoControl control = detectLeftControl((int)point.x, (int)point.y); - if (control != null && control.isClickable()) { - control.click(); - return true; - } return false; } - private MapInfoControl detectLeftControl(int x, int y) { - x -= LEFT_MARGIN_X; - y -= LEFT_MARGIN_Y; - if (y >= 0 && x >= 0) { - for (int i = 0; i < leftControls.size(); i++) { - if (leftControls.get(i).isVisible()) { - y -= leftControls.get(i).getHeight(); - if (y <= 0) { - if (x <= leftControls.get(i).getWidth()) { - return leftControls.get(i); - } else { - return null; - } - } - } - } - } - return null; - } private ViewGroup createStatusBar() { - final int mw = (int) compass.getWidth() ; - final int mh = (int) compass.getHeight() ; - FrameLayout statusBar = new FrameLayout(view.getContext()); - LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, - Gravity.LEFT | Gravity.TOP); + final Drawable compass = view.getResources().getDrawable(R.drawable.compass); + final int mw = (int) compass.getMinimumWidth() ; + final int mh = (int) compass.getMinimumHeight() ; + LinearLayout statusBar = new LinearLayout(view.getContext()); + statusBar.setOrientation(LinearLayout.HORIZONTAL); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + params.leftMargin = (int) (5 * scaleCoefficient); ImageView compassView = new ImageView(view.getContext()) { @Override protected void onDraw(Canvas canvas) { canvas.save(); - canvas.rotate(view.getRotate(), getLeft() + mw / 2, getTop() + mh / 2); - canvas.drawBitmap(compass, getLeft(), getTop(), paintImg); + canvas.translate(getLeft(), getTop()); + canvas.rotate(view.getRotate(), mw / 2, mh / 2); + compass.draw(canvas); canvas.restore(); } }; @@ -526,82 +497,78 @@ public class MapInfoLayer extends OsmandMapLayer { map.switchRotateMapMode(); } }); + compassView.setImageDrawable(compass); statusBar.addView(compassView, params); - compassView.setImageBitmap(compass); + + // Space + params = new LinearLayout.LayoutParams(0, 0, 1); + TextView space = new TextView(view.getContext()); + statusBar.addView(space, params); + statusBar.setWeightSum(1); + + + params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + ImageView globus = new ImageView(view.getContext()); + globus.setImageDrawable(view.getResources().getDrawable(R.drawable.globus)); + globus.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // TODO show map dialog + } + }); + statusBar.addView(globus, params); + + params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + ImageView backToLocation = new ImageView(view.getContext()); + backToLocation.setImageDrawable(view.getResources().getDrawable(R.drawable.back_to_loc)); + backToLocation.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + map.backToLocationImpl(); + } + }); + statusBar.addView(backToLocation, params); statusBar.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); return statusBar; } - public abstract class MapInfoControl { + public abstract class MapInfoControl extends View { int width = 0; int height = 0; boolean pressed = false; Drawable background; public MapInfoControl(int background){ + super(view.getContext()); + this.background = view.getResources().getDrawable(background).mutate(); } - public boolean isClickable(){ - return false; - } - - public boolean isVisible() { - return true; - } - - public void click() { - } - - public boolean isPressed() { - return pressed; - } - + @Override public void setPressed(boolean pressed) { - if(this.pressed != pressed) { - this.pressed = pressed; - if(pressed) { - background.setState(pressedState); - } else { - background.setState(simpleState); - } - Rect padding = new Rect(); - if(background.getPadding(padding)) { - background.setBounds(-padding.left, -padding.top, - width + padding.right, height + padding.bottom); - } - } - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return isVisible() ? height : 0; - } - - public void prefferedLayout(){ - layout(getMeasuredWidth(), getMeasuredHeight()); - } - - public void layout(int w, int h) { - this.width = w; - this.height = h; + super.setPressed(pressed); + background.setState(getDrawableState()); Rect padding = new Rect(); - if(background.getPadding(padding)) { - background.setBounds(-padding.left, -padding.top, - w + padding.right, h + padding.bottom); + if (background.getPadding(padding)) { + background.setBounds(-padding.left + getLeft(), getTop() + -padding.top, getRight() + padding.right, getBottom() + padding.bottom); } } - public abstract int getMeasuredWidth(); + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + Rect padding = new Rect(); + if (background.getPadding(padding)) { + background.setBounds(-padding.left + left, top + -padding.top, right + padding.right, bottom + padding.bottom); + } + } - public abstract int getMeasuredHeight(); - - void onDraw(Canvas cv) { + @Override + protected void onDraw(Canvas cv) { background.draw(cv); } } @@ -612,7 +579,6 @@ public class MapInfoLayer extends OsmandMapLayer { Paint textPaint; String subtext; Paint subtextPaint; - int cacheMeasuredWidth = -1; int leftMargin = 0; private Drawable imageDrawable; @@ -621,42 +587,54 @@ public class MapInfoLayer extends OsmandMapLayer { super(background); this.leftMargin = leftMargin; this.imageDrawable = drawable; - if(imageDrawable != null) { - // Unknown reason to add 3*scaleCoefficient - imageDrawable.setBounds(0, (int) (3*scaleCoefficient), imageDrawable.getMinimumWidth(), imageDrawable.getMinimumHeight() + - (int)(3*scaleCoefficient)); - } this.textPaint = textPaint; this.subtextPaint = subtextPaint; } + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if(imageDrawable != null) { + // Unknown reason to add 3*scaleCoefficient + imageDrawable.setBounds(getLeft(), + getTop() + (int) (3*scaleCoefficient), + getLeft() + imageDrawable.getMinimumWidth(), + getTop() + imageDrawable.getMinimumHeight() + + (int)(3*scaleCoefficient)); + } + } + public void setText(String text, String subtext) { this.text = text; this.subtext = subtext; - cacheMeasuredWidth = -1; + requestLayout(); } @Override - public int getMeasuredWidth() { - if (cacheMeasuredWidth == -1) { - int w = 0; - if (text != null) { - if(imageDrawable != null) { - w += imageDrawable.getBounds().width(); - } - w += leftMargin; - w += textPaint.measureText(text); - if (subtext != null) { - w += subtextPaint.measureText(subtext) + 2 * scaleCoefficient; - } + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // ignore attributes + int w = 0; + int h = 0; + if (text != null) { + if(imageDrawable != null) { + w += imageDrawable.getMinimumWidth(); + } + w += leftMargin; + w += textPaint.measureText(text); + if (subtext != null) { + w += subtextPaint.measureText(subtext) + 2 * scaleCoefficient; + } + + h = (int) (5 * scaleCoefficient + Math.max(textPaint.getTextSize(), subtextPaint.getTextSize())); + if(imageDrawable != null) { + h = Math.max(h, (int)(imageDrawable.getMinimumHeight())); } - cacheMeasuredWidth = w; } - return cacheMeasuredWidth; + setMeasuredDimension(w, h); } @Override - void onDraw(Canvas cv) { + protected void onDraw(Canvas cv) { super.onDraw(cv); if (isVisible()) { int margin = 0; @@ -665,27 +643,17 @@ public class MapInfoLayer extends OsmandMapLayer { margin = imageDrawable.getBounds().width(); } margin += leftMargin; - cv.drawText(text, margin , getHeight() - scaleCoefficient, textPaint); + cv.drawText(text, margin + getLeft(), getBottom() - 2 * scaleCoefficient, textPaint); if (subtext != null) { - cv.drawText(subtext, margin + 2 * scaleCoefficient + textPaint.measureText(text), - getHeight() - scaleCoefficient, subtextPaint); + cv.drawText(subtext, getLeft() + margin + 2 * scaleCoefficient + textPaint.measureText(text), getBottom() + - 2 * scaleCoefficient, subtextPaint); } } } - @Override public boolean isVisible() { return text != null && text.length() > 0; } - - @Override - public int getMeasuredHeight() { - int h = (int) (2 * scaleCoefficient + Math.max(textPaint.getTextSize(), subtextPaint.getTextSize())); - if(imageDrawable != null) { - h = Math.max(h, (int)(imageDrawable.getMinimumHeight())); - } - return h; - } }