Project

General

Profile

Download (6.2 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / main / MainSettingsPopup.java @ c820515c

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

    
(4-4/4)