From 5048b8bd89b1f5a3958488b286ebc1e027b124ed Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 8 Jul 2019 16:46:58 -0700 Subject: [PATCH] Implement DEV-218 & DEV-219 and commit a starting point for the Emote app --- interface/resources/qml/InteractiveWindow.qml | 31 +++++- .../simplifiedUI/emoteApp/bar/EmoteAppBar.qml | 101 ++++++++++++++++++ interface/src/ui/InteractiveWindow.cpp | 4 + scripts/simplifiedUI/ui/simplifiedUI.js | 96 ++++++++++++++++- 4 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 interface/resources/qml/hifi/simplifiedUI/emoteApp/bar/EmoteAppBar.qml diff --git a/interface/resources/qml/InteractiveWindow.qml b/interface/resources/qml/InteractiveWindow.qml index df3475ea7b..8358019ffd 100644 --- a/interface/resources/qml/InteractiveWindow.qml +++ b/interface/resources/qml/InteractiveWindow.qml @@ -156,7 +156,7 @@ Windows.Window { if (Qt.platform.os !== "windows" && (flags & Desktop.ALWAYS_ON_TOP)) { nativeWindowFlags |= Qt.WindowStaysOnTopHint; } - nativeWindow.flags = nativeWindowFlags; + nativeWindow.flags = flags || nativeWindowFlags; nativeWindow.x = interactiveWindowPosition.x; nativeWindow.y = interactiveWindowPosition.y; @@ -225,10 +225,39 @@ Windows.Window { // Handle message traffic from our loaded QML to the script that launched us signal sendToScript(var message); + function onRequestNewWidth(newWidth) { + interactiveWindowSize.width = newWidth; + updateInteractiveWindowSizeForMode(); + } + + function onRequestNewHeight(newWidth) { + interactiveWindowSize.width = newWidth; + updateInteractiveWindowSizeForMode(); + } + + signal keyPressEvent(int key, int modifiers); + signal keyReleaseEvent(int key, int modifiers); + onDynamicContentChanged: { if (dynamicContent && dynamicContent.sendToScript) { dynamicContent.sendToScript.connect(sendToScript); } + + if (dynamicContent && dynamicContent.requestNewWidth) { + dynamicContent.requestNewWidth.connect(onRequestNewWidth); + } + + if (dynamicContent && dynamicContent.requestNewHeight) { + dynamicContent.requestNewHeight.connect(onRequestNewHeight); + } + + if (dynamicContent && dynamicContent.keyPressEvent) { + dynamicContent.keyPressEvent.connect(keyPressEvent); + } + + if (dynamicContent && dynamicContent.keyReleaseEvent) { + dynamicContent.keyReleaseEvent.connect(keyReleaseEvent); + } } onInteractiveWindowVisibleChanged: { diff --git a/interface/resources/qml/hifi/simplifiedUI/emoteApp/bar/EmoteAppBar.qml b/interface/resources/qml/hifi/simplifiedUI/emoteApp/bar/EmoteAppBar.qml new file mode 100644 index 0000000000..9366ea4f7e --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/emoteApp/bar/EmoteAppBar.qml @@ -0,0 +1,101 @@ +// +// EmoteAppBar.qml +// +// Created by Zach Fox on 2019-07-08 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.10 +import QtQuick.Controls 2.3 +import "../../simplifiedConstants" as SimplifiedConstants +import "../../simplifiedControls" as SimplifiedControls +import stylesUit 1.0 as HifiStylesUit +import TabletScriptingInterface 1.0 + +Rectangle { + id: root + color: simplifiedUI.colors.darkBackground + anchors.fill: parent + + property int originalWidth: 48 + property int hoveredWidth: 480 + property int requestedWidth + + onRequestedWidthChanged: { + root.requestNewWidth(root.requestedWidth); + } + + Behavior on requestedWidth { + enabled: true + SmoothedAnimation { duration: 220 } + } + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + MouseArea { + anchors.fill: parent + hoverEnabled: enabled + onEntered: { + Tablet.playSound(TabletEnums.ButtonHover); + root.requestedWidth = root.hoveredWidth; + } + onExited: { + Tablet.playSound(TabletEnums.ButtonClick); + root.requestedWidth = root.originalWidth; + } + } + + Rectangle { + id: mainEmojiContainer + z: 2 + color: simplifiedUI.colors.darkBackground + anchors.top: parent.top + anchors.left: parent.left + height: parent.height + width: root.originalWidth + + HifiStylesUit.GraphikRegular { + text: "😊" + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenterOffset: -2 + anchors.verticalCenterOffset: -2 + horizontalAlignment: Text.AlignHCenter + size: 26 + color: simplifiedUI.colors.text.almostWhite + } + } + + Rectangle { + id: drawerContainer + z: 1 + color: simplifiedUI.colors.darkBackground + anchors.top: parent.top + anchors.right: parent.right + height: parent.height + width: root.hoveredWidth + + HifiStylesUit.GraphikRegular { + text: "Emotes go here." + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + size: 20 + color: simplifiedUI.colors.text.almostWhite + } + } + + function fromScript(message) { + switch (message.method) { + default: + console.log('EmoteAppBar.qml: Unrecognized message from JS'); + break; + } + } + signal sendToScript(var message); + signal requestNewWidth(int newWidth); +} diff --git a/interface/src/ui/InteractiveWindow.cpp b/interface/src/ui/InteractiveWindow.cpp index 84d24ddeae..26a3825271 100644 --- a/interface/src/ui/InteractiveWindow.cpp +++ b/interface/src/ui/InteractiveWindow.cpp @@ -201,6 +201,10 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap } connect(object, SIGNAL(sendToScript(QVariant)), this, SLOT(qmlToScript(const QVariant&)), Qt::QueuedConnection); + QObject::connect(object, SIGNAL(keyPressEvent(int, int)), this, SLOT(forwardKeyPressEvent(int, int)), + Qt::QueuedConnection); + QObject::connect(object, SIGNAL(keyReleaseEvent(int, int)), this, SLOT(forwardKeyReleaseEvent(int, int)), + Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowPositionChanged()), this, SIGNAL(positionChanged()), Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowSizeChanged()), this, SIGNAL(sizeChanged()), Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection); diff --git a/scripts/simplifiedUI/ui/simplifiedUI.js b/scripts/simplifiedUI/ui/simplifiedUI.js index 2402895f11..b6516b8bae 100644 --- a/scripts/simplifiedUI/ui/simplifiedUI.js +++ b/scripts/simplifiedUI/ui/simplifiedUI.js @@ -15,6 +15,7 @@ // START CONFIG OPTIONS var DOCKED_QML_SUPPORTED = true; +var SHOW_PROTOTYPE_EMOTE_APP = false; var TOOLBAR_NAME = "com.highfidelity.interface.toolbar.system"; var DEFAULT_SCRIPTS_PATH_PREFIX = ScriptDiscoveryService.defaultScriptsPath + "/"; // END CONFIG OPTIONS @@ -101,6 +102,12 @@ var AVATAR_APP_HEIGHT_PX = 615; var avatarAppWindow = false; var POPOUT_SAFE_MARGIN_X = 30; var POPOUT_SAFE_MARGIN_Y = 30; +var AVATAR_APP_WINDOW_FLAGS = 0x00000001 | // Qt::Window + 0x00001000 | // Qt::WindowTitleHint + 0x00002000 | // Qt::WindowSystemMenuHint + 0x08000000 | // Qt::WindowCloseButtonHint + 0x00008000 | // Qt::WindowMaximizeButtonHint + 0x00004000; // Qt::WindowMinimizeButtonHint function toggleAvatarApp() { if (avatarAppWindow) { avatarAppWindow.close(); @@ -121,7 +128,8 @@ function toggleAvatarApp() { position: { x: Math.max(Window.x + POPOUT_SAFE_MARGIN_X, Window.x + Window.innerWidth / 2 - AVATAR_APP_WIDTH_PX / 2), y: Math.max(Window.y + POPOUT_SAFE_MARGIN_Y, Window.y + Window.innerHeight / 2 - AVATAR_APP_HEIGHT_PX / 2) - } + }, + flags: AVATAR_APP_WINDOW_FLAGS }); avatarAppWindow.fromQml.connect(onMessageFromAvatarApp); @@ -166,6 +174,12 @@ var SETTINGS_APP_WINDOW_TITLE = "Settings"; var SETTINGS_APP_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE; var SETTINGS_APP_WIDTH_PX = 480; var SETTINGS_APP_HEIGHT_PX = 615; +var SETTINGS_APP_WINDOW_FLAGS = 0x00000001 | // Qt::Window + 0x00001000 | // Qt::WindowTitleHint + 0x00002000 | // Qt::WindowSystemMenuHint + 0x08000000 | // Qt::WindowCloseButtonHint + 0x00008000 | // Qt::WindowMaximizeButtonHint + 0x00004000; // Qt::WindowMinimizeButtonHint var settingsAppWindow = false; function toggleSettingsApp() { if (settingsAppWindow) { @@ -187,13 +201,81 @@ function toggleSettingsApp() { position: { x: Math.max(Window.x + POPOUT_SAFE_MARGIN_X, Window.x + Window.innerWidth / 2 - SETTINGS_APP_WIDTH_PX / 2), y: Math.max(Window.y + POPOUT_SAFE_MARGIN_Y, Window.y + Window.innerHeight / 2 - SETTINGS_APP_HEIGHT_PX / 2) - } + }, + flags: SETTINGS_APP_WINDOW_FLAGS }); settingsAppWindow.fromQml.connect(onMessageFromSettingsApp); settingsAppWindow.closed.connect(onSettingsAppClosed); } +function updateEmoteAppBarPosition() { + if (!emoteAppBarWindow) { + return; + } + + emoteAppBarWindow.position = { + x: Window.x + EMOTE_APP_BAR_LEFT_MARGIN, + y: Window.y + Window.innerHeight - EMOTE_APP_BAR_BOTTOM_MARGIN + }; +} + + +var EMOTE_APP_BAR_MESSAGE_SOURCE = "EmoteAppBar.qml"; +function onMessageFromEmoteAppBar(message) { + if (message.source !== EMOTE_APP_BAR_MESSAGE_SOURCE) { + return; + } + + switch (message.method) { + + default: + console.log("Unrecognized message from " + EMOTE_APP_BAR_MESSAGE_SOURCE + ": " + JSON.stringify(message)); + break; + } +} + + +function onEmoteAppBarClosed() { + if (emoteAppBarWindow) { + emoteAppBarWindow.fromQml.disconnect(onMessageFromEmoteAppBar); + emoteAppBarWindow.closed.disconnect(onEmoteAppClosed); + } + emoteAppBarWindow = false; +} + + +var EMOTE_APP_BAR_QML_PATH = Script.resourcesPath() + "qml/hifi/simplifiedUI/emoteApp/bar/EmoteAppBar.qml"; +var EMOTE_APP_BAR_WINDOW_TITLE = "Emote"; +var EMOTE_APP_BAR_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE; +var EMOTE_APP_BAR_WIDTH_PX = 48; +var EMOTE_APP_BAR_HEIGHT_PX = 48; +var EMOTE_APP_BAR_LEFT_MARGIN = 48; +var EMOTE_APP_BAR_BOTTOM_MARGIN = 48; +var EMOTE_APP_BAR_WINDOW_FLAGS = 0x00000001 | // Qt::Window + 0x00000800 | // Qt::FramelessWindowHint + 0x40000000 | // Qt::NoDropShadowWindowHint + 0x00200000; // Qt::WindowDoesNotAcceptFocus +var emoteAppBarWindow = false; +function showEmoteAppBar() { + emoteAppBarWindow = Desktop.createWindow(EMOTE_APP_BAR_QML_PATH, { + title: EMOTE_APP_BAR_WINDOW_TITLE, + presentationMode: EMOTE_APP_BAR_PRESENTATION_MODE, + size: { + x: EMOTE_APP_BAR_WIDTH_PX, + y: EMOTE_APP_BAR_HEIGHT_PX + }, + position: { + x: Window.x + EMOTE_APP_BAR_LEFT_MARGIN, + y: Window.y + Window.innerHeight - EMOTE_APP_BAR_BOTTOM_MARGIN + }, + flags: EMOTE_APP_BAR_WINDOW_FLAGS + }); + + emoteAppBarWindow.fromQml.connect(onMessageFromEmoteAppBar); + emoteAppBarWindow.closed.connect(onEmoteAppBarClosed); +} + function maybeDeleteOutputDeviceMutedOverlay() { if (outputDeviceMutedOverlay) { @@ -455,6 +537,8 @@ function onGeometryChanged(rect) { "y": rect.y }; } + + updateEmoteAppBarPosition(); } function onDisplayModeChanged(isHMDMode) { @@ -547,6 +631,10 @@ function startup() { AvatarInputs.showAudioTools = false; oldShowBubbleTools = AvatarInputs.showBubbleTools; AvatarInputs.showBubbleTools = false; + + if (SHOW_PROTOTYPE_EMOTE_APP) { + showEmoteAppBar(); + } } @@ -586,6 +674,10 @@ function shutdown() { settingsAppWindow.close(); } + if (emoteAppBarWindow) { + emoteAppBarWindow.close(); + } + maybeDeleteInputDeviceMutedOverlay(); maybeDeleteOutputDeviceMutedOverlay();