Revision c820515c
Added by Leszek Koltunski almost 2 years ago
| src/main/java/org/distorted/main/MainActivity.java | ||
|---|---|---|
| 66 | 66 |
private FirebaseAnalytics mFirebaseAnalytics; |
| 67 | 67 |
private int mCurrentApiVersion; |
| 68 | 68 |
private String mOldVersion, mCurrVersion; |
| 69 |
private int mScreenWidth; |
|
| 69 |
private int mScreenWidth, mScreenHeight;
|
|
| 70 | 70 |
private TextView mBubbleUpdates; |
| 71 | 71 |
private int mNumUpdates; |
| 72 | 72 |
private int mCurrentObject; |
| ... | ... | |
| 199 | 199 |
float conv = ((float) dpi/DisplayMetrics.DENSITY_DEFAULT); |
| 200 | 200 |
|
| 201 | 201 |
mScreenWidth = (int) (conf.screenWidthDp*conv + 0.5f); |
| 202 |
mScreenHeight= (int) (conf.screenHeightDp*conv + 0.5f); |
|
| 202 | 203 |
} |
| 203 | 204 |
|
| 204 | 205 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 456 | 457 |
|
| 457 | 458 |
public void onSettings(View v) |
| 458 | 459 |
{
|
| 460 |
int sw = (int)(mScreenWidth*0.7); |
|
| 461 |
int sh = (int)(mScreenHeight*0.2f); |
|
| 459 | 462 |
|
| 463 |
int vw = v.getWidth(); |
|
| 464 |
|
|
| 465 |
MainSettingsPopup popup = new MainSettingsPopup(this,mScreenWidth,mScreenHeight); |
|
| 466 |
popup.displayPopup(this,v,sw,sh,(int)((vw-sw)/2),0); |
|
| 460 | 467 |
} |
| 461 | 468 |
|
| 462 | 469 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| src/main/java/org/distorted/main/MainSettingsPopup.java | ||
|---|---|---|
| 1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 2 |
// Copyright 2023 Leszek Koltunski // |
|
| 3 |
// // |
|
| 4 |
// This file is part of Magic Cube. // |
|
| 5 |
// // |
|
| 6 |
// Magic Cube is proprietary software licensed under an EULA which you should have received // |
|
| 7 |
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html // |
|
| 8 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 9 |
|
|
| 10 |
package org.distorted.main; |
|
| 11 |
|
|
| 12 |
import android.content.Context; |
|
| 13 |
import android.os.Build; |
|
| 14 |
import android.util.TypedValue; |
|
| 15 |
import android.view.Gravity; |
|
| 16 |
import android.view.LayoutInflater; |
|
| 17 |
import android.view.View; |
|
| 18 |
import android.widget.AdapterView; |
|
| 19 |
import android.widget.ArrayAdapter; |
|
| 20 |
import android.widget.ListPopupWindow; |
|
| 21 |
import android.widget.PopupWindow; |
|
| 22 |
import android.widget.Spinner; |
|
| 23 |
import android.widget.TextView; |
|
| 24 |
|
|
| 25 |
import java.lang.reflect.Field; |
|
| 26 |
|
|
| 27 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 28 |
|
|
| 29 |
public class MainSettingsPopup implements AdapterView.OnItemSelectedListener |
|
| 30 |
{
|
|
| 31 |
private static final float MENU_TITLE_SIZE= 0.070f; |
|
| 32 |
private static final float MENU_TEXT_SIZE = 0.060f; |
|
| 33 |
|
|
| 34 |
private final PopupWindow mPopup; |
|
| 35 |
private static final int[] mLocation = new int[2]; |
|
| 36 |
private int mCurrMethod; |
|
| 37 |
|
|
| 38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 39 |
// this is supposed to prevent showing the navigational bar when we show the drop down list, |
|
| 40 |
// but it doesn't quite work... At least not in the emulator. |
|
| 41 |
// see https://gist.github.com/kakajika/a236ba721a5c0ad3c1446e16a7423a63 |
|
| 42 |
// |
|
| 43 |
// EDIT: the bar does not appear on API 34 without the need to call this method. Must have been |
|
| 44 |
// fixed by Android developers. |
|
| 45 |
|
|
| 46 |
public static void avoidSpinnerDropdownFocus(Spinner spinner) |
|
| 47 |
{
|
|
| 48 |
try |
|
| 49 |
{
|
|
| 50 |
Field listPopupField = Spinner.class.getDeclaredField("mPopup");
|
|
| 51 |
listPopupField.setAccessible(true); |
|
| 52 |
Object listPopup = listPopupField.get(spinner); |
|
| 53 |
|
|
| 54 |
if( listPopup instanceof ListPopupWindow ) |
|
| 55 |
{
|
|
| 56 |
Field popupField = ListPopupWindow.class.getDeclaredField("mPopup");
|
|
| 57 |
popupField.setAccessible(true); |
|
| 58 |
Object popup = popupField.get((ListPopupWindow) listPopup); |
|
| 59 |
|
|
| 60 |
if( popup instanceof PopupWindow ) |
|
| 61 |
{
|
|
| 62 |
((PopupWindow) popup).setFocusable(false); |
|
| 63 |
} |
|
| 64 |
} |
|
| 65 |
} |
|
| 66 |
catch (NoSuchFieldException | IllegalAccessException ignored) |
|
| 67 |
{
|
|
| 68 |
|
|
| 69 |
} |
|
| 70 |
} |
|
| 71 |
|
|
| 72 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 73 |
|
|
| 74 |
MainSettingsPopup(MainActivity act, int width, int height) |
|
| 75 |
{
|
|
| 76 |
// due to bugs in Android API <=25, a Spinner inside a PopupWindow will crash once you click on it. |
|
| 77 |
// solution: on those APIs, use a special Spinner in dialog mode (this does not crash) |
|
| 78 |
int id = android.os.Build.VERSION.SDK_INT <= 25 ? R.layout.settings_popup_android25 : R.layout.settings_popup; |
|
| 79 |
|
|
| 80 |
LayoutInflater layoutInflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
|
| 81 |
final View layout = layoutInflater.inflate(id, null); |
|
| 82 |
|
|
| 83 |
mPopup = new PopupWindow(act); |
|
| 84 |
mPopup.setContentView(layout); |
|
| 85 |
mPopup.setFocusable(true); |
|
| 86 |
|
|
| 87 |
int titleSize = (int)(MENU_TITLE_SIZE*width); |
|
| 88 |
int textSize = (int)(MENU_TEXT_SIZE*width); |
|
| 89 |
|
|
| 90 |
TextView title = layout.findViewById(R.id.sortTitle); |
|
| 91 |
title.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize); |
|
| 92 |
TextView text = layout.findViewById(R.id.sortText); |
|
| 93 |
text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); |
|
| 94 |
|
|
| 95 |
Spinner actSpinner = layout.findViewById(R.id.sortMethod); |
|
| 96 |
actSpinner.setOnItemSelectedListener(this); |
|
| 97 |
|
|
| 98 |
mCurrMethod = -1; |
|
| 99 |
|
|
| 100 |
String[] actNames = { "Classic" , "Category" , "Difficulty", "Author" , "Year" };
|
|
| 101 |
ArrayAdapter<String> actAdapter = new ArrayAdapter<>(act, android.R.layout.simple_spinner_item, actNames); |
|
| 102 |
actAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
|
| 103 |
actSpinner.setAdapter(actAdapter); |
|
| 104 |
} |
|
| 105 |
|
|
| 106 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 107 |
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes |
|
| 108 |
|
|
| 109 |
public void displayPopup(MainActivity act, View view, int w, int h, int xoff, int yoff) |
|
| 110 |
{
|
|
| 111 |
View v = mPopup.getContentView(); |
|
| 112 |
v.setSystemUiVisibility(MainActivity.FLAGS); |
|
| 113 |
|
|
| 114 |
View topLayout = act.findViewById(R.id.relativeLayout); |
|
| 115 |
|
|
| 116 |
boolean isFullScreen; |
|
| 117 |
|
|
| 118 |
if( topLayout!=null ) |
|
| 119 |
{
|
|
| 120 |
topLayout.getLocationOnScreen(mLocation); |
|
| 121 |
isFullScreen = (mLocation[1]==0); |
|
| 122 |
} |
|
| 123 |
else |
|
| 124 |
{
|
|
| 125 |
isFullScreen = true; |
|
| 126 |
} |
|
| 127 |
|
|
| 128 |
try |
|
| 129 |
{
|
|
| 130 |
// if on Android 11 or we are fullscreen |
|
| 131 |
if (Build.VERSION_CODES.R<=Build.VERSION.SDK_INT || isFullScreen ) |
|
| 132 |
{
|
|
| 133 |
mPopup.showAsDropDown(view, xoff, yoff, Gravity.CENTER); |
|
| 134 |
mPopup.update(view, w, h); |
|
| 135 |
} |
|
| 136 |
else // Android 10 or below in pop-up mode or split-screen mode |
|
| 137 |
{
|
|
| 138 |
view.getLocationOnScreen(mLocation); |
|
| 139 |
int width = view.getWidth(); |
|
| 140 |
int height = view.getHeight(); |
|
| 141 |
int x = mLocation[0]+(width-w)/2; |
|
| 142 |
int y = mLocation[1]+height+yoff; |
|
| 143 |
mPopup.showAsDropDown(view); |
|
| 144 |
mPopup.update(x,y,w,h); |
|
| 145 |
} |
|
| 146 |
} |
|
| 147 |
catch( IllegalArgumentException iae ) |
|
| 148 |
{
|
|
| 149 |
// ignore, this means window is 'not attached to window manager' - |
|
| 150 |
// which most probably is because we are already exiting the app. |
|
| 151 |
} |
|
| 152 |
} |
|
| 153 |
|
|
| 154 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 155 |
|
|
| 156 |
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) |
|
| 157 |
{
|
|
| 158 |
if( parent.getId()==R.id.sortMethod && mCurrMethod!=pos ) |
|
| 159 |
{
|
|
| 160 |
mCurrMethod = pos; |
|
| 161 |
} |
|
| 162 |
} |
|
| 163 |
|
|
| 164 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 165 |
|
|
| 166 |
public void onNothingSelected(AdapterView<?> parent) |
|
| 167 |
{
|
|
| 168 |
|
|
| 169 |
} |
|
| 170 |
} |
|
| 171 |
|
|
| src/main/res/layout/settings_popup.xml | ||
|---|---|---|
| 1 |
<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 3 |
android:id="@+id/settingsGrid" |
|
| 4 |
android:layout_width="wrap_content" |
|
| 5 |
android:layout_height="wrap_content" |
|
| 6 |
android:gravity="center" |
|
| 7 |
android:orientation="vertical"> |
|
| 8 |
|
|
| 9 |
<TextView |
|
| 10 |
android:id="@+id/sortTitle" |
|
| 11 |
android:layout_width="match_parent" |
|
| 12 |
android:layout_height="wrap_content" |
|
| 13 |
android:text="@string/settings_title" |
|
| 14 |
android:background="@color/light_grey" |
|
| 15 |
android:gravity="center"/> |
|
| 16 |
|
|
| 17 |
<LinearLayout |
|
| 18 |
android:layout_width="wrap_content" |
|
| 19 |
android:layout_height="match_parent" |
|
| 20 |
android:gravity="center" |
|
| 21 |
android:orientation="horizontal"> |
|
| 22 |
|
|
| 23 |
<TextView |
|
| 24 |
android:id="@+id/sortText" |
|
| 25 |
android:layout_marginStart="5dp" |
|
| 26 |
android:layout_marginEnd="25dp" |
|
| 27 |
android:layout_width="wrap_content" |
|
| 28 |
android:layout_height="match_parent" |
|
| 29 |
android:text="@string/sort_by" |
|
| 30 |
android:gravity="start|center_vertical"/> |
|
| 31 |
|
|
| 32 |
<Spinner |
|
| 33 |
android:id="@+id/sortMethod" |
|
| 34 |
android:layout_width="wrap_content" |
|
| 35 |
android:layout_height="match_parent" |
|
| 36 |
android:gravity="end|center_vertical"/> |
|
| 37 |
|
|
| 38 |
</LinearLayout> |
|
| 39 |
</LinearLayout> |
|
| src/main/res/layout/settings_popup_android25.xml | ||
|---|---|---|
| 1 |
<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 3 |
android:id="@+id/settingsGrid" |
|
| 4 |
android:layout_width="wrap_content" |
|
| 5 |
android:layout_height="wrap_content" |
|
| 6 |
android:gravity="center" |
|
| 7 |
android:orientation="vertical"> |
|
| 8 |
|
|
| 9 |
<TextView |
|
| 10 |
android:id="@+id/sortTitle" |
|
| 11 |
android:layout_width="match_parent" |
|
| 12 |
android:layout_height="wrap_content" |
|
| 13 |
android:text="@string/settings_title" |
|
| 14 |
android:background="@color/light_grey" |
|
| 15 |
android:gravity="center"/> |
|
| 16 |
|
|
| 17 |
<LinearLayout |
|
| 18 |
android:layout_width="wrap_content" |
|
| 19 |
android:layout_height="match_parent" |
|
| 20 |
android:gravity="center" |
|
| 21 |
android:orientation="horizontal"> |
|
| 22 |
|
|
| 23 |
<TextView |
|
| 24 |
android:id="@+id/sortText" |
|
| 25 |
android:layout_marginStart="5dp" |
|
| 26 |
android:layout_marginEnd="25dp" |
|
| 27 |
android:layout_width="wrap_content" |
|
| 28 |
android:layout_height="match_parent" |
|
| 29 |
android:text="@string/sort_by" |
|
| 30 |
android:gravity="start|center_vertical"/> |
|
| 31 |
|
|
| 32 |
<Spinner |
|
| 33 |
android:id="@+id/sortMethod" |
|
| 34 |
android:layout_width="wrap_content" |
|
| 35 |
android:layout_height="match_parent" |
|
| 36 |
android:spinnerMode="dialog" |
|
| 37 |
android:gravity="end|center_vertical"/> |
|
| 38 |
|
|
| 39 |
</LinearLayout> |
|
| 40 |
</LinearLayout> |
|
| src/main/res/values-de/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">Kontakt</string> |
| 54 | 54 |
<string name="email">Melden Sie einen Fehler, schlagen Sie eine Funktion vor:</string> |
| 55 | 55 |
<string name="exit_app">App beenden?</string> |
| 56 |
<string name="sort_by">Ordnung</string> |
|
| 57 |
<string name="settings_title">Einstellungen</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">Löser</string> |
| 58 | 60 |
<string name="object_pattern">Muster</string> |
| src/main/res/values-es/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">Contacto</string> |
| 54 | 54 |
<string name="email">Reportar un error, sugerir una función:</string> |
| 55 | 55 |
<string name="exit_app">¿Salir de la aplicación?</string> |
| 56 |
<string name="sort_by">Ordenar</string> |
|
| 57 |
<string name="settings_title">Ajustes</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">Solucionador</string> |
| 58 | 60 |
<string name="object_pattern">Patrones</string> |
| src/main/res/values-fr/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">Contactez-nous</string> |
| 54 | 54 |
<string name="email">Signaler un bug, suggérer une fonctionnalité :</string> |
| 55 | 55 |
<string name="exit_app">Quitter l\'application ?</string> |
| 56 |
<string name="sort_by">Trier par</string> |
|
| 57 |
<string name="settings_title">Paramètres</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">Solveur</string> |
| 58 | 60 |
<string name="object_pattern">Motifs</string> |
| src/main/res/values-ja/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">お問い合わせ</string> |
| 54 | 54 |
<string name="email">バグを報告し、機能を提案してください:</string> |
| 55 | 55 |
<string name="exit_app">アプリを終了しますか?</string> |
| 56 |
<string name="sort_by">並べ替え</string> |
|
| 57 |
<string name="settings_title">設定</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">ソルバー</string> |
| 58 | 60 |
<string name="object_pattern">パターン</string> |
| src/main/res/values-ko/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">문의하기</string> |
| 54 | 54 |
<string name="email">버그 신고, 기능 제안:</string> |
| 55 | 55 |
<string name="exit_app">앱을 종료하시겠습니까?</string> |
| 56 |
<string name="sort_by">정렬 기준</string> |
|
| 57 |
<string name="settings_title">설정</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">솔버</string> |
| 58 | 60 |
<string name="object_pattern">패턴</string> |
| src/main/res/values-pl/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">Kontakt</string> |
| 54 | 54 |
<string name="email">Zaraportuj błąd, zadaj pytanie:</string> |
| 55 | 55 |
<string name="exit_app">Wyjść z apki?</string> |
| 56 |
<string name="sort_by">Sortuj po</string> |
|
| 57 |
<string name="settings_title">Ustawienia</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">Rozwiązywacz</string> |
| 58 | 60 |
<string name="object_pattern">Wzory</string> |
| src/main/res/values-ru/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">Контакт</string> |
| 54 | 54 |
<string name="email">Сообщить об ошибке, задать вопрос:</string> |
| 55 | 55 |
<string name="exit_app">Выйти из приложения?</string> |
| 56 |
<string name="sort_by">Группа по</string> |
|
| 57 |
<string name="settings_title">Настройки</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">Решатель</string> |
| 58 | 60 |
<string name="object_pattern">Узоры</string> |
| src/main/res/values-zh-rCN/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">联系我们</string> |
| 54 | 54 |
<string name="email">报告错误,提出问题:</string> |
| 55 | 55 |
<string name="exit_app">退出应用程序?</string> |
| 56 |
<string name="sort_by">排序方式</string> |
|
| 57 |
<string name="settings_title">设置</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">求解器</string> |
| 58 | 60 |
<string name="object_pattern">图案</string> |
| src/main/res/values-zh-rTW/strings.xml | ||
|---|---|---|
| 53 | 53 |
<string name="contact">聯繫我們</string> |
| 54 | 54 |
<string name="email">报告错误,提出问题:</string> |
| 55 | 55 |
<string name="exit_app">退出應用程式?</string> |
| 56 |
<string name="sort_by">排序方式</string> |
|
| 57 |
<string name="settings_title">設定</string> |
|
| 56 | 58 |
|
| 57 | 59 |
<string name="object_solver">求解器</string> |
| 58 | 60 |
<string name="object_pattern">圖案</string> |
| src/main/res/values/strings.xml | ||
|---|---|---|
| 55 | 55 |
<string name="contact">Contact us</string> |
| 56 | 56 |
<string name="email">Report a bug, suggest a feature:</string> |
| 57 | 57 |
<string name="exit_app">Exit App?</string> |
| 58 |
<string name="sort_by">Sort by</string> |
|
| 59 |
<string name="settings_title">Settings</string> |
|
| 58 | 60 |
|
| 59 | 61 |
<string name="stars">Stars</string> |
| 60 | 62 |
<string name="scores">High Scores</string> |
Also available in: Unified diff
Progress with sorting the objects by various criteria.