From f241e75c903e50fe2eb307a088c2aa9103b6fc32 Mon Sep 17 00:00:00 2001 From: 0xRe1nk0 <0xre1nk0@gmail.com> Date: Mon, 3 Mar 2025 05:31:45 +0200 Subject: [PATCH] UI review fix --- .../BaseMultiStateCardController.java | 18 +++ .../FavoriteAppearanceController.java | 3 + .../net/osmand/plus/helpers/IntentHelper.java | 12 -- ...aultFavoriteAppearanceSaveBottomSheet.java | 4 +- .../editors/FavoriteAppearanceFragment.java | 135 ++++++++++-------- .../editors/FavoriteShapesCardController.java | 3 +- .../mapcontextmenu/editors/ShapesCard.java | 8 +- .../EditFavoriteGroupDialogFragment.java | 18 ++- .../views/mapwidgets/WidgetsContextMenu.java | 3 +- .../osmand/plus/widgets/popup/PopUpMenu.java | 57 ++++++-- .../widgets/popup/PopUpMenuDisplayData.java | 9 +- 11 files changed, 175 insertions(+), 95 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/card/base/multistate/BaseMultiStateCardController.java b/OsmAnd/src/net/osmand/plus/card/base/multistate/BaseMultiStateCardController.java index 0e632a67b22..5ff8428b4a9 100644 --- a/OsmAnd/src/net/osmand/plus/card/base/multistate/BaseMultiStateCardController.java +++ b/OsmAnd/src/net/osmand/plus/card/base/multistate/BaseMultiStateCardController.java @@ -10,6 +10,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.widgets.popup.PopUpMenu; import net.osmand.plus.widgets.popup.PopUpMenuDisplayData; +import net.osmand.plus.widgets.popup.PopUpMenuDisplayData.CustomDropDown; import net.osmand.plus.widgets.popup.PopUpMenuItem; import java.util.ArrayList; @@ -24,6 +25,9 @@ public abstract class BaseMultiStateCardController implements IMultiStateCardCon protected List states; protected CardState selectedState; + protected CustomDropDown customDropDownSelectorPopup; + protected Boolean limitHeightSelectorPopup; + public BaseMultiStateCardController(@NonNull OsmandApplication app) { this.app = app; } @@ -49,6 +53,12 @@ public void onSelectorButtonClicked(@NonNull View view) { } } PopUpMenuDisplayData data = new PopUpMenuDisplayData(); + if (customDropDownSelectorPopup != null) { + data.customDropDown = customDropDownSelectorPopup; + } + if (limitHeightSelectorPopup != null) { + data.limitHeight = limitHeightSelectorPopup; + } data.anchorView = view; data.menuItems = items; data.nightMode = nightMode; @@ -74,6 +84,14 @@ protected CardState findCardState(@Nullable Object tag) { return states.get(0); } + public void setCustomDropDownSelectorPopup(@NonNull CustomDropDown customDropDownSelectorPopup) { + this.customDropDownSelectorPopup = customDropDownSelectorPopup; + } + + public void setLimitHeightSelectorPopup(@Nullable Boolean limitHeightSelectorPopup) { + this.limitHeightSelectorPopup = limitHeightSelectorPopup; + } + protected boolean isCardStateAvailable(@NonNull CardState cardState) { return true; } diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/appearance/favorite/FavoriteAppearanceController.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/appearance/favorite/FavoriteAppearanceController.java index 94d32d27ef0..78d3293ac04 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/appearance/favorite/FavoriteAppearanceController.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/appearance/favorite/FavoriteAppearanceController.java @@ -22,6 +22,7 @@ import net.osmand.plus.myplaces.favorites.FavoriteGroup; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; +import net.osmand.plus.widgets.popup.PopUpMenuDisplayData.CustomDropDown; import net.osmand.shared.routing.ColoringType; public class FavoriteAppearanceController implements IDialogController, IColorCardControllerListener, CardListener, OnIconsPaletteListener { @@ -61,6 +62,8 @@ public FavoriteAppearanceController(@NonNull OsmandApplication app, @NonNull Fav } editorIconController.init(); editorIconController.setIconsPaletteListener(this); + editorIconController.getCardController().setCustomDropDownSelectorPopup(CustomDropDown.TOP_DROPDOWN); + editorIconController.getCardController().setLimitHeightSelectorPopup(true); shapesCardController = new FavoriteShapesCardController(app, this, selectedBackgroundType != null ? selectedBackgroundType : null); } diff --git a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java index d8bcbab8671..9ab730071e0 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java @@ -527,18 +527,6 @@ public void parseContentIntent() { } clearIntent(intent); } - if (intent.hasExtra(EditFavoriteGroupDialogFragment.GROUP_NAME_KEY)) { - String groupName = intent.getStringExtra(EditFavoriteGroupDialogFragment.GROUP_NAME_KEY); - FavoriteGroup favoriteGroup = app.getFavoritesHelper().getGroup(FavoriteGroup.convertDisplayNameToGroupIdName(app, groupName)); - - PointsGroup pointsGroup = favoriteGroup != null ? favoriteGroup.toPointsGroup(app) : null; - FragmentManager manager = mapActivity.getSupportFragmentManager(); - if (pointsGroup != null) { - FavoriteAppearanceFragment.showInstance(manager, pointsGroup, true); - } - - clearIntent(intent); - } if (intent.hasExtra(BaseSettingsFragment.OPEN_CONFIG_ON_MAP)) { switch (intent.getStringExtra(BaseSettingsFragment.OPEN_CONFIG_ON_MAP)) { case BaseSettingsFragment.MAP_CONFIG: diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/DefaultFavoriteAppearanceSaveBottomSheet.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/DefaultFavoriteAppearanceSaveBottomSheet.java index 06db6c32c3a..ef328584011 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/DefaultFavoriteAppearanceSaveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/DefaultFavoriteAppearanceSaveBottomSheet.java @@ -102,11 +102,9 @@ public int getSecondDividerHeight() { return getResources().getDimensionPixelSize(R.dimen.horizontal_divider_height); } - public static void showInstance(@NonNull FragmentManager manager, @Nullable Fragment target, - @NonNull String editorTag, int pointsSize) { + public static void showInstance(@NonNull FragmentManager manager, @Nullable Fragment target, int pointsSize) { if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { Bundle bundle = new Bundle(); - bundle.putString(EDITOR_TAG_KEY, editorTag); bundle.putInt(POINTS_SIZE_KEY, pointsSize); DefaultFavoriteAppearanceSaveBottomSheet fragment = new DefaultFavoriteAppearanceSaveBottomSheet(); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteAppearanceFragment.java index 3e825f1b859..9d93afba3eb 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteAppearanceFragment.java @@ -5,24 +5,30 @@ import static net.osmand.plus.configmap.tracks.appearance.favorite.FavoriteAppearanceController.PROCESS_ID; import static net.osmand.shared.gpx.GpxUtilities.DEFAULT_ICON_NAME; +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.Window; import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.core.view.ViewCompat; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import net.osmand.data.BackgroundType; import net.osmand.plus.R; -import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.base.BaseOsmAndDialogFragment; import net.osmand.plus.base.dialog.DialogManager; import net.osmand.plus.card.base.multistate.IMultiStateCardController; import net.osmand.plus.card.base.multistate.MultiStateCard; @@ -32,15 +38,16 @@ import net.osmand.plus.myplaces.favorites.FavoriteGroup; import net.osmand.plus.myplaces.favorites.FavouritesHelper; import net.osmand.plus.myplaces.favorites.FavouritesHelper.SaveOption; +import net.osmand.plus.myplaces.favorites.dialogs.FavoritesTreeFragment; import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.ColorUtilities; +import net.osmand.plus.utils.UiUtilities; import net.osmand.plus.widgets.dialogbutton.DialogButton; import net.osmand.plus.widgets.dialogbutton.DialogButtonType; import net.osmand.shared.gpx.GpxUtilities.PointsGroup; -import net.osmand.util.Algorithms; -public class FavoriteAppearanceFragment extends BaseOsmAndFragment { +public class FavoriteAppearanceFragment extends BaseOsmAndDialogFragment { public static final String TAG = FavoriteAppearanceFragment.class.getName(); @@ -57,8 +64,6 @@ public class FavoriteAppearanceFragment extends BaseOsmAndFragment { private String iconName = DEFAULT_ICON_NAME; private BackgroundType backgroundType = DEFAULT_BACKGROUND_TYPE; - private boolean launchPrevIntent; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -78,6 +83,34 @@ public void onCreate(Bundle savedInstanceState) { registerFavoriteAppearanceController(); } + @ColorRes + public int getStatusBarColorId() { + AndroidUiHelper.setStatusBarContentColor(getView(), nightMode); + return ColorUtilities.getStatusBarColorId(nightMode); + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + updateNightMode(); + Activity activity = requireActivity(); + int themeId = nightMode ? R.style.OsmandDarkTheme_DarkActionbar : R.style.OsmandLightTheme_DarkActionbar_LightStatusBar; + Dialog dialog = new Dialog(activity, themeId) { + @Override + public void onBackPressed() { + dismiss(); + } + }; + Window window = dialog.getWindow(); + if (window != null) { + if (!settings.DO_NOT_USE_ANIMATIONS.get()) { + window.getAttributes().windowAnimations = R.style.Animations_Alpha; + } + window.setStatusBarColor(ColorUtilities.getColor(app, getStatusBarColorId())); + } + return dialog; + } + private void registerFavoriteAppearanceController() { dialogManager.register(PROCESS_ID, new FavoriteAppearanceController(app, favoriteGroup, new DefaultFavoriteListener() { @Override @@ -106,7 +139,6 @@ public BackgroundType getOriginalShape() { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { updateNightMode(); view = themedInflater.inflate(R.layout.favorite_default_appearance_fragment, container, false); - AndroidUtils.addStatusBarPadding21v(requireMyActivity(), view); setupToolbar(); setupButtons(); @@ -170,31 +202,6 @@ public void setBackgroundType(@NonNull BackgroundType backgroundType) { this.backgroundType = backgroundType; } - @Override - public int getStatusBarColorId() { - return ColorUtilities.getStatusBarColorId(nightMode); - } - - @Nullable - protected PointEditor getEditor() { - return requireMapActivity().getContextMenu().getFavoritePointEditor(); - } - - public void dismiss() { - hideKeyboard(); - FragmentActivity activity = getActivity(); - if (activity != null) { - activity.getSupportFragmentManager().popBackStack(); - } - } - - protected void hideKeyboard() { - FragmentActivity activity = getActivity(); - if (activity != null) { - AndroidUtils.hideSoftKeyboard(activity, activity.getCurrentFocus()); - } - } - private void setupToolbar() { View appbar = view.findViewById(R.id.appbar); ViewCompat.setElevation(appbar, 5.0f); @@ -219,12 +226,38 @@ protected void setupButtons() { } protected void savePressed() { - PointEditor editor = getEditor(); FragmentActivity activity = getActivity(); - if (editor != null && activity != null) { - String tag = editor.getFragmentTag(); + if (activity != null) { FragmentManager manager = activity.getSupportFragmentManager(); - DefaultFavoriteAppearanceSaveBottomSheet.showInstance(manager, this, tag, pointsGroup.getPoints().size()); + DefaultFavoriteAppearanceSaveBottomSheet.showInstance(manager, this, pointsGroup.getPoints().size()); + } + } + + @Override + public void dismiss() { + boolean hasChanges = false; + if (favoriteGroup != null) { + if (controller.getColor() != null && controller.getColor() != color) { + hasChanges = true; + } + if (controller.getIcon() != null && !controller.getIcon().equals(iconName)) { + hasChanges = true; + } + if (controller.getShape() != null && controller.getShape() != backgroundType) { + hasChanges = true; + } + } + + if (hasChanges) { + Context themedContext = UiUtilities.getThemedContext(requireActivity(), nightMode); + AlertDialog.Builder dismissDialog = new AlertDialog.Builder(themedContext); + dismissDialog.setTitle(getString(R.string.exit_without_saving)); + dismissDialog.setMessage(getString(R.string.dismiss_changes_descr)); + dismissDialog.setNegativeButton(R.string.shared_string_cancel, null); + dismissDialog.setPositiveButton(R.string.shared_string_exit, (dialog, which) -> super.dismiss()); + dismissDialog.show(); + } else { + super.dismiss(); } } @@ -250,16 +283,16 @@ public void editPointsGroup(@NonNull SaveOption saveOption) { favouritesHelper.saveCurrentPointsIntoFile(true); } } + + Fragment targetFragment = getTargetFragment(); + if (targetFragment instanceof FavoritesTreeFragment treeFragment) { + treeFragment.reloadData(); + } dismiss(); } @Override public void onDestroy() { - MapActivity mapActivity = getMapActivity(); - if (launchPrevIntent && mapActivity != null && !mapActivity.isChangingConfigurations()) { - mapActivity.launchPrevActivityIntent(); - } - FragmentActivity activity = getActivity(); if (activity != null && !activity.isChangingConfigurations()) { dialogManager.unregister(FavoriteAppearanceController.PROCESS_ID); @@ -268,28 +301,14 @@ public void onDestroy() { super.onDestroy(); } - @Nullable - protected MapActivity getMapActivity() { - return (MapActivity) getActivity(); - } - - @NonNull - protected MapActivity requireMapActivity() { - return (MapActivity) requireActivity(); - } - public static void showInstance(@NonNull FragmentManager manager, @NonNull PointsGroup pointsGroup, - boolean launchPrevIntent) { + @NonNull Fragment treeFragment) { if (AndroidUtils.isFragmentCanBeAdded(manager, TAG)) { FavoriteAppearanceFragment fragment = new FavoriteAppearanceFragment(); fragment.pointsGroup = pointsGroup; - fragment.launchPrevIntent = launchPrevIntent; - fragment.setRetainInstance(true); - manager.beginTransaction() - .add(R.id.fragmentContainer, fragment, TAG) - .addToBackStack(TAG) - .commitAllowingStateLoss(); + fragment.setTargetFragment(treeFragment, 0); + fragment.show(manager, TAG); } } } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteShapesCardController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteShapesCardController.java index 9856d4e6385..6026490ae37 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteShapesCardController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoriteShapesCardController.java @@ -96,8 +96,7 @@ public void onBindCardContent(@NonNull FragmentActivity activity, @NonNull ViewG } else { BackgroundType type = (BackgroundType) selectedState.getTag(); if (type != null) { - MapActivity mapActivity = (MapActivity) activity; - shapesCard = new ShapesCard(mapActivity, type, centralController.requireColor()){ + shapesCard = new ShapesCard(activity, type, centralController.requireColor()){ @Override protected Drawable getOutlineDrawable(@DrawableRes int shapeIconId) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/ShapesCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/ShapesCard.java index 0305d59baa8..78cf66e154b 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/ShapesCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/ShapesCard.java @@ -9,23 +9,25 @@ import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; import net.osmand.data.BackgroundType; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.MapBaseCard; import net.osmand.plus.utils.ColorUtilities; import net.osmand.plus.widgets.FlowLayout; -public class ShapesCard extends MapBaseCard { +public class ShapesCard extends BaseCard { @NonNull private BackgroundType selectedShape; @ColorInt protected int selectedColor; - public ShapesCard(@NonNull MapActivity mapActivity, @NonNull BackgroundType shape, @ColorInt int color) { - super(mapActivity); + public ShapesCard(@NonNull FragmentActivity fragmentActivity, @NonNull BackgroundType shape, @ColorInt int color) { + super(fragmentActivity); this.selectedShape = shape; this.selectedColor = color; } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/favorites/dialogs/EditFavoriteGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/favorites/dialogs/EditFavoriteGroupDialogFragment.java index 4917107535e..9b233b3b3e5 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/favorites/dialogs/EditFavoriteGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/favorites/dialogs/EditFavoriteGroupDialogFragment.java @@ -25,6 +25,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.plus.mapcontextmenu.editors.FavoriteAppearanceFragment; import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.myplaces.favorites.FavoriteGroup; @@ -32,6 +33,7 @@ import net.osmand.plus.utils.AndroidUtils; import net.osmand.plus.utils.FontCache; import net.osmand.plus.utils.UiUtilities; +import net.osmand.shared.gpx.GpxUtilities.PointsGroup; import net.osmand.util.Algorithms; public class EditFavoriteGroupDialogFragment extends MenuBottomSheetDialogFragment { @@ -108,13 +110,15 @@ public void createMenuItems(Bundle savedInstanceState) { .setOnClickListener(v -> { FragmentActivity activity = getActivity(); if (activity != null) { - Bundle bundle = new Bundle(); - Bundle prevParams = new Bundle(); - - bundle.putString(GROUP_NAME_KEY, group.getName()); - prevParams.putInt(TAB_ID, FAV_TAB); - - MapActivity.launchMapActivityMoveToTop(activity, prevParams, null, bundle); + PointsGroup pointsGroup = group != null ? group.toPointsGroup(app) : null; + FragmentManager manager = activity.getSupportFragmentManager(); + if (pointsGroup != null) { + Fragment fragment = getParentFragment(); + if (fragment instanceof FavoritesTreeFragment) { + FavoriteAppearanceFragment.showInstance(manager, pointsGroup, fragment); + dismiss(); + } + } } }) .create(); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsContextMenu.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsContextMenu.java index 5feaa48f59b..413fb8031a3 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsContextMenu.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsContextMenu.java @@ -23,6 +23,7 @@ import net.osmand.plus.views.mapwidgets.widgetinterfaces.ISupportMultiRow; import net.osmand.plus.widgets.popup.PopUpMenu; import net.osmand.plus.widgets.popup.PopUpMenuDisplayData; +import net.osmand.plus.widgets.popup.PopUpMenuDisplayData.CustomDropDown; import net.osmand.plus.widgets.popup.PopUpMenuItem; import net.osmand.plus.widgets.popup.PopUpMenuWidthMode; import net.osmand.util.Algorithms; @@ -103,7 +104,7 @@ static public void showMenu(@NonNull View view, @NonNull MapActivity mapActivity displayData.nightMode = nightMode; displayData.widthMode = PopUpMenuWidthMode.STANDARD; displayData.showCompound = false; - displayData.customDropDown = false; + displayData.customDropDown = CustomDropDown.NONE; displayData.layoutId = R.layout.popup_menu_item_full_divider; PopUpMenu.show(displayData); } diff --git a/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenu.java b/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenu.java index 544b1699c09..8c0702f9103 100644 --- a/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenu.java +++ b/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenu.java @@ -10,8 +10,8 @@ import android.view.View; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.view.menu.MenuBuilder; -import androidx.appcompat.view.menu.MenuPopupHelper; import androidx.appcompat.widget.ListPopupWindow; import androidx.appcompat.widget.PopupMenu; import androidx.core.view.MenuCompat; @@ -73,15 +73,15 @@ private ListPopupWindow createCustomListPopUpWindow() { listPopupWindow.setContentWidth(totalWidth); listPopupWindow.setModal(true); listPopupWindow.setAdapter(adapter); - if (displayData.customDropDown) { - if (shouldShowAsDropDown(ctx)) { - listPopupWindow.setDropDownGravity(Gravity.START | Gravity.TOP); - listPopupWindow.setVerticalOffset(-anchorView.getHeight() + contentPaddingHalf); - } else { - listPopupWindow.setDropDownGravity(Gravity.START | Gravity.BOTTOM); - listPopupWindow.setVerticalOffset(anchorView.getHeight() - contentPaddingHalf); + + setDropDown(listPopupWindow, anchorView, ctx); + if (displayData.limitHeight) { + Integer maxHeight = calculatePopupMaxHeight(anchorView, ctx); + if (maxHeight != null) { + listPopupWindow.setHeight(maxHeight); } } + if (displayData.bgColor != 0) { listPopupWindow.setBackgroundDrawable(new ColorDrawable(displayData.bgColor)); } @@ -94,6 +94,47 @@ private ListPopupWindow createCustomListPopUpWindow() { return listPopupWindow; } + private void setDropDown(@NonNull ListPopupWindow listPopupWindow, @NonNull View anchorView, @NonNull Context ctx){ + int contentPaddingHalf = getDimension(ctx, R.dimen.content_padding_half); + + switch (displayData.customDropDown) { + case AUTO_DROP_DOWN -> { + if (shouldShowAsDropDown(ctx)) { + listPopupWindow.setDropDownGravity(Gravity.START | Gravity.TOP); + listPopupWindow.setVerticalOffset(-anchorView.getHeight() + contentPaddingHalf); + } else { + listPopupWindow.setDropDownGravity(Gravity.START | Gravity.BOTTOM); + listPopupWindow.setVerticalOffset(anchorView.getHeight() - contentPaddingHalf); + } + } + case TOP_DROPDOWN -> { + listPopupWindow.setDropDownGravity(Gravity.START | Gravity.TOP); + listPopupWindow.setVerticalOffset(-anchorView.getHeight() + contentPaddingHalf); + } + case BOTTOM_DROPDOWN -> { + listPopupWindow.setDropDownGravity(Gravity.START | Gravity.BOTTOM); + listPopupWindow.setVerticalOffset(anchorView.getHeight() - contentPaddingHalf); + } + } + } + + @Nullable + private Integer calculatePopupMaxHeight(View anchorView, Context context) { + int totalHeightNeeded = calculateApproxPopupWindowHeight(context); + int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels; + int[] location = new int[2]; + anchorView.getLocationOnScreen(location); + int availableSpaceBelow = screenHeight - location[1] - anchorView.getHeight(); + + + if (totalHeightNeeded <= availableSpaceBelow) { + return null; + } + + int contentPaddingHalf = context.getResources().getDimensionPixelSize(R.dimen.content_padding_half); + return availableSpaceBelow - contentPaddingHalf; + } + private boolean shouldShowAsDropDown(@NonNull Context ctx) { int screenHeight = ctx.getResources().getDisplayMetrics().heightPixels; int anchorViewTopY = AndroidUtils.getViewOnScreenY(displayData.anchorView); diff --git a/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenuDisplayData.java b/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenuDisplayData.java index a2014bde614..a7df47fda60 100644 --- a/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenuDisplayData.java +++ b/OsmAnd/src/net/osmand/plus/widgets/popup/PopUpMenuDisplayData.java @@ -20,8 +20,9 @@ public class PopUpMenuDisplayData { public PopUpMenuWidthMode widthMode = PopUpMenuWidthMode.AS_ANCHOR_VIEW; public List menuItems; public OnPopUpMenuItemClickListener onItemClickListener; - public boolean customDropDown = true; + public CustomDropDown customDropDown = CustomDropDown.AUTO_DROP_DOWN; public boolean showCompound = true; + public boolean limitHeight = false; public boolean hasCustomizations() { if (layoutId != DEFAULT_LAYOUT_ID) { @@ -35,4 +36,10 @@ public boolean hasCustomizations() { return false; } + public enum CustomDropDown { + AUTO_DROP_DOWN, + TOP_DROPDOWN, + BOTTOM_DROPDOWN, + NONE + } }