1 |
c820515c
|
leszek
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
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 |
def32b2c
|
leszek
|
import java.lang.ref.WeakReference;
|
26 |
c820515c
|
leszek
|
import java.lang.reflect.Field;
|
27 |
|
|
|
28 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
29 |
|
|
|
30 |
|
|
public class MainSettingsPopup implements AdapterView.OnItemSelectedListener
|
31 |
|
|
{
|
32 |
def32b2c
|
leszek
|
public static final int SORT_CLASSIC = 0;
|
33 |
|
|
public static final int SORT_CATEGORY = 1;
|
34 |
|
|
public static final int SORT_DIFFICULTY = 2;
|
35 |
|
|
public static final int SORT_AUTHOR = 3;
|
36 |
|
|
public static final int SORT_YEAR = 4;
|
37 |
|
|
|
38 |
417d51b6
|
leszek
|
public static final int SORT_DEFAULT = SORT_CLASSIC;
|
39 |
|
|
|
40 |
def32b2c
|
leszek
|
private static final String[] mSortNames = { "Classic" , "Category" , "Difficulty", "Author" , "Year" };
|
41 |
c820515c
|
leszek
|
private static final float MENU_TITLE_SIZE= 0.070f;
|
42 |
|
|
private static final float MENU_TEXT_SIZE = 0.060f;
|
43 |
def32b2c
|
leszek
|
private static final int[] mLocation = new int[2];
|
44 |
c820515c
|
leszek
|
|
45 |
|
|
private final PopupWindow mPopup;
|
46 |
def32b2c
|
leszek
|
private final WeakReference<MainActivity> mAct;
|
47 |
c820515c
|
leszek
|
private int mCurrMethod;
|
48 |
|
|
|
49 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
50 |
|
|
// this is supposed to prevent showing the navigational bar when we show the drop down list,
|
51 |
|
|
// but it doesn't quite work... At least not in the emulator.
|
52 |
|
|
// see https://gist.github.com/kakajika/a236ba721a5c0ad3c1446e16a7423a63
|
53 |
|
|
//
|
54 |
|
|
// EDIT: the bar does not appear on API 34 without the need to call this method. Must have been
|
55 |
|
|
// fixed by Android developers.
|
56 |
|
|
|
57 |
|
|
public static void avoidSpinnerDropdownFocus(Spinner spinner)
|
58 |
|
|
{
|
59 |
|
|
try
|
60 |
|
|
{
|
61 |
|
|
Field listPopupField = Spinner.class.getDeclaredField("mPopup");
|
62 |
|
|
listPopupField.setAccessible(true);
|
63 |
|
|
Object listPopup = listPopupField.get(spinner);
|
64 |
|
|
|
65 |
|
|
if( listPopup instanceof ListPopupWindow )
|
66 |
|
|
{
|
67 |
|
|
Field popupField = ListPopupWindow.class.getDeclaredField("mPopup");
|
68 |
|
|
popupField.setAccessible(true);
|
69 |
|
|
Object popup = popupField.get((ListPopupWindow) listPopup);
|
70 |
|
|
|
71 |
|
|
if( popup instanceof PopupWindow )
|
72 |
|
|
{
|
73 |
|
|
((PopupWindow) popup).setFocusable(false);
|
74 |
|
|
}
|
75 |
|
|
}
|
76 |
|
|
}
|
77 |
|
|
catch (NoSuchFieldException | IllegalAccessException ignored)
|
78 |
|
|
{
|
79 |
|
|
|
80 |
|
|
}
|
81 |
|
|
}
|
82 |
|
|
|
83 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
84 |
|
|
|
85 |
|
|
MainSettingsPopup(MainActivity act, int width, int height)
|
86 |
|
|
{
|
87 |
def32b2c
|
leszek
|
mAct = new WeakReference<>(act);
|
88 |
|
|
|
89 |
c820515c
|
leszek
|
// due to bugs in Android API <=25, a Spinner inside a PopupWindow will crash once you click on it.
|
90 |
|
|
// solution: on those APIs, use a special Spinner in dialog mode (this does not crash)
|
91 |
|
|
int id = android.os.Build.VERSION.SDK_INT <= 25 ? R.layout.settings_popup_android25 : R.layout.settings_popup;
|
92 |
|
|
|
93 |
|
|
LayoutInflater layoutInflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
94 |
|
|
final View layout = layoutInflater.inflate(id, null);
|
95 |
|
|
|
96 |
|
|
mPopup = new PopupWindow(act);
|
97 |
|
|
mPopup.setContentView(layout);
|
98 |
|
|
mPopup.setFocusable(true);
|
99 |
|
|
|
100 |
|
|
int titleSize = (int)(MENU_TITLE_SIZE*width);
|
101 |
|
|
int textSize = (int)(MENU_TEXT_SIZE*width);
|
102 |
|
|
|
103 |
|
|
TextView title = layout.findViewById(R.id.sortTitle);
|
104 |
|
|
title.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize);
|
105 |
|
|
TextView text = layout.findViewById(R.id.sortText);
|
106 |
|
|
text.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
107 |
|
|
|
108 |
|
|
Spinner actSpinner = layout.findViewById(R.id.sortMethod);
|
109 |
|
|
actSpinner.setOnItemSelectedListener(this);
|
110 |
|
|
|
111 |
|
|
mCurrMethod = -1;
|
112 |
|
|
|
113 |
def32b2c
|
leszek
|
ArrayAdapter<String> actAdapter = new ArrayAdapter<>(act, android.R.layout.simple_spinner_item, mSortNames);
|
114 |
c820515c
|
leszek
|
actAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
115 |
|
|
actSpinner.setAdapter(actAdapter);
|
116 |
|
|
}
|
117 |
|
|
|
118 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
119 |
|
|
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
|
120 |
|
|
|
121 |
|
|
public void displayPopup(MainActivity act, View view, int w, int h, int xoff, int yoff)
|
122 |
|
|
{
|
123 |
|
|
View v = mPopup.getContentView();
|
124 |
|
|
v.setSystemUiVisibility(MainActivity.FLAGS);
|
125 |
|
|
|
126 |
|
|
View topLayout = act.findViewById(R.id.relativeLayout);
|
127 |
|
|
|
128 |
|
|
boolean isFullScreen;
|
129 |
|
|
|
130 |
|
|
if( topLayout!=null )
|
131 |
|
|
{
|
132 |
|
|
topLayout.getLocationOnScreen(mLocation);
|
133 |
|
|
isFullScreen = (mLocation[1]==0);
|
134 |
|
|
}
|
135 |
|
|
else
|
136 |
|
|
{
|
137 |
|
|
isFullScreen = true;
|
138 |
|
|
}
|
139 |
|
|
|
140 |
|
|
try
|
141 |
|
|
{
|
142 |
|
|
// if on Android 11 or we are fullscreen
|
143 |
|
|
if (Build.VERSION_CODES.R<=Build.VERSION.SDK_INT || isFullScreen )
|
144 |
|
|
{
|
145 |
|
|
mPopup.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
|
146 |
|
|
mPopup.update(view, w, h);
|
147 |
|
|
}
|
148 |
|
|
else // Android 10 or below in pop-up mode or split-screen mode
|
149 |
|
|
{
|
150 |
|
|
view.getLocationOnScreen(mLocation);
|
151 |
|
|
int width = view.getWidth();
|
152 |
|
|
int height = view.getHeight();
|
153 |
|
|
int x = mLocation[0]+(width-w)/2;
|
154 |
|
|
int y = mLocation[1]+height+yoff;
|
155 |
|
|
mPopup.showAsDropDown(view);
|
156 |
|
|
mPopup.update(x,y,w,h);
|
157 |
|
|
}
|
158 |
|
|
}
|
159 |
|
|
catch( IllegalArgumentException iae )
|
160 |
|
|
{
|
161 |
|
|
// ignore, this means window is 'not attached to window manager' -
|
162 |
|
|
// which most probably is because we are already exiting the app.
|
163 |
|
|
}
|
164 |
|
|
}
|
165 |
|
|
|
166 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
167 |
|
|
|
168 |
|
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
|
169 |
|
|
{
|
170 |
|
|
if( parent.getId()==R.id.sortMethod && mCurrMethod!=pos )
|
171 |
|
|
{
|
172 |
|
|
mCurrMethod = pos;
|
173 |
def32b2c
|
leszek
|
MainActivity act = mAct.get();
|
174 |
|
|
act.sortObjectsBy(pos);
|
175 |
c820515c
|
leszek
|
}
|
176 |
|
|
}
|
177 |
|
|
|
178 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
179 |
|
|
|
180 |
|
|
public void onNothingSelected(AdapterView<?> parent)
|
181 |
|
|
{
|
182 |
|
|
|
183 |
|
|
}
|
184 |
|
|
}
|