Project

General

Profile

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

magiccube / src / main / java / org / distorted / config / ConfigScreen.java @ c02fa107

1 1237d25d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 9d51b9d6 Leszek Koltunski
// 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 1237d25d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.config;
11
12 97a4ae23 Leszek Koltunski
import android.os.Build;
13
import android.util.TypedValue;
14
import android.view.Gravity;
15 1237d25d Leszek Koltunski
import android.view.View;
16 97a4ae23 Leszek Koltunski
import android.widget.GridLayout;
17 302c76a0 Leszek Koltunski
import android.widget.ImageButton;
18 1237d25d Leszek Koltunski
import android.widget.LinearLayout;
19 97a4ae23 Leszek Koltunski
import android.widget.PopupWindow;
20
import android.widget.ScrollView;
21
import android.widget.TextView;
22
23 432a5f2c Leszek Koltunski
import org.distorted.helpers.PopupCreator;
24 97a4ae23 Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
25 1237d25d Leszek Koltunski
26
import org.distorted.helpers.TransparentImageButton;
27
import org.distorted.main.R;
28
import org.distorted.main.RubikActivity;
29 302c76a0 Leszek Koltunski
import org.distorted.objects.RubikObject;
30 a7d8c3cd Leszek Koltunski
import org.distorted.objects.RubikObjectList;
31 97a4ae23 Leszek Koltunski
32
import static android.view.View.inflate;
33 1237d25d Leszek Koltunski
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35
36
public class ConfigScreen
37
{
38 27401bea Leszek Koltunski
  private static final float TEXT_SIZE = 0.0310f;
39
  private static final float PADDING   = 0.0060f;
40
  private static final float MARGIN    = 0.0024f;
41 6e3fcb91 Leszek Koltunski
  private static final int NUM_COLUMNS = 5;
42 97a4ae23 Leszek Koltunski
  private static final int[] mLocation = new int[2];
43
44
  private TransparentImageButton mBackButton, mObjectButton, mPrevButton, mNextButton;
45
  private TextView mMovesText;
46
  private PopupWindow mObjectPopup;
47 74d088c3 Leszek Koltunski
  private ConfigScreenPane mPane;
48 97a4ae23 Leszek Koltunski
  private int mObjectOrdinal;
49
  private int mColCount, mRowCount, mMaxRowCount;
50
  private int mObjectSize;
51
  private int mBarHeight;
52
  private float mButtonSize;
53
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55
56
  private void setupObjectWindow(final ConfigActivity act, final float width, final float height)
57
    {
58 432a5f2c Leszek Koltunski
    int numObjects= RubikObjectList.getNumObjects();
59
    mRowCount = (numObjects + NUM_COLUMNS-1) / NUM_COLUMNS;
60
    mColCount = NUM_COLUMNS;
61
62 27401bea Leszek Koltunski
    int cubeSize  = (int)( (Math.min(width,(int)(height*0.7f))) / 9 );
63
    int margin    = (int)(height*RubikActivity.POPUP_MARGIN);
64
    int padding   = (int)(height*RubikActivity.POPUP_PADDING);
65 432a5f2c Leszek Koltunski
    mObjectSize   = (int)(cubeSize + 2*margin + 0.5f);
66
    mMaxRowCount  = (int)((height-mBarHeight)/mObjectSize);
67 97a4ae23 Leszek Koltunski
68
    ScrollView view = (ScrollView)inflate( act, R.layout.popup_object_simple, null);
69
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
70
71 a88b947f Leszek Koltunski
    PopupCreator.createObjectGrid(objectGrid,act,mRowCount,mColCount,numObjects,margin,cubeSize,padding);
72 a7d8c3cd Leszek Koltunski
73 432a5f2c Leszek Koltunski
    for(int child=0; child<numObjects; child++)
74 97a4ae23 Leszek Koltunski
      {
75 302c76a0 Leszek Koltunski
      final RubikObject obj = RubikObjectList.getObject(child);
76
      View v = objectGrid.getChildAt(child);
77
      ImageButton button = PopupCreator.getButton(obj,v);
78 432a5f2c Leszek Koltunski
      final int ordinal = child;
79 314e9ff0 Leszek Koltunski
80 97a4ae23 Leszek Koltunski
      button.setOnClickListener( new View.OnClickListener()
81
        {
82
        @Override
83
        public void onClick(View v)
84
          {
85
          if( act.getControl().isUINotBlocked() && mObjectOrdinal!=ordinal )
86
            {
87
            mObjectOrdinal = ordinal;
88 280dc794 Leszek Koltunski
            act.changeObject(mObjectOrdinal);
89 a7d8c3cd Leszek Koltunski
            mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
90 74d088c3 Leszek Koltunski
            mPane.updatePane(act,mObjectOrdinal);
91 97a4ae23 Leszek Koltunski
            }
92
93
          mObjectPopup.dismiss();
94
          }
95
        });
96
      }
97 432a5f2c Leszek Koltunski
98
    mObjectPopup = new PopupWindow(act);
99
    mObjectPopup.setFocusable(true);
100
    mObjectPopup.setContentView(view);
101 97a4ae23 Leszek Koltunski
    }
102 1237d25d Leszek Koltunski
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104
105
  private void setupBackButton(final ConfigActivity act)
106
    {
107
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_smallback,R.drawable.ui_medium_smallback, R.drawable.ui_big_smallback, R.drawable.ui_huge_smallback);
108 97a4ae23 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
109 1237d25d Leszek Koltunski
    mBackButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
110
111
    mBackButton.setOnClickListener( new View.OnClickListener()
112
      {
113
      @Override
114
      public void onClick(View v)
115
        {
116
        ObjectControl control = act.getControl();
117
        if( control!=null ) control.unblockEverything();
118
        act.finish();
119
        }
120
      });
121
    }
122
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124
125 27401bea Leszek Koltunski
  private void setupObjectButton(final ConfigActivity act, final int width, final int height)
126 1237d25d Leszek Koltunski
    {
127 27401bea Leszek Koltunski
    final int margin= (int)(height*MARGIN);
128 97a4ae23 Leszek Koltunski
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_menu,R.drawable.ui_medium_cube_menu, R.drawable.ui_big_cube_menu, R.drawable.ui_huge_cube_menu);
129
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
130
    mObjectButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
131
132
    mObjectButton.setOnClickListener( new View.OnClickListener()
133
      {
134
      @Override
135
      public void onClick(View view)
136
        {
137
        if( mObjectPopup==null )
138
          {
139
          setupObjectWindow(act,width,height);
140
          }
141
142
        if( act.getControl().isUINotBlocked())
143
          {
144
          int rowCount = Math.min(mMaxRowCount,mRowCount);
145
          View popupView = mObjectPopup.getContentView();
146
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
147 1071fb69 Leszek Koltunski
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount+5*margin,margin,margin);
148 97a4ae23 Leszek Koltunski
          }
149
        }
150
      });
151
    }
152
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
155
156
  private void displayPopup(ConfigActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
157
    {
158
    View topLayout = act.findViewById(R.id.mainLayout);
159
    boolean isFullScreen;
160
161
    if( topLayout!=null )
162
      {
163
      topLayout.getLocationOnScreen(mLocation);
164
      isFullScreen = (mLocation[1]==0);
165
      }
166
    else
167
      {
168
      isFullScreen = true;
169
      }
170
171
    try
172
      {
173
      // if on Android 11 or we are fullscreen
174
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
175
        {
176
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
177
        window.update(view, w, h);
178
        }
179
      else  // Android 10 or below in pop-up mode or split-screen mode
180
        {
181
        view.getLocationOnScreen(mLocation);
182
        int width  = view.getWidth();
183
        int height = view.getHeight();
184
        int x = mLocation[0]+(width-w)/2;
185
        int y = mLocation[1]+height+yoff;
186
187
        window.showAsDropDown(view);
188
        window.update(x,y,w,h);
189
        }
190
      }
191
    catch( IllegalArgumentException iae )
192
      {
193
      // ignore, this means window is 'not attached to window manager' -
194
      // which most probably is because we are already exiting the app.
195
      }
196 1237d25d Leszek Koltunski
    }
197
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
200 a7d8c3cd Leszek Koltunski
  private void prevObject(ConfigActivity act, int numObjects)
201 1237d25d Leszek Koltunski
    {
202 97a4ae23 Leszek Koltunski
    mObjectOrdinal--;
203 a7d8c3cd Leszek Koltunski
    if( mObjectOrdinal<0 ) mObjectOrdinal=numObjects-1;
204 97a4ae23 Leszek Koltunski
205 280dc794 Leszek Koltunski
    act.changeObject(mObjectOrdinal);
206 74d088c3 Leszek Koltunski
    mPane.updatePane(act,mObjectOrdinal);
207 97a4ae23 Leszek Koltunski
    }
208
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
211 a7d8c3cd Leszek Koltunski
  private void nextObject(ConfigActivity act, int numObjects)
212 97a4ae23 Leszek Koltunski
    {
213
    mObjectOrdinal++;
214 a7d8c3cd Leszek Koltunski
    if( mObjectOrdinal>=numObjects ) mObjectOrdinal=0;
215 97a4ae23 Leszek Koltunski
216 280dc794 Leszek Koltunski
    act.changeObject(mObjectOrdinal);
217 74d088c3 Leszek Koltunski
    mPane.updatePane(act,mObjectOrdinal);
218 97a4ae23 Leszek Koltunski
    }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  private void setupPrevButton(final ConfigActivity act)
223
    {
224
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_left,R.drawable.ui_medium_left, R.drawable.ui_big_left, R.drawable.ui_huge_left);
225
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
226
    mPrevButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
227
228
    mPrevButton.setOnClickListener( new View.OnClickListener()
229
      {
230
      @Override
231
      public void onClick(View v)
232
        {
233 a7d8c3cd Leszek Koltunski
        int numObjects = RubikObjectList.getNumObjects();
234
        prevObject(act,numObjects);
235
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
236 97a4ae23 Leszek Koltunski
        }
237
      });
238
    }
239
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
242
  private void setupNextButton(final ConfigActivity act)
243
    {
244
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_right,R.drawable.ui_medium_right, R.drawable.ui_big_right, R.drawable.ui_huge_right);
245
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
246
    mNextButton = new TransparentImageButton(act,icon,TransparentImageButton.GRAVITY_MIDDLE,params);
247
248
    mNextButton.setOnClickListener( new View.OnClickListener()
249
      {
250
      @Override
251
      public void onClick(View v)
252
        {
253 a7d8c3cd Leszek Koltunski
        int numObjects = RubikObjectList.getNumObjects();
254
        nextObject(act,numObjects);
255
        mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
256 97a4ae23 Leszek Koltunski
        }
257
      });
258
    }
259
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261
262 27401bea Leszek Koltunski
  private void setupTextView(final ConfigActivity act, final float height, int numObjects)
263 97a4ae23 Leszek Koltunski
    {
264 27401bea Leszek Koltunski
    int padding = (int)(height*PADDING);
265
    int margin  = (int)(height*MARGIN);
266 97a4ae23 Leszek Koltunski
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT,2.0f);
267
    params.topMargin    = margin;
268
    params.bottomMargin = margin;
269
    params.leftMargin   = margin;
270
    params.rightMargin  = margin;
271
272
    mMovesText = new TextView(act);
273
    mMovesText.setTextSize(20);
274
    mMovesText.setLayoutParams(params);
275
    mMovesText.setPadding(padding,0,padding,0);
276
    mMovesText.setGravity(Gravity.CENTER);
277
    mMovesText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mButtonSize);
278 a7d8c3cd Leszek Koltunski
    mMovesText.setText(act.getString(R.string.mo_placeholder,mObjectOrdinal+1,numObjects));
279 97a4ae23 Leszek Koltunski
    }
280
281 8bf8fe70 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283 74d088c3 Leszek Koltunski
  void onAttachedToWindow(final ConfigActivity act, final int objectOrdinal)
284 97a4ae23 Leszek Koltunski
    {
285 a7d8c3cd Leszek Koltunski
    int numObjects = RubikObjectList.getNumObjects();
286 97a4ae23 Leszek Koltunski
    int width = act.getScreenWidthInPixels();
287 27401bea Leszek Koltunski
    int height= act.getScreenHeightInPixels();
288 97a4ae23 Leszek Koltunski
    mBarHeight = act.getHeightBar();
289 27401bea Leszek Koltunski
    mButtonSize = height*TEXT_SIZE;
290 97a4ae23 Leszek Koltunski
    mObjectOrdinal = objectOrdinal;
291
292 74d088c3 Leszek Koltunski
    LinearLayout.LayoutParams paramsL = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
293
    LinearLayout.LayoutParams paramsM = new LinearLayout.LayoutParams(width/2, LinearLayout.LayoutParams.MATCH_PARENT);
294
    LinearLayout.LayoutParams paramsR = new LinearLayout.LayoutParams(width/4, LinearLayout.LayoutParams.MATCH_PARENT);
295 97a4ae23 Leszek Koltunski
296
    LinearLayout layoutLeft = new LinearLayout(act);
297
    layoutLeft.setLayoutParams(paramsL);
298
    LinearLayout layoutMid  = new LinearLayout(act);
299
    layoutMid.setLayoutParams(paramsM);
300
    LinearLayout layoutRight= new LinearLayout(act);
301
    layoutRight.setLayoutParams(paramsR);
302
303 27401bea Leszek Koltunski
    setupObjectButton(act,width,height);
304 97a4ae23 Leszek Koltunski
    setupPrevButton(act);
305
    setupNextButton(act);
306 27401bea Leszek Koltunski
    setupTextView(act,height,numObjects);
307 97a4ae23 Leszek Koltunski
    setupBackButton(act);
308
309
    layoutLeft.addView(mObjectButton);
310
    layoutMid.addView(mPrevButton);
311
    layoutMid.addView(mMovesText);
312
    layoutMid.addView(mNextButton);
313
    layoutRight.addView(mBackButton);
314
315
    LinearLayout layout = act.findViewById(R.id.lowerBar);
316
    layout.removeAllViews();
317
    layout.addView(layoutLeft);
318
    layout.addView(layoutMid);
319
    layout.addView(layoutRight);
320 1237d25d Leszek Koltunski
321 74d088c3 Leszek Koltunski
    mPane = new ConfigScreenPane(act,mObjectOrdinal);
322 1237d25d Leszek Koltunski
    }
323
}