hacky setting of lower menu based on ribbon press

This commit is contained in:
amwatson 2024-04-06 20:01:13 -05:00
parent 8a748b1e0d
commit d012252cb8
5 changed files with 61 additions and 26 deletions

View file

@ -28,6 +28,10 @@ class VrRibbonLayer(activity: VrActivity) : VrUILayer(activity, R.layout.vr_ribb
initializePositionalPanel()
}
// Used in positional menu to know when background is selected, but not the buttons,
// in which case, move the panel.
private var isMenuBackgroundSelected = false
fun switchMenus(menuTypeNew: MenuType) {
if (menuTypeNew == menuTypeCurrent)
return
@ -40,6 +44,10 @@ class VrRibbonLayer(activity: VrActivity) : VrUILayer(activity, R.layout.vr_ribb
VrMessageQueue.post(VrMessageQueue.MessageType.CHANGE_LOWER_MENU, 1)
}
fun isMenuBackgroundSelected(): Boolean {
return isMenuBackgroundSelected
}
private fun initializeLeftMenu() {
val radioGroup = window?.findViewById<RadioGroup>(R.id.vertical_tab)
radioGroup?.setOnCheckedChangeListener { group, checkedId ->
@ -77,6 +85,19 @@ class VrRibbonLayer(activity: VrActivity) : VrUILayer(activity, R.layout.vr_ribb
horizontalLockToggle?.isChecked = true;
VrMessageQueue.post(VrMessageQueue.MessageType.CHANGE_LOCK_HORIZONTAL_AXIS, if (horizontalLockToggle?.isChecked == true) 1 else 0)
window?.findViewById<View>(R.id.frame)?.setOnTouchListener { _, motionEvent ->
/// set isMenuBackgroundSelected based on the motionEvent
when (motionEvent.action) {
KeyEvent.ACTION_DOWN -> {
isMenuBackgroundSelected = true
}
KeyEvent.ACTION_UP -> {
isMenuBackgroundSelected = false
}
}
false
}
}
private fun initializeMainPanel() {

View file

@ -214,7 +214,7 @@ bool UILayer::GetRayIntersectionWithPanel(const XrVector3f& start,
scale, start, end, result2d, result3d);
}
// Next error code: -8
// Next error code: -9
int32_t UILayer::Init(const std::string& className, const jobject activityObject,
const XrVector3f& position, const XrSession& session) {
mVrUILayerClass = JniUtils::GetGlobalClassReference(mEnv, activityObject, className.c_str());
@ -238,7 +238,16 @@ int32_t UILayer::Init(const std::string& className, const jobject activityObject
BAIL_ON_COND(mSendClickToUIMethodID == nullptr, "could not find sendClickToUI()", -6);
BAIL_ON_ERR(CreateSwapchain(), -7);
if (className == "org/citra/citra_emu/vr/ui/VrRibbonLayer") {
ALOGD("UILayer: using companion class");
mIsMenuBackgroundSelectedMethodId =
mEnv->GetMethodID(mVrUILayerClass, "isMenuBackgroundSelected", "()Z");
BAIL_ON_COND(mIsMenuBackgroundSelectedMethodId == nullptr,
"could not find isMenuBackgroundSelected()", -7);
}
BAIL_ON_ERR(CreateSwapchain(), -8);
return 0;
}
@ -327,3 +336,7 @@ void UILayer::SendClickToUI(const XrVector2f& pos2d, const int type) {
}
void UILayer::SetPanelWithPose(const XrPosef& pose) { mPanelFromWorld = pose; }
bool UILayer::IsMenuBackgroundSelected() const {
return mEnv->CallBooleanMethod(mVrUILayerObject, mIsMenuBackgroundSelectedMethodId);
}

View file

@ -125,6 +125,8 @@ public:
void SetPanelWithPose(const XrPosef& pose);
bool IsMenuBackgroundSelected() const;
private:
int Init(const std::string& className, const jobject activityObject, const XrVector3f& position,
const XrSession& session);
@ -154,7 +156,8 @@ private:
// the decorView representing an entire window, it's important to accont for
// the x, y offset of the view within the window, in case there are things
// like window decorations or status bars.
jmethodID mGetBoundsMethodID = nullptr;
jmethodID mSendClickToUIMethodID = nullptr;
jmethodID mSetSurfaceMethodId = nullptr;
jmethodID mGetBoundsMethodID = nullptr;
jmethodID mSendClickToUIMethodID = nullptr;
jmethodID mSetSurfaceMethodId = nullptr;
jmethodID mIsMenuBackgroundSelectedMethodId = nullptr;
};

View file

@ -407,7 +407,7 @@ private:
// Super Immersive Mode update and computation.
//////////////////////////////////////////////////
bool showLowerPanel = true;
bool showLowerPanel = appState.mLowerMenuType != LowerMenuType::POSITIONAL_MENU;
float immersiveModeFactor = (VRSettings::values.vr_immersive_mode < 2)
? immersiveScaleFactor[VRSettings::values.vr_immersive_mode]
: immersiveScaleFactor[2];
@ -526,7 +526,7 @@ private:
// Cursor visibility will depend on hit-test but will be in front
// of all other panels. This is because precedence lines up with depth order.
HandleCursorLayer(jni, appState, layers, layerCount);
HandleCursorLayer(jni, appState, showLowerPanel, layers, layerCount);
}
std::vector<const XrCompositionLayerBaseHeader*> layerHeaders;
@ -665,7 +665,7 @@ private:
/** Handle the cursor and any hand-tracked/layer-dependent input
* interactions.
**/
void HandleCursorLayer(JNIEnv* jni, const AppState& appState,
void HandleCursorLayer(JNIEnv* jni, const AppState& appState, const bool showLowerPanel,
std::vector<XrCompositionLayer>& layers, uint32_t& layerCount) const {
bool shouldRenderCursor = false;
@ -690,7 +690,6 @@ private:
mInputStateFrame.mIsHandActive[mInputStateFrame.mPreferredHand];
static bool sIsLowerPanelBeingPositioned = false;
const bool wasLowerPanelBeingPositioned = sIsLowerPanelBeingPositioned;
sIsLowerPanelBeingPositioned &=
appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU &&
@ -732,26 +731,11 @@ private:
// No dialogs/popups that should impede normal cursor interaction with
// applicable panels
// Lock ribbon in place when placement is complete
const bool needRibbonUpdate =
!sIsLowerPanelBeingPositioned && wasLowerPanelBeingPositioned;
if (needRibbonUpdate) {
mRibbonLayer->SetPanelWithPose(mGameSurfaceLayer->GetLowerPanelPose());
}
// 3. Lower panel
if (!shouldRenderCursor) {
if (!shouldRenderCursor && showLowerPanel) {
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanel(
start, end, cursorPos2d, cursorPose3d);
if ((shouldRenderCursor || sIsLowerPanelBeingPositioned) &&
appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU &&
triggerState.currentState) {
mGameSurfaceLayer->SetLowerPanelFromController(
{appState.mIsHorizontalAxisLocked ? 0.0f : cursorPose3d.position.x,
cursorPose3d.position.y, cursorPose3d.position.z});
sIsLowerPanelBeingPositioned = true;
} else if (appState.mLowerMenuType == LowerMenuType::MAIN_MENU) {
if (appState.mLowerMenuType == LowerMenuType::MAIN_MENU) {
SendTriggerStateToWindow(jni, mActivityObject, mSendClickToWindowMethodID,
triggerState, cursorPos2d);
}
@ -764,6 +748,18 @@ private:
if (shouldRenderCursor && triggerState.changedSinceLastSync) {
mRibbonLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
}
if (appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU &&
(sIsLowerPanelBeingPositioned ||
(shouldRenderCursor && mRibbonLayer->IsMenuBackgroundSelected())) &&
triggerState.currentState) {
mGameSurfaceLayer->SetLowerPanelFromController(
{appState.mIsHorizontalAxisLocked ? 0.0f : cursorPose3d.position.x,
cursorPose3d.position.y, cursorPose3d.position.z});
mRibbonLayer->SetPanelWithPose(mGameSurfaceLayer->GetLowerPanelPose());
sIsLowerPanelBeingPositioned = true;
}
}
// 5. Top panel (only if positional menu is active)

View file

@ -28,6 +28,8 @@
android:background="@drawable/vr_menu_background"
android:backgroundTint="#011627"
android:padding="50dp"
android:clickable="true"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">