From 878208deee79b55325a91d305993fde0f3f576ba Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 26 Jan 2021 19:41:49 +0200 Subject: [PATCH 1/5] Review Show track on the map: all lines should be tappable. Slider color = profile color --- ...h_switch_divider_and_additional_button.xml | 16 ++++--- OsmAnd/res/layout/trip_recording_fragment.xml | 5 ++- OsmAnd/src/net/osmand/plus/UiUtilities.java | 2 +- .../monitoring/TripRecordingBottomSheet.java | 42 +++++++++++++++---- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml b/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml index 681c03e560..8f95b5777b 100644 --- a/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml +++ b/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml @@ -7,15 +7,16 @@ android:baselineAligned="false" android:gravity="center_vertical" android:minHeight="@dimen/bottom_sheet_selected_item_title_height" - android:paddingStart="@dimen/content_padding" - android:paddingEnd="@dimen/content_padding" - android:paddingRight="@dimen/content_padding" - android:paddingLeft="@dimen/content_padding"> + > @@ -46,8 +47,9 @@ android:layout_gravity="center_vertical" android:layout_marginStart="@dimen/bottom_sheet_content_margin" android:layout_marginLeft="@dimen/bottom_sheet_content_margin" - android:layout_marginEnd="@dimen/bottom_sheet_content_margin" - android:layout_marginRight="@dimen/bottom_sheet_content_margin" + android:clickable="false" + android:focusable="false" + android:focusableInTouchMode="false" tools:checked="true" /> @@ -73,6 +75,8 @@ android:layout_gravity="center" android:layout_marginStart="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginRight="@dimen/content_padding" app:srcCompat="@drawable/ic_action_track_line_bold_color" /> diff --git a/OsmAnd/res/layout/trip_recording_fragment.xml b/OsmAnd/res/layout/trip_recording_fragment.xml index 8c43e98d5f..d35626a7ce 100644 --- a/OsmAnd/res/layout/trip_recording_fragment.xml +++ b/OsmAnd/res/layout/trip_recording_fragment.xml @@ -32,6 +32,8 @@ android:background="?attr/dashboard_divider" /> @@ -106,8 +109,6 @@ android:id="@+id/second_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:layout_marginTop="@dimen/content_padding" - android:layout_marginBottom="@dimen/bottom_sheet_content_margin_small" android:background="?attr/dashboard_divider" /> diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index 94bd3c4bcb..8d3a6d35bf 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -636,7 +636,7 @@ public class UiUtilities { int activeDisableColor = getColorWithAlpha(activeColor, 0.25f); ColorStateList activeCsl = new ColorStateList(states, new int[] {activeColor, activeDisableColor}); int inactiveColor = ContextCompat.getColor(ctx, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_secondary_light); - ColorStateList inactiveCsl = new ColorStateList(states, new int[] {inactiveColor, inactiveColor}); + ColorStateList inactiveCsl = new ColorStateList(states, new int[] {activeDisableColor, inactiveColor}); slider.setTrackActiveTintList(activeCsl); slider.setTrackInactiveTintList(inactiveCsl); slider.setHaloTintList(activeCsl); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 54b444ff30..096430f3da 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -9,6 +9,7 @@ import android.os.Bundle; import android.text.SpannableString; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; @@ -18,10 +19,12 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.SwitchCompat; +import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; import com.google.android.material.slider.RangeSlider; +import net.osmand.AndroidUtils; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.NavigationService; import net.osmand.plus.OsmandApplication; @@ -49,9 +52,10 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { private ImageView upDownBtn; private SwitchCompat confirmEveryRun; - private RangeSlider intervalSlider; private TextView intervalValueView; private LinearLayout container; + private LinearLayout expandHideIntervalContainer; + private View divider; private boolean infoExpanded; @Override @@ -92,8 +96,10 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { } }); + divider = itemView.findViewById(R.id.second_divider); + expandHideIntervalContainer = itemView.findViewById(R.id.interval_view_container); upDownBtn = itemView.findViewById(R.id.up_down_button); - upDownBtn.setOnClickListener(new View.OnClickListener() { + expandHideIntervalContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -108,8 +114,11 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { updateIntervalLegend(); container = itemView.findViewById(R.id.always_ask_and_range_slider_container); - intervalSlider = itemView.findViewById(R.id.interval_slider); + RangeSlider intervalSlider = itemView.findViewById(R.id.interval_slider); intervalSlider.setValueTo(secondsLength + minutesLength - 1); + int currentModeColorRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); + int currentModeColor = ContextCompat.getColor(app, currentModeColorRes); + UiUtilities.setupSlider(intervalSlider, nightMode, currentModeColor, true); container.setVisibility(View.GONE); intervalSlider.addOnChangeListener(new RangeSlider.OnChangeListener() { @@ -126,6 +135,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { updateIntervalLegend(); } }); + for (int i = 0; i < secondsLength + minutesLength; i++) { if (i < secondsLength) { if (settings.SAVE_GLOBAL_TRACK_INTERVAL.get() <= SECONDS[i] * 1000) { @@ -151,13 +161,19 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { } }); - SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); + final SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); - showTrackOnMapButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - + View basicItem = itemView.findViewById(R.id.basic_item_body); + basicItem.setOnClickListener(new View.OnClickListener() { @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), isChecked, false); + public void onClick(View v) { + if (showTrackOnMapButton.isChecked()) { + showTrackOnMapButton.setChecked(false); + app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), false, false); + } else { + showTrackOnMapButton.setChecked(true); + app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), true, false); + } } }); UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); @@ -217,6 +233,16 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { private void toggleInfoView() { infoExpanded = !infoExpanded; + ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) divider.getLayoutParams(); + if (getMapActivity() != null) { + final int dp8 = AndroidUtils.dpToPx(getMapActivity(), 8f); + final int dp16 = AndroidUtils.dpToPx(getMapActivity(), 16f); + if (infoExpanded) { + AndroidUtils.setMargins(marginParams, 0, dp16, 0, dp8); + } else { + AndroidUtils.setMargins(marginParams, 0, 0, 0, dp8); + } + } AndroidUiHelper.updateVisibility(container, infoExpanded); updateUpDownBtn(); } From a9a423138af52e84f016fcefd8bd0e44d6524901 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 27 Jan 2021 12:28:17 +0200 Subject: [PATCH 2/5] Buttons height Buttons, add a parameter for our button default/large (user needed proper name). Those parameters should control buttons height, default 36dp, large 48 dp. Make bottom buttons 48 --- .../base/MenuBottomSheetDialogFragment.java | 18 ++++++++++++++++++ .../monitoring/TripRecordingBottomSheet.java | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index 2af2d9673b..0afa81a300 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -268,6 +268,18 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra dismissButtonStringRes = stringRes; } + protected int getDismissButtonHeight(){ + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height_small); + } + + protected int getRightButtonHeight(){ + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height_small); + } + + protected int getThirdButtonHeight(){ + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height_small); + } + protected DialogButtonType getDismissButtonType() { return DialogButtonType.SECONDARY; } @@ -360,6 +372,8 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private void setupDismissButton() { dismissButton = buttonsContainer.findViewById(R.id.dismiss_button); + android.widget.LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getDismissButtonHeight()); + dismissButton.setLayoutParams(lp); int buttonTextId = getDismissButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), buttonTextId); @@ -376,6 +390,8 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private void setupRightButton() { rightButton = buttonsContainer.findViewById(R.id.right_bottom_button); + android.widget.LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getRightButtonHeight()); + rightButton.setLayoutParams(lp); int buttonTextId = getRightBottomButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { UiUtilities.setupDialogButton(nightMode, rightButton, getRightBottomButtonType(), buttonTextId); @@ -398,6 +414,8 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra protected void setupThirdButton() { thirdButton = buttonsContainer.findViewById(R.id.third_button); + android.widget.LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getThirdButtonHeight()); + thirdButton.setLayoutParams(lp); int buttonTextId = getThirdBottomButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { UiUtilities.setupDialogButton(nightMode, thirdButton, getThirdBottomButtonType(), buttonTextId); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 096430f3da..1cb23e7ba9 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -252,6 +252,16 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { return true; } + @Override + protected int getRightButtonHeight(){ + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); + } + + @Override + protected int getDismissButtonHeight(){ + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height); + } + @Override protected int getRightBottomButtonTextId() { return R.string.start_recording; From 14d00037b2e8481a2e7a26746208bd29d46ee537 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 27 Jan 2021 13:37:32 +0200 Subject: [PATCH 3/5] Pull request review --- .../base/MenuBottomSheetDialogFragment.java | 9 +++------ .../monitoring/TripRecordingBottomSheet.java | 19 ++++++------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java index 0afa81a300..9f97a07563 100644 --- a/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/MenuBottomSheetDialogFragment.java @@ -372,8 +372,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private void setupDismissButton() { dismissButton = buttonsContainer.findViewById(R.id.dismiss_button); - android.widget.LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getDismissButtonHeight()); - dismissButton.setLayoutParams(lp); + dismissButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getDismissButtonHeight())); int buttonTextId = getDismissButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), buttonTextId); @@ -390,8 +389,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra private void setupRightButton() { rightButton = buttonsContainer.findViewById(R.id.right_bottom_button); - android.widget.LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getRightButtonHeight()); - rightButton.setLayoutParams(lp); + rightButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getRightButtonHeight())); int buttonTextId = getRightBottomButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { UiUtilities.setupDialogButton(nightMode, rightButton, getRightBottomButtonType(), buttonTextId); @@ -414,8 +412,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra protected void setupThirdButton() { thirdButton = buttonsContainer.findViewById(R.id.third_button); - android.widget.LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getThirdButtonHeight()); - thirdButton.setLayoutParams(lp); + thirdButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getThirdButtonHeight())); int buttonTextId = getThirdBottomButtonTextId(); if (buttonTextId != DEFAULT_VALUE) { UiUtilities.setupDialogButton(nightMode, thirdButton, getThirdBottomButtonType(), buttonTextId); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 1cb23e7ba9..533d9f151d 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -54,7 +54,6 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { private SwitchCompat confirmEveryRun; private TextView intervalValueView; private LinearLayout container; - private LinearLayout expandHideIntervalContainer; private View divider; private boolean infoExpanded; @@ -97,7 +96,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { }); divider = itemView.findViewById(R.id.second_divider); - expandHideIntervalContainer = itemView.findViewById(R.id.interval_view_container); + LinearLayout expandHideIntervalContainer = itemView.findViewById(R.id.interval_view_container); upDownBtn = itemView.findViewById(R.id.up_down_button); expandHideIntervalContainer.setOnClickListener(new View.OnClickListener() { @@ -167,13 +166,9 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { basicItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (showTrackOnMapButton.isChecked()) { - showTrackOnMapButton.setChecked(false); - app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), false, false); - } else { - showTrackOnMapButton.setChecked(true); - app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), true, false); - } + boolean checked = !showTrackOnMapButton.isChecked(); + showTrackOnMapButton.setChecked(checked); + app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), checked, false); } }); UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); @@ -234,15 +229,13 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { private void toggleInfoView() { infoExpanded = !infoExpanded; ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) divider.getLayoutParams(); - if (getMapActivity() != null) { - final int dp8 = AndroidUtils.dpToPx(getMapActivity(), 8f); - final int dp16 = AndroidUtils.dpToPx(getMapActivity(), 16f); + final int dp8 = AndroidUtils.dpToPx(app, 8f); + final int dp16 = AndroidUtils.dpToPx(app, 16f); if (infoExpanded) { AndroidUtils.setMargins(marginParams, 0, dp16, 0, dp8); } else { AndroidUtils.setMargins(marginParams, 0, 0, 0, dp8); } - } AndroidUiHelper.updateVisibility(container, infoExpanded); updateUpDownBtn(); } From 2baf45e76f322e19d4724bf39c406ca21435e7c6 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 27 Jan 2021 13:46:33 +0200 Subject: [PATCH 4/5] Code styling fix --- ...h_switch_divider_and_additional_button.xml | 139 +++++++++--------- .../monitoring/TripRecordingBottomSheet.java | 14 +- 2 files changed, 76 insertions(+), 77 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml b/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml index 8f95b5777b..6953783885 100644 --- a/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml +++ b/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml @@ -1,84 +1,83 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:baselineAligned="false" + android:gravity="center_vertical" + android:minHeight="@dimen/bottom_sheet_selected_item_title_height"> - + - + - + - + - + - + - + - + - + - + diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 533d9f151d..789fc0aeb0 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -229,13 +229,13 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { private void toggleInfoView() { infoExpanded = !infoExpanded; ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) divider.getLayoutParams(); - final int dp8 = AndroidUtils.dpToPx(app, 8f); - final int dp16 = AndroidUtils.dpToPx(app, 16f); - if (infoExpanded) { - AndroidUtils.setMargins(marginParams, 0, dp16, 0, dp8); - } else { - AndroidUtils.setMargins(marginParams, 0, 0, 0, dp8); - } + final int dp8 = AndroidUtils.dpToPx(app, 8f); + final int dp16 = AndroidUtils.dpToPx(app, 16f); + if (infoExpanded) { + AndroidUtils.setMargins(marginParams, 0, dp16, 0, dp8); + } else { + AndroidUtils.setMargins(marginParams, 0, 0, 0, dp8); + } AndroidUiHelper.updateVisibility(container, infoExpanded); updateUpDownBtn(); } From cae54bf0efc4f909d0d1c1d0031cd88b882bbea3 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 27 Jan 2021 13:48:45 +0200 Subject: [PATCH 5/5] Code style 2 --- OsmAnd/res/layout/trip_recording_fragment.xml | 200 +++++++++--------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/OsmAnd/res/layout/trip_recording_fragment.xml b/OsmAnd/res/layout/trip_recording_fragment.xml index d35626a7ce..f69e4eb4c7 100644 --- a/OsmAnd/res/layout/trip_recording_fragment.xml +++ b/OsmAnd/res/layout/trip_recording_fragment.xml @@ -1,115 +1,115 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:osmand="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> - + - + - + - + - + - - + + - + - + - - + + - +