Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
QtView.java
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4package org.qtproject.qt.android;
5
6import android.app.Activity;
7import android.content.Context;
8import android.content.ContextWrapper;
9import android.content.pm.PackageManager.NameNotFoundException;
10import android.content.res.Resources;
11import android.os.Handler;
12import android.os.Looper;
13import android.view.View;
14import android.view.ViewGroup;
15
16import java.security.InvalidParameterException;
17import java.util.ArrayList;
18
19// Base class for embedding QWindow into native Android view hierarchy. Extend to implement
20// the creation of appropriate window to embed.
21abstract class QtView extends ViewGroup {
22 private final static String TAG = "QtView";
23
24 public interface QtWindowListener {
25 // Called when the QWindow has been created and it's Java counterpart embedded into
26 // QtView
28 }
29
30 protected QtWindow m_window;
31 protected long m_windowReference;
32 protected long m_parentWindowReference;
33 protected QtWindowListener m_windowListener;
34 protected QtEmbeddedViewInterface m_viewInterface;
35 // Implement in subclass to handle the creation of the QWindow and its parent container.
36 // TODO could we take care of the parent window creation and parenting outside of the
37 // window creation method to simplify things if user would extend this? Preferably without
38 // too much JNI back and forth. Related to parent window creation, so handle with QTBUG-121511.
39 abstract protected void createWindow(long parentWindowRef);
40
41 static native void createRootWindow(View rootView, int x, int y, int width, int height);
42 static native void deleteWindow(long windowReference);
43 private static native void setWindowVisible(long windowReference, boolean visible);
44 private static native void resizeWindow(long windowReference,
45 int x, int y, int width, int height);
46
55 public QtView(Context context, String appLibName) throws InvalidParameterException {
56 super(context);
57 if (appLibName == null || appLibName.isEmpty()) {
58 throw new InvalidParameterException("QtView: argument 'appLibName' may not be empty "+
59 "or null");
60 }
61
62 QtEmbeddedLoader loader = new QtEmbeddedLoader(context);
63 m_viewInterface = QtEmbeddedDelegateFactory.create((Activity)context);
64 loader.setMainLibraryName(appLibName);
65 addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
66 @Override
67 public void onLayoutChange(View v, int left, int top, int right, int bottom,
68 int oldLeft, int oldTop, int oldRight, int oldBottom) {
69 if (m_windowReference != 0L) {
70 final int oldWidth = oldRight - oldLeft;
71 final int oldHeight = oldBottom - oldTop;
72 final int newWidth = right - left;
73 final int newHeight = bottom - top;
74 if (oldWidth != newWidth || oldHeight != newHeight || left != oldLeft ||
75 top != oldTop) {
76 resizeWindow(m_windowReference, left, top, newWidth, newHeight);
77 }
78 }
79 }
80 });
81 loader.loadQtLibraries();
82 // Start Native Qt application
83 m_viewInterface.startQtApplication(loader.getApplicationParameters(),
84 loader.getMainLibraryPath());
85 }
86
87 @Override
88 protected void onAttachedToWindow() {
89 super.onAttachedToWindow();
90 m_viewInterface.setView(this);
91 m_viewInterface.queueLoadWindow();
92 }
93
94 @Override
95 protected void onDetachedFromWindow() {
96 super.onDetachedFromWindow();
97 destroyWindow();
98 m_viewInterface.setView(null);
99 }
100
101 @Override
102 public void onLayout(boolean changed, int l, int t, int r, int b) {
103 if (m_window != null)
104 m_window.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
105 }
106
107 @Override
108 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
109 {
110 measureChildren(widthMeasureSpec, heightMeasureSpec);
111
112 final int count = getChildCount();
113
114 int maxHeight = 0;
115 int maxWidth = 0;
116
117 // Find out how big everyone wants to be
118 measureChildren(widthMeasureSpec, heightMeasureSpec);
119
120 // Find rightmost and bottom-most child
121 for (int i = 0; i < count; i++) {
122 View child = getChildAt(i);
123 if (child.getVisibility() != GONE) {
124 maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
125 maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
126 }
127 }
128
129 // Check against minimum height and width
130 maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
131 maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
132
133 setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
134 resolveSize(maxHeight, heightMeasureSpec));
135 }
136
137
138 public void setQtWindowListener(QtWindowListener listener) {
139 m_windowListener = listener;
140 }
141
142 void setWindowReference(long windowReference) {
143 m_windowReference = windowReference;
144 }
145
146 long windowReference() {
147 return m_windowReference;
148 }
149
150 // Set the visibility of the underlying QWindow. If visible is true, showNormal() is called.
151 // If false, the window is hidden.
152 void setWindowVisible(boolean visible) {
153 if (m_windowReference != 0L)
154 setWindowVisible(m_windowReference, true);
155 }
156
157 // Called from Qt when the QWindow has been created.
158 // window - the Java QtWindow of the created QAndroidPlatformWindow, to embed into the QtView
159 // viewReference - the reference to the created QQuickView
160 void addQtWindow(QtWindow window, long viewReference, long parentWindowRef) {
161 setWindowReference(viewReference);
162 m_parentWindowReference = parentWindowRef;
163 final Handler handler = new Handler(Looper.getMainLooper());
164 handler.post(new Runnable() {
165 @Override
166 public void run() {
167 m_window = window;
168 m_window.setLayoutParams(new ViewGroup.LayoutParams(
169 ViewGroup.LayoutParams.MATCH_PARENT,
170 ViewGroup.LayoutParams.MATCH_PARENT));
171 addView(m_window, 0);
172 // Call show window + parent
173 setWindowVisible(true);
174 if (m_windowListener != null)
175 m_windowListener.onQtWindowLoaded();
176 }
177 });
178 }
179
180 // Destroy the underlying QWindow
181 void destroyWindow() {
182 if (m_parentWindowReference != 0L)
183 deleteWindow(m_parentWindowReference);
184 m_parentWindowReference = 0L;
185 }
186
187 QtWindow getQtWindow() {
188 return m_window;
189 }
190}
void startQtApplication(String appParams, String mainLib)
void setWindowVisible(JNIEnv *, jclass, jlong windowRef, jboolean visible)
void deleteWindow(JNIEnv *, jclass, jlong windowRef)
QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, Function &&f, Args &&...args)
static void * context
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLboolean r
[2]
GLenum GLenum GLsizei count
GLint GLsizei width
GLint y
GLdouble GLdouble t
Definition qopenglext.h:243
@ Handler
QLayoutItem * child
[0]
aWidget window() -> setWindowTitle("New Window Title")
[2]