6package org.qtproject.qt.android;
8import android.app.Activity;
9import android.content.pm.ActivityInfo;
10import android.content.pm.PackageManager;
11import android.content.res.Configuration;
12import android.graphics.Color;
13import android.graphics.drawable.ColorDrawable;
14import android.graphics.drawable.Drawable;
15import android.graphics.Rect;
16import android.os.Build;
17import android.util.DisplayMetrics;
18import android.util.Log;
19import android.util.TypedValue;
20import android.view.Display;
21import android.view.ViewTreeObserver;
22import android.view.animation.AccelerateInterpolator;
23import android.view.animation.AlphaAnimation;
24import android.view.animation.Animation;
25import android.view.Menu;
26import android.view.View;
27import android.view.ViewConfiguration;
28import android.view.ViewGroup;
29import android.view.Window;
30import android.view.WindowInsetsController;
31import android.widget.ImageView;
32import android.widget.PopupMenu;
34import java.util.HashMap;
36class QtActivityDelegate
extends QtActivityDelegateBase
38 private static final String QtTAG =
"QtActivityDelegate";
40 private QtRootLayout m_layout =
null;
41 private ImageView m_splashScreen =
null;
42 private boolean m_splashScreenSticky =
false;
44 private View m_dummyView =
null;
45 private HashMap<Integer, View> m_nativeViews =
new HashMap<Integer, View>();
48 QtActivityDelegate(Activity activity)
52 setActionBarVisibility(
false);
53 setActivityBackgroundDrawable();
59 QtLayout getQtLayout()
66 void setSystemUiVisibility(
int systemUiVisibility)
68 QtNative.runAction(() -> {
69 m_displayManager.setSystemUiVisibility(systemUiVisibility);
70 m_layout.requestLayout();
71 QtNative.updateWindow();
76 public boolean updateActivityAfterRestart(Activity activity) {
77 boolean updated = super.updateActivityAfterRestart(activity);
81 ViewGroup layoutParent = (ViewGroup)m_layout.getParent();
82 if (layoutParent !=
null)
83 layoutParent.removeView(m_layout);
85 m_activity.setContentView(m_layout);
91 void startNativeApplicationImpl(String appParams, String mainLib)
93 m_layout.getViewTreeObserver().addOnGlobalLayoutListener(
94 new ViewTreeObserver.OnGlobalLayoutListener() {
96 public void onGlobalLayout() {
97 QtNative.startApplication(appParams, mainLib);
98 m_layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
104 protected void setUpLayout()
106 int orientation = m_activity.getResources().getConfiguration().orientation;
107 m_layout =
new QtRootLayout(m_activity);
109 setUpSplashScreen(orientation);
110 m_activity.registerForContextMenu(m_layout);
111 m_activity.setContentView(m_layout,
112 new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
113 ViewGroup.LayoutParams.MATCH_PARENT));
114 QtDisplayManager.handleOrientationChanges(m_activity);
116 handleUiModeChange(m_activity.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK);
119 ? m_activity.getWindowManager().getDefaultDisplay()
120 : m_activity.getDisplay();
121 QtDisplayManager.handleRefreshRateChanged(QtDisplayManager.getRefreshRate(
display));
123 m_layout.getViewTreeObserver().addOnPreDrawListener(() -> {
128 m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(
r);
129 DisplayMetrics
metrics =
new DisplayMetrics();
130 m_activity.getWindowManager().getDefaultDisplay().getMetrics(
metrics);
131 final int kbHeight = metrics.heightPixels -
r.bottom;
137 m_layout.getLocationOnScreen(
location);
139 r.width(), kbHeight);
142 registerGlobalFocusChangeListener(m_layout);
143 m_inputDelegate.setEditPopupMenu(
new EditPopupMenu(m_activity, m_layout));
147 protected void setUpSplashScreen(
int orientation)
150 ActivityInfo
info = m_activity.getPackageManager().getActivityInfo(
151 m_activity.getComponentName(),
152 PackageManager.GET_META_DATA);
154 String splashScreenKey =
"android.app.splash_screen_drawable_"
155 + (orientation == Configuration.ORIENTATION_LANDSCAPE ?
"landscape" :
"portrait");
156 if (!
info.metaData.containsKey(splashScreenKey))
157 splashScreenKey =
"android.app.splash_screen_drawable";
159 if (
info.metaData.containsKey(splashScreenKey)) {
160 m_splashScreenSticky =
161 info.metaData.containsKey(
"android.app.splash_screen_sticky") &&
162 info.metaData.getBoolean(
"android.app.splash_screen_sticky");
164 int id =
info.metaData.getInt(splashScreenKey);
165 m_splashScreen =
new ImageView(m_activity);
166 m_splashScreen.setImageDrawable(m_activity.getResources().getDrawable(
167 id, m_activity.getTheme()));
168 m_splashScreen.setScaleType(ImageView.ScaleType.FIT_XY);
169 m_splashScreen.setLayoutParams(
new ViewGroup.LayoutParams(
170 ViewGroup.LayoutParams.MATCH_PARENT,
171 ViewGroup.LayoutParams.MATCH_PARENT));
172 m_layout.addView(m_splashScreen);
174 }
catch (Exception e) {
180 protected void hideSplashScreen(
final int duration)
182 QtNative.runAction(() -> {
183 if (m_splashScreen ==
null)
187 m_layout.removeView(m_splashScreen);
188 m_splashScreen =
null;
192 final Animation fadeOut =
new AlphaAnimation(1, 0);
193 fadeOut.setInterpolator(
new AccelerateInterpolator());
194 fadeOut.setDuration(duration);
196 fadeOut.setAnimationListener(
new Animation.AnimationListener() {
198 public void onAnimationEnd(Animation animation) {
203 public void onAnimationRepeat(Animation
animation) {
207 public void onAnimationStart(Animation
animation) {
211 m_splashScreen.startAnimation(fadeOut);
216 public void initializeAccessibility()
218 QtNative.runAction(() -> {
220 if (m_layout !=
null)
221 m_accessibilityDelegate =
new QtAccessibilityDelegate(m_layout);
223 Log.w(QtTAG,
"Null layout, failed to initialize accessibility delegate.");
228 public void resetOptionsMenu()
230 QtNative.runAction(() -> m_activity.invalidateOptionsMenu());
236 QtNative.runAction(() -> m_activity.openOptionsMenu());
239 private boolean m_contextMenuVisible =
false;
241 public void onCreatePopupMenu(Menu
menu)
243 QtNative.fillContextMenu(
menu);
244 m_contextMenuVisible =
true;
249 public void openContextMenu(
final int x,
final int y,
final int w,
final int h)
251 m_layout.postDelayed(() -> {
252 final QtEditText focusedEditText =
m_inputDelegate.getCurrentQtEditText();
253 if (focusedEditText ==
null) {
254 Log.w(QtTAG,
"No focused view when trying to open context menu");
257 m_layout.setLayoutParams(focusedEditText,
new QtLayout.LayoutParams(
w,
h,
x,
y),
false);
258 PopupMenu popup =
new PopupMenu(m_activity, focusedEditText);
259 QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu());
260 popup.setOnMenuItemClickListener(menuItem ->
261 m_activity.onContextItemSelected(menuItem));
262 popup.setOnDismissListener(popupMenu ->
263 m_activity.onContextMenuClosed(popupMenu.getMenu()));
269 public void closeContextMenu()
271 QtNative.runAction(() -> m_activity.closeContextMenu());
275 void setActionBarVisibility(
boolean visible)
277 if (m_activity.getActionBar() ==
null)
279 if (ViewConfiguration.get(m_activity).hasPermanentMenuKey() || !visible)
280 m_activity.getActionBar().hide();
282 m_activity.getActionBar().show();
287 public void addTopLevelWindow(
final QtWindow
window)
292 QtNative.runAction(()-> {
293 if (m_topLevelWindows.size() == 0) {
294 if (m_dummyView != null) {
295 m_layout.removeView(m_dummyView);
300 window.setLayoutParams(
new ViewGroup.LayoutParams(
301 ViewGroup.LayoutParams.MATCH_PARENT,
302 ViewGroup.LayoutParams.MATCH_PARENT));
304 m_layout.addView(
window, m_topLevelWindows.size());
306 if (!m_splashScreenSticky)
313 void removeTopLevelWindow(
final int id)
315 QtNative.runAction(()-> {
316 if (m_topLevelWindows.containsKey(
id)) {
317 QtWindow window = m_topLevelWindows.remove(id);
318 if (m_topLevelWindows.isEmpty()) {
321 m_dummyView = window;
323 m_layout.removeView(window);
331 void bringChildToFront(
final int id)
333 QtNative.runAction(() -> {
334 QtWindow
window = m_topLevelWindows.get(
id);
336 m_layout.moveChild(
window, m_topLevelWindows.size() - 1);
342 void bringChildToBack(
int id)
344 QtNative.runAction(() -> {
345 QtWindow
window = m_topLevelWindows.get(
id);
347 m_layout.moveChild(
window, 0);
352 QtAccessibilityDelegate createAccessibilityDelegate()
354 if (m_layout !=
null)
355 return new QtAccessibilityDelegate(m_layout);
357 Log.w(QtTAG,
"Null layout, failed to initialize accessibility delegate.");
361 private void setActivityBackgroundDrawable()
363 TypedValue attr =
new TypedValue();
364 m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground,
367 if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
368 attr.type <= TypedValue.TYPE_LAST_COLOR_INT) {
369 backgroundDrawable =
new ColorDrawable(attr.data);
371 backgroundDrawable = m_activity.getResources().
372 getDrawable(attr.resourceId, m_activity.getTheme());
375 m_activity.getWindow().setBackgroundDrawable(backgroundDrawable);
380 public void insertNativeView(
int id,
View view,
int x,
int y,
int w,
int h)
382 QtNative.runAction(()-> {
383 if (m_dummyView !=
null) {
384 m_layout.removeView(m_dummyView);
388 if (m_nativeViews.containsKey(
id))
389 m_layout.removeView(m_nativeViews.remove(
id));
391 if (
w < 0 ||
h < 0) {
392 view.setLayoutParams(
new ViewGroup.LayoutParams(
393 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
395 view.setLayoutParams(
new QtLayout.LayoutParams(
w,
h,
x,
y));
399 m_layout.addView(
view);
400 m_nativeViews.put(
id,
view);
406 public void setNativeViewGeometry(
int id,
int x,
int y,
int w,
int h)
408 QtNative.runAction(() -> {
409 if (m_nativeViews.containsKey(
id)) {
410 View view = m_nativeViews.get(id);
411 view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
413 Log.e(QtTAG,
"View " + id +
" not found!");
static QtJniTypes::QtInputDelegate m_inputDelegate
struct wl_display * display
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLfloat GLfloat GLfloat GLfloat h